private WadoClientResponse fetch( ApplicationEntity localAE, ApplicationEntity remoteAE, String studyInstanceUID, String seriesInstanceUID, String sopInstanceUID, InstanceAvailableCallback callback) { setCallBack(callback); WadoClient client = createClient(); WebServiceAEExtension wsAEExt = remoteAE.getAEExtension(WebServiceAEExtension.class); try { return client.fetch( localAE.getAETitle(), remoteAE.getAETitle(), studyInstanceUID, seriesInstanceUID, sopInstanceUID, wsAEExt.getWadoRSBaseURL()); } catch (IOException e) { LOG.error( "Error fetching Study {}, from AE {}" + " check baseurl configuration for WadoRS", studyInstanceUID, remoteAE.getAETitle()); } return null; }
protected void setApplicationEntityAttributes(ApplicationEntity from) { setOlockHash(from.olockHash); setDescription(from.description); setAETitleAliases(from.getAETitleAliases()); setVendorData(from.vendorData); setApplicationClusters(from.applicationClusters); setPreferredCalledAETitles(from.preferredCalledAETitles); setPreferredCallingAETitles(from.preferredCallingAETitles); setAcceptedCallingAETitles(from.getAcceptedCallingAETitles()); setSupportedCharacterSets(from.supportedCharacterSets); setAssociationAcceptor(from.associationAcceptor); setAssociationInitiator(from.associationInitiator); setAeInstalled(from.aeInstalled); setUuid(from.getUuid()); }
public Association connect(ApplicationEntity remote, AAssociateRQ rq) throws IOException, InterruptedException, IncompatibleConnectionException, GeneralSecurityException { CompatibleConnection cc = findCompatibelConnection(remote); if (rq.getCalledAET() == null) rq.setCalledAET(remote.getAETitle()); return connect(cc.getLocalConnection(), cc.getRemoteConnection(), rq); }
public QueryParam( ApplicationEntity ae, boolean combinedDatetimeMatching, boolean fuzzySemanticMatching) { this.arcAE = ae.getAEExtension(ArchiveAEExtension.class); this.arcDev = arcAE.getArchiveDeviceExtension(); this.qrView = arcAE.getQueryRetrieveView(); this.combinedDatetimeMatching = combinedDatetimeMatching; this.fuzzySemanticMatching = fuzzySemanticMatching; }
private void checkTransferCapability(String cuid, String tsuid) throws DicomServiceException { TransferCapability tc = ae.getTransferCapabilityFor(cuid, TransferCapability.Role.SCP); if (tc == null) { throw new DicomServiceException(org.dcm4che3.net.Status.SOPclassNotSupported); } if (!tc.containsTransferSyntax(tsuid)) { throw new DicomServiceException(TRANSFER_SYNTAX_NOT_SUPPORTED); } }
private CStoreForwardTask createTask(final Association as) { ApplicationEntity localAE = retrieveCtx.getLocalApplicationEntity(); Association storeas = openAssociation(as, localAE); final CStoreForwardTask task = new CStoreForwardTask(retrieveCtx, storeas); forwardTasks.put(as, task); as.addAssociationListener( new AssociationListener() { @Override public void onClose(Association association) { task.onStore(null); forwardTasks.remove(as); } }); if (storeas != null) { retrieveCtx.incrementPendingCStoreForward(); localAE.getDevice().execute(task); } return task; }
private static void addTC( ApplicationEntity ae, EnumSet<QueryOption> queryOpts, TransferCapability.Role role, String cuid, String... tss) { String name = UID.nameOf(cuid).replace('/', ' '); TransferCapability tc = new TransferCapability(name + ' ' + role, cuid, role, tss); tc.setQueryOptions(queryOpts); ae.addTransferCapability(tc); }
@GET @Path("/whoami") @Produces(MediaType.TEXT_HTML) public Response whoami() throws ConfigurationException { HttpSource source = new HttpSource(request); ApplicationEntity ae = hostAECache.findAE(source); Device callerDevice = ae.getDevice(); return Response.ok( "<div>Calling Device: <br>Host:" + request.getRemoteHost() + "<br>AETitle: " + ae.getAETitle() + "<br>Device Name: " + callerDevice.getDeviceName() + "</div>") .build(); }
private void init() { this.ae = device.getApplicationEntity(aeTitle); if (ae == null || !ae.isInstalled() || (arcAE = ae.getAEExtension(ArchiveAEExtension.class)) == null) throw new WebApplicationException(Response.Status.SERVICE_UNAVAILABLE); this.boundary = contentType.getParameters().get("boundary"); if (boundary == null) throw new WebApplicationException("Missing Boundary Parameter", Response.Status.BAD_REQUEST); if (contentType.isCompatible(MediaTypes.MULTIPART_RELATED_TYPE)) { String type = contentType.getParameters().get("type"); if (type == null) throw new WebApplicationException("Missing Type Parameter", Response.Status.BAD_REQUEST); try { MediaType rootBodyMediaType = MediaType.valueOf(type); if (rootBodyMediaType.isCompatible(MediaTypes.APPLICATION_DICOM_TYPE)) creatorType = CreatorType.BINARY; else if (rootBodyMediaType.isCompatible(MediaTypes.APPLICATION_DICOM_XML_TYPE)) { creatorType = CreatorType.XML_BULKDATA; metadata = new ArrayList<MetaDataPathTSTuple>(); bulkdata = new HashMap<String, BulkdataPath>(); } else if (rootBodyMediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) { creatorType = CreatorType.JSON_BULKDATA; metadata = new ArrayList<MetaDataPathTSTuple>(); bulkdata = new HashMap<String, BulkdataPath>(); } else throw new WebApplicationException(Response.Status.UNSUPPORTED_MEDIA_TYPE); } catch (IllegalArgumentException e) { throw new WebApplicationException(e, Response.Status.BAD_REQUEST); } } else { creatorType = CreatorType.BINARY; } wadoURL = uriInfo.getBaseUri() + "wado/" + ae.getAETitle() + "/studies/"; if (studyInstanceUID != null) response.setString(Tag.RetrieveURL, VR.UR, wadoURL + studyInstanceUID); else response.setNull(Tag.RetrieveURL, VR.UR); sopSequence = response.newSequence(Tag.ReferencedSOPSequence, 10); }
public Device createDevice( String name, Issuer issuer, Code institutionCode, String aet, String host, int port, int tlsPort) throws Exception { Device device = init(new Device(name), issuer, institutionCode); ApplicationEntity ae = new ApplicationEntity(aet); ae.setAssociationAcceptor(true); device.addApplicationEntity(ae); Connection dicom = new Connection("dicom", host, port); device.addConnection(dicom); ae.addConnection(dicom); Connection dicomTLS = new Connection("dicom-tls", host, tlsPort); dicomTLS.setTlsCipherSuites( Connection.TLS_RSA_WITH_AES_128_CBC_SHA, Connection.TLS_RSA_WITH_3DES_EDE_CBC_SHA); device.addConnection(dicomTLS); ae.addConnection(dicomTLS); return device; }
@Override public StoreContext spool( String localAETitle, String remoteAETitle, InputStream in, InstanceAvailableCallback callback) throws Exception { StoreContext context; ApplicationEntity localAE = aeCache.findApplicationEntity(localAETitle); StoreSession session = storeService.createStoreSession(storeService); session.setSource( new GenericParticipant(localAE.getConnections().get(0).getHostname(), "WadoRS Fetch")); session.setRemoteAET(remoteAETitle); ArchiveAEExtension arcAEExt = aeCache.get(localAETitle).getAEExtension(ArchiveAEExtension.class); session.setArchiveAEExtension(arcAEExt); storeService.init(session); context = storeService.createStoreContext(session); try { DicomInputStream din = new DicomInputStream(in); Attributes fmi = din.getFileMetaInformation(); storeService.writeSpoolFile(context, fmi, din); } catch (Exception e) { throw new Exception("Failed to spool WadoRS response from AE " + remoteAETitle); } return context; }
private Association openAssociation(Association as, ApplicationEntity localAE) { try { LOG.info( "{}: open association to {} for forwarding C-STORE-RQ received in association {}", retrieveCtx.getRequestAssociation(), retrieveCtx.getDestinationAETitle(), as); return localAE.connect(retrieveCtx.getDestinationAE(), createAARQ(as)); } catch (Exception e) { LOG.warn( "{}: failed to open association to {} for forwarding C-STORE-RQ received in association {}:\n", retrieveCtx.getRequestAssociation(), retrieveCtx.getDestinationAETitle(), as, e); return null; } }
private static ApplicationEntity createAE( String aet, String description, Connection dicom, Connection dicomTLS, QueryRetrieveView qrView, boolean storeSCP, boolean storeSCU) { ApplicationEntity ae = new ApplicationEntity(aet); ae.setDescription(description); ae.addConnection(dicom); if (dicomTLS != null) ae.addConnection(dicomTLS); ArchiveAEExtension aeExt = new ArchiveAEExtension(); ae.addAEExtension(aeExt); ae.setAssociationAcceptor(true); ae.setAssociationInitiator(true); addTC(ae, null, SCP, UID.VerificationSOPClass, UID.ImplicitVRLittleEndian); addTC(ae, null, SCU, UID.VerificationSOPClass, UID.ImplicitVRLittleEndian); addTCs(ae, EnumSet.allOf(QueryOption.class), SCP, QUERY_CUIDS, UID.ImplicitVRLittleEndian); if (storeSCU) { addTCs( ae, EnumSet.of(QueryOption.RELATIONAL), SCP, RETRIEVE_CUIDS, UID.ImplicitVRLittleEndian); for (int i = 0; i < CUIDS_TSUIDS.length; i++, i++) addTCs(ae, null, SCU, CUIDS_TSUIDS[i], CUIDS_TSUIDS[i + 1]); } if (storeSCP) { for (int i = 0; i < CUIDS_TSUIDS.length; i++, i++) addTCs(ae, null, SCP, CUIDS_TSUIDS[i], CUIDS_TSUIDS[i + 1]); addTC(ae, null, SCP, UID.StorageCommitmentPushModelSOPClass, UID.ImplicitVRLittleEndian); addTC(ae, null, SCP, UID.ModalityPerformedProcedureStepSOPClass, UID.ImplicitVRLittleEndian); addTC(ae, null, SCU, UID.ModalityPerformedProcedureStepSOPClass, UID.ImplicitVRLittleEndian); } aeExt.setQueryRetrieveViewID(qrView.getViewID()); return ae; }
public void open() throws IOException, InterruptedException, IncompatibleConnectionException, GeneralSecurityException { as = ae.connect(remote, rq); }
public MoveSCU(ApplicationEntity ae) { this.ae = ae; this.device = ae.getDevice(); }
public MoveSCU() throws IOException { this.device = new Device("movescu"); this.device.addConnection(conn); this.device.addApplicationEntity(ae); ae.addConnection(conn); }
@POST @Path("/studies") @Consumes({"multipart/related", "multipart/form-data"}) public Response storeInstances(InputStream in) throws Exception { String str = req.toString(); LOG.info(str); init(); final StoreSession session = storeService.createStoreSession(storeService); session.setSource(new HttpSource(request)); ApplicationEntity sourceAE = aeCache.findAE(new HttpSource(request)); session.setRemoteAET( sourceAE != null ? sourceAE.getAETitle() : null); // add AE for the web source session.setArchiveAEExtension(arcAE); storeService.initStorageSystem(session); storeService.initSpoolDirectory(session); storeService.initMetaDataStorageSystem(session); try { new MultipartParser(boundary) .parse( in, new MultipartParser.Handler() { @Override public void bodyPart(int partNumber, MultipartInputStream in) throws IOException { Map<String, List<String>> headerParams = in.readHeaderParams(); String transferSyntax = null; LOG.info("storeInstances: Extract Part #{}{}", partNumber, headerParams); String contentType = getHeaderParamValue(headerParams, "content-type"); String contentLocation = getHeaderParamValue(headerParams, "content-location"); MediaType mediaType; try { mediaType = contentType == null ? MediaType.TEXT_PLAIN_TYPE : MediaType.valueOf(contentType); } catch (IllegalArgumentException e) { LOG.info( "storeInstances: Ignore Part with illegal Content-Type={}", contentType); in.skipAll(); return; } // check for metadata transfer syntax if (contentLocation == null) { transferSyntax = contentType.contains("transfer-syntax=") ? contentType.split("transfer-syntax=")[1] : null; } if (!creatorType.readBodyPart( StowRS.this, session, in, mediaType, contentLocation, transferSyntax)) { LOG.info("storeInstances: Ignore Part with Content-Type={}", mediaType); in.skipAll(); } } }); creatorType.storeMetadataAndBulkdata(this, session); } finally { storeService.onClose(session); } return buildResponse(); }