Exemplo n.º 1
0
 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;
 }
Exemplo n.º 2
0
 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;
 }
Exemplo n.º 3
0
 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;
 }
Exemplo n.º 4
0
 @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));
 }
Exemplo n.º 5
0
 @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;
 }
Exemplo n.º 6
0
 @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;
 }
Exemplo n.º 7
0
 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;
 }
Exemplo n.º 8
0
 @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);
 }
  /**
   * Ask archive to move one DICOM object to the destination (C-MOVE). See PS 3.4 - Annex C
   * QUERY/RETRIEVE SERVICE CLASS.
   *
   * <p>Use the Study Root Query/Retrieve Information Model to communicate with the archive. See PS
   * 3.4 - C.6.2 Study Root SOP Class Group.
   *
   * <p>PS 3.4 - C.4.2.1.4.1 Request Identifier Structure (for C-MOVE): An Identifier in a C-MOVE
   * request shall contain:
   *
   * <p>- the Query/Retrieve Level (0008,0052) which defines the level of the retrieval
   *
   * <p>- Unique Key Attributes which may include Patient ID, Study Instance UIDs, Series Instance
   * UIDs, and the SOP Instance UIDs
   *
   * <p>PS 3.4 - C.4.2.2.1 Baseline Behavior of SCU (of C-MOVE):
   *
   * <p>The SCU shall supply a single value in the Unique Key Attribute for each level above the
   * Query/Retrieve level. For the level of retrieve, the SCU shall supply one unique key if the
   * level of retrieve is above the STUDY level and shall supply one UID, or a list of UIDs if a
   * retrieval of several items is desired and the retrieve level is STUDY, SERIES or IMAGE.
   *
   * @param ds the DICOM object represented as a Dataset.
   * @return a result-code: 0x0000 = SUCCESS sub-operations complete no failures, 0xB000 = WARNING
   *     sub-operations complete one or more failures, other = errors defined in PS 3.4 - C.4.2.1.5
   *     Status
   * @throws ConnectException
   * @throws InterruptedException
   * @throws IOException
   */
  public Vector cMOVE(Dataset ds) throws ConnectException, InterruptedException, IOException {
    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.StudyRootQueryRetrieveInformationModelMOVE,
                        UIDs.ExplicitVRLittleEndian))
            == null
        && (pc =
                aassoc
                    .getAssociation()
                    .getAcceptedPresContext(
                        UIDs.StudyRootQueryRetrieveInformationModelMOVE,
                        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.StudyInstanceUID);

    // 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.initCMoveRQ(
        assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelMOVE, priority, dest);
    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.StudyInstanceUID, 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();
    Dataset dds = moveRsp.getDataset();

    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
    Dimse dms = future.get();

    // >>>> 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;
  }