protected Dataset doNSet(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Command cmd = rq.getCommand(); String iuid = cmd.getRequestedSOPInstanceUID(); Dataset ds = rq.getDataset(); checkStudyIuid(iuid, ds); try { StudyMgt stymgt = getStudyMgtHome().create(); try { stymgt.updateStudy(iuid, ds, service.studyMovePatientMatching()); } finally { try { stymgt.remove(); } catch (Exception e) { log.warn("Failed to remove StudyMgt Session Bean", e); } } } catch (DcmServiceException e) { throw e; } catch (Exception e) { throw new DcmServiceException(Status.ProcessingFailure, e); } service.sendStudyMgtNotification(assoc, Command.N_SET_RQ, 0, iuid, ds); return null; }
protected Dataset doNAction(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Command cmd = rq.getCommand(); int actionTypeID = cmd.getInt(Tags.ActionTypeID, -1); String iuid = cmd.getRequestedSOPInstanceUID(); Dataset ds = rq.getDataset(); if (log.isDebugEnabled()) { log.debug("Received N-Action cmd with ds:"); log.debug(ds); } checkStudyIuid(iuid, ds); try { switch (actionTypeID) { case 1: service.moveSeriesToTrash(toSeriesIuids(ds)); break; case 2: service.moveInstancesToTrash(toSopIuids(ds)); break; } } catch (Exception e) { throw new DcmServiceException(Status.ProcessingFailure, e); } service.sendStudyMgtNotification(assoc, Command.N_ACTION_RQ, actionTypeID, iuid, ds); return null; }
protected Dataset doNCreate(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Command cmd = rq.getCommand(); String iuid = cmd.getAffectedSOPInstanceUID(); Dataset ds = rq.getDataset(); String suid = ds.getString(Tags.StudyInstanceUID); if (suid == null) { throw new DcmServiceException(Status.MissingAttribute, "Missing Study Instance UID"); } if (iuid == null) { rspCmd.putUI(Tags.AffectedSOPInstanceUID, iuid = suid); } else { checkStudyIuid(iuid, ds); } try { StudyMgt stymgt = getStudyMgtHome().create(); try { stymgt.createStudy(ds, service.patientMatching()); } finally { try { stymgt.remove(); } catch (Exception e) { log.warn("Failed to remove StudyMgt Session Bean", e); } } } catch (DcmServiceException e) { throw e; } catch (Exception e) { throw new DcmServiceException(Status.ProcessingFailure, e); } service.sendStudyMgtNotification(assoc, Command.N_CREATE_RQ, 0, iuid, ds); return null; }
/** * Implements the ECHO service. The C-ECHO service is invoked by a DIMSE-service-user to verify * end-to-end communications with a peer DIMSE-service-user. See PS 3.7 - 9.1.5 C-ECHO SERVICE * * @exception ConnectException * @exception InterruptedException * @exception IOException */ public long cECHO() throws ConnectException, InterruptedException, IOException { PresContext pc; long t1 = System.currentTimeMillis(); // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // Test, if Presentation Context for C-ECHO is supported // API doc: Association.getAcceptedPresContext(String asuid, String tsuid) if ((pc = aassoc .getAssociation() .getAcceptedPresContext(UIDs.Verification, UIDs.ImplicitVRLittleEndian)) == null) { throw new ConnectException( "Association does not support presentation context: Verification SOP/ImplicitVRLittleEndian."); } // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command cEchoRQ = oFact.newCommand(); // API doc: Command.initCEchoRQ(int msgID) cEchoRQ.initCEchoRQ(1); // API doc: AssociationFactorynewDimse(int pcid, Command cmd) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse echoRq = aFact.newDimse(pc.pcid(), cEchoRQ); // PS 3.7 - 9.3.5 C-ECHO PROTOCOL, 9.3.5.2 C-ECHO-RSP // Always returns SUCESS result code. // Invoke active association with echo request Dimse FutureRSP future = aassoc.invoke(echoRq); // Response to the C-ECHO request. // The result cannot be accessed until it has been set. Dimse echoRsp = future.get(); Command rspCmd = echoRsp.getCommand(); // PS 3.7 - 9.3.5 C-MOVE PROTOCOL, 9.3.5.2 C-ECHO-RSP int status = rspCmd.getStatus(); switch (status) { case 0x0000: // Success break; default: log.error("C-ECHO failed: " + Integer.toHexString(status)); break; } return System.currentTimeMillis() - t1; }
@Override protected Dataset doNGet(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Command rqCmd = rq.getCommand(); Dataset rqData = rq.getDataset(); if (!abstractSyntaxEquals( assoc, rq, UIDs.UnifiedProcedureStepPullSOPClass, UIDs.UnifiedProcedureStepWatchSOPClass)) throw new DcmServiceException(Status.UnrecognizedOperation); if (rqData != null) throw new DcmServiceException(Status.MistypedArgument, "N-GET-RQ includes Data Set"); return service.getUPS( rspCmd.getAffectedSOPInstanceUID(), rqCmd.getTags(Tags.AttributeIdentifierList)); }
@Override protected Dataset doNCreate(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { String calledAET = assoc.getAssociation().getCalledAET(); Command rqCmd = rq.getCommand(); Dataset rqData = rq.getDataset(); if (!abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepPushSOPClass)) throw new DcmServiceException(UNRECOGNIZE_OPERATION); log.debug("Identifier:\n"); log.debug(rqData); checkNCreateRQ(rqCmd, rqData); coerceNCreateRQ(rspCmd, rqData); service.createUPS(calledAET, rqData); return null; }
@Override protected Dataset doNSet(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { String calledAET = assoc.getAssociation().getCalledAET(); Command rqCmd = rq.getCommand(); Dataset rqData = rq.getDataset(); if (!abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepPullSOPClass)) throw new DcmServiceException(UNRECOGNIZE_OPERATION); log.debug("Identifier:\n"); log.debug(rqData); checkNSetRQ(rqCmd, rqData); initSPSModificationDateandTime(rqData); service.updateUPS(calledAET, rspCmd.getAffectedSOPInstanceUID(), rqData); return null; }
protected Dataset doNDelete(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Command cmd = rq.getCommand(); String iuid = cmd.getRequestedSOPInstanceUID(); Dataset ds = rq.getDataset(); // should be null try { service.moveStudyToTrash(iuid); } catch (ObjectNotFoundException e) { if (!ignoreDeleteFailed) { throw new DcmServiceException(Status.NoSuchObjectInstance); } } catch (Exception e) { throw new DcmServiceException(Status.ProcessingFailure, e); } service.sendStudyMgtNotification(assoc, Command.N_DELETE_RQ, 0, iuid, null); return null; }
void sendPPS(boolean create, Dataset pps, String aet) throws Exception { ActiveAssociation aa = openAssociation(aet, UIDs.GeneralPurposePerformedProcedureStepSOPClass); try { Association a = aa.getAssociation(); DcmObjectFactory dof = DcmObjectFactory.getInstance(); Command cmdRq = dof.newCommand(); final String iuid = pps.getString(Tags.SOPInstanceUID); if (create) { cmdRq.initNCreateRQ(a.nextMsgID(), UIDs.GeneralPurposePerformedProcedureStepSOPClass, iuid); } else { cmdRq.initNSetRQ(a.nextMsgID(), UIDs.GeneralPurposePerformedProcedureStepSOPClass, iuid); } Dimse dimseRq = AssociationFactory.getInstance().newDimse(PCID_GPPPS, cmdRq, pps.exclude(SOP_IUID)); if (log.isDebugEnabled()) { log.debug("GP-PPS Attributes:"); log.debug(pps); } final Dimse dimseRsp = aa.invoke(dimseRq).get(); final Command cmdRsp = dimseRsp.getCommand(); final int status = cmdRsp.getStatus(); switch (status) { case 0x0000: break; case 0x0116: log.warn( "Received Warning Status 116H (=Attribute Value Out of Range) from remote AE " + aet); break; default: throw new DcmServiceException(status, cmdRsp.getString(Tags.ErrorComment)); } } finally { try { aa.release(true); } catch (Exception e) { log.warn("Failed to release " + aa.getAssociation()); } } }
protected void load(AttributeCoercions acs, String dn) throws NamingException { NamingEnumeration<SearchResult> ne = search(dn, "(objectclass=dcmAttributeCoercion)"); try { while (ne.hasMore()) { SearchResult sr = ne.next(); Attributes attrs = sr.getAttributes(); acs.add( new AttributeCoercion( stringValue(attrs.get("dicomSOPClass"), null), Dimse.valueOf(stringValue(attrs.get("dcmDIMSE"), null)), TransferCapability.Role.valueOf(stringValue(attrs.get("dicomTransferRole"), null)), stringValue(attrs.get("dicomAETitle"), null), stringValue(attrs.get("labeledURI"), null))); } } finally { safeClose(ne); } }
@Override protected Dataset doNAction(ActiveAssociation assoc, Dimse rq, Command rspCmd) throws IOException, DcmServiceException { Association a = assoc.getAssociation(); String calledAET = a.getCalledAET(); String callingAET = a.getCallingAET(); String receivingAET; Command rqCmd = rq.getCommand(); Dataset rqData = rq.getDataset(); int actionTypeID = rqCmd.getInt(Tags.ActionTypeID, 0); rspCmd.putUS(Tags.ActionTypeID, actionTypeID); String iuid = rqCmd.getRequestedSOPInstanceUID(); String tuid; int state; boolean dellock; switch (actionTypeID) { case 1: if (abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepPullSOPClass)) { type1(rqData, Tags.UPSState); state = UPSScpService.upsStateAsInt(rqData.getString(Tags.UPSState)); if (state == UPSState.SCHEDULED) throw new DcmServiceException(MAY_ONLY_BECOME_SCHEDULED_VIA_NCREATE); tuid = rqData.getString(Tags.TransactionUID); if (tuid == null) throw new DcmServiceException(CORRECT_TRANSACTION_UID_NOT_PROVIDED); service.changeUPSState(calledAET, iuid, state, tuid); return rqData; } break; case 2: if (abstractSyntaxEquals( assoc, rq, UIDs.UnifiedProcedureStepPushSOPClass, UIDs.UnifiedProcedureStepWatchSOPClass)) { checkCodeItem(rqData, ItemCount.SINGLE, Tags.UPSDiscontinuationReasonCodeSeq); service.requestUPSCancel(calledAET, iuid, callingAET, rqData); return rqData; } break; case 3: if (abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepWatchSOPClass)) { type1(rqData, Tags.ReceivingAE); type1(rqData, Tags.DeletionLock); receivingAET = rqData.getString(Tags.ReceivingAE); dellock = deletionLockAsBoolean(rqData.getString(Tags.DeletionLock)); if (iuid.equals(UIDs.UnifiedWorklistandProcedureStepSOPInstance)) service.subscribeGlobally(calledAET, receivingAET, dellock); else service.subscribeReceiveUPSEventReports(calledAET, iuid, receivingAET, dellock); return rqData; } break; case 4: if (abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepWatchSOPClass)) { type1(rqData, Tags.ReceivingAE); receivingAET = rqData.getString(Tags.ReceivingAE); if (iuid.equals(UIDs.UnifiedWorklistandProcedureStepSOPInstance)) service.unsubscribeGlobally(receivingAET); else service.unsubscribeReceiveUPSEventReports(iuid, receivingAET); return rqData; } break; case 5: if (abstractSyntaxEquals(assoc, rq, UIDs.UnifiedProcedureStepWatchSOPClass) && iuid.equals(UIDs.UnifiedWorklistandProcedureStepSOPInstance)) { type1(rqData, Tags.ReceivingAE); receivingAET = rqData.getString(Tags.ReceivingAE); service.suspendGlobalSubscription(receivingAET); return rqData; } break; } throw new DcmServiceException(Status.NoSuchActionType).setActionTypeID(actionTypeID); }
private static boolean abstractSyntaxEquals( ActiveAssociation assoc, Dimse rq, String uid1, String uid2) { String asuid = assoc.getAssociation().getProposedPresContext(rq.pcid()).getAbstractSyntaxUID(); return asuid.equals(uid1) || asuid.equals(uid2); }
public Vector cGET(Dataset ds) throws ConnectException, IOException, InterruptedException { PresContext pc; List dimseList; Vector datasetVector; // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // Test, if Presentation Context for C-MOVE is supported // API doc: Association.getAcceptedPresContext(String asuid, String tsuid) if ((pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelGET, UIDs.ExplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelGET, UIDs.ImplicitVRLittleEndian)) == null) { throw new ConnectException( "Association does not support presentation context for StudyRootQueryRetrieveInformationModelMOVE SOP."); } // Get the Study Instance UID of the study to mode String suid = ds.getString(Tags.SOPInstanceUID); // Prepare info for logging String patName = ds.getString(Tags.PatientName); String patID = ds.getString(Tags.PatientID); String studyDate = ds.getString(Tags.StudyDate); String prompt = "Study[" + suid + "] from " + studyDate + " for Patient[" + patID + "]: " + patName; // log.info("Moving: " + prompt); // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command rqCmd = dof.newCommand(); // API doc: Command.initCMoveRQ(int msgID, String sopClassUID, int priority, String moveDest) rqCmd.initCGetRSP(assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelGET, priority); Dataset rqDs = dof.newDataset(); rqDs.putCS(Tags.QueryRetrieveLevel, getQueryRetrieveLevel(STUDY_LEVEL)); // Only Unique Key allowed in C-MOVE. PS 3.4 -C.2.2.1 Attribute Types rqDs.putUI(Tags.SOPInstanceUID, suid); // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse moveRq = aFact.newDimse(pc.pcid(), rqCmd, rqDs); // Invoke active association with move request Dimse FutureRSP future = aassoc.invoke(moveRq); // Response to the C-MOVE request. // The result cannot be accessed until it has been set. Dimse moveRsp = future.get(); Command rspCmd = moveRsp.getCommand(); if (DEBUG) { StringWriter w = new StringWriter(); w.write("C-FIND RQ Identifier:\n"); keys.dumpDataset(w, null); log.debug(w.toString()); } // Invoke active association with find request Dimse // Response to the C-FIND request. // The result cannot be accessed until it has been set. // Get the list of found objects dimseList = future.listPending(); // >>>> Extract Dataset from Dimse datasetVector = new Vector(); // If no List of DIMSE objects was generated or it is empty return an empty Vector if (dimseList == null || dimseList.isEmpty()) { return datasetVector; } // Process all elements for (int i = 0; i < dimseList.size(); i++) { datasetVector.addElement(((Dimse) dimseList.get(i)).getDataset()); if (((Dimse) dimseList.get(i)).getDataset() == null) System.out.println(" Dataset created succesffullyu "); } // PS 3.7 - 9.3.4 C-MOVE PROTOCOL, 9.3.4.2 C-MOVE-RSP int status = rspCmd.getStatus(); switch (status) { case 0x0000: // log.info("Moved: " + prompt); break; case 0xB000: log.error("One or more failures during move of " + prompt); break; default: log.error("Failed to move " + prompt + "\n\terror tstatus: " + Integer.toHexString(status)); break; } System.out.println("The move sise is : " + datasetVector.size()); return datasetVector; }
/** * Stores a DICOM object in an archive (Storage SCP). * * <p>See PS 3.4 - Annex B STORAGE SERVICE CLASS. * * @param ds the Dataset to store. * @throws ConnectException * @throws ParseException * @throws IOException * @throws InterruptedException * @throws IllegalStateException */ public void cSTORE(Dataset ds) throws InterruptedException, IOException, ConnectException, ParseException { String sopClassUID; String sopInstUID; PresContext pc = null; // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // SOP Class UID must be given if ((sopClassUID = ds.getString(Tags.SOPClassUID)) == null) { throw new ParseException("No SOP Class UID in Dataset", 0); } // SOP Instance UID must be given if ((sopInstUID = ds.getString(Tags.SOPInstanceUID)) == null) { throw new ParseException("No SOP Instance UID in Dataset", 0); } // Test, if applicable presentation context was found if ((pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ImplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ExplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ExplicitVRBigEndian)) == null) { throw new ConnectException("No applicable presentation context found"); } // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command cStoreRQ = oFact.newCommand(); // API doc: Command.initCStoreRQ(int msgID, String sopClassUID, String sopInstUID, int priority) cStoreRQ.initCStoreRQ(assoc.nextMsgID(), sopClassUID, sopInstUID, priority); // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse storeRq = aFact.newDimse(pc.pcid(), cStoreRQ, ds); // PS 3.7 - 9.3.1 C-STORE PROTOCOL, 9.3.1.2 C-STORE-RSP // Always returns SUCESS result code. // Invoke active association with echo request Dimse FutureRSP future = aassoc.invoke(storeRq); System.out.println("store is going in this AE"); // Response to the C-ECHO request. // The result cannot be accessed until it has been set. Dimse storeRsp = future.get(); Command rspCmd = storeRsp.getCommand(); // PS 3.7 - 9.3.5 C-MOVE PROTOCOL, 9.3.5.2 C-ECHO-RSP int status = rspCmd.getStatus(); switch (status) { case 0x0000: // Success break; default: log.error("C-STORE failed: " + Integer.toHexString(status)); break; } }