Search in sources :

Example 16 with InstanceLocations

use of org.dcm4chee.arc.store.InstanceLocations in project dcm4chee-arc-light by dcm4che.

the class RetrieveServiceImpl method removeNotAccessableMatches.

@Override
public Map<String, Collection<InstanceLocations>> removeNotAccessableMatches(RetrieveContext ctx) {
    ArchiveAEExtension arcAE = ctx.getArchiveAEExtension();
    String altCMoveSCP = arcAE.alternativeCMoveSCP();
    ArchiveDeviceExtension arcDev = getArchiveDeviceExtension();
    Collection<InstanceLocations> matches = ctx.getMatches();
    int numMatches = matches.size();
    Map<String, Collection<InstanceLocations>> notAccessable = new HashMap<>(1);
    Iterator<InstanceLocations> iter = matches.iterator();
    while (iter.hasNext()) {
        InstanceLocations match = iter.next();
        if (!isAccessable(arcDev, match)) {
            iter.remove();
            if (!match.getLocations().isEmpty())
                putMatchTo(notAccessable, altCMoveSCP, match, numMatches);
            else
                putMatchTo(notAccessable, StringUtils.maskNull(match.getExternalRetrieveAET(), altCMoveSCP), match, numMatches);
        }
    }
    return notAccessable;
}
Also used : InstanceLocations(org.dcm4chee.arc.store.InstanceLocations)

Example 17 with InstanceLocations

use of org.dcm4chee.arc.store.InstanceLocations in project dcm4chee-arc-light by dcm4che.

the class RetrieveServiceImpl method restrictRetrieveAccordingTransferCapabilities.

@Override
public boolean restrictRetrieveAccordingTransferCapabilities(RetrieveContext ctx) {
    ArchiveAEExtension arcAE = ctx.getArchiveAEExtension();
    ApplicationEntity destAE = ctx.getDestinationAE();
    boolean noDestinationRestriction = destAE.getTransferCapabilitiesWithRole(SCP).isEmpty();
    Collection<InstanceLocations> matches = ctx.getMatches();
    Iterator<InstanceLocations> iter = matches.iterator();
    boolean restrictRetrieveSilently = arcAE.restrictRetrieveSilently();
    while (iter.hasNext()) {
        InstanceLocations match = iter.next();
        if (!(ctx.getLocalApplicationEntity().hasTransferCapabilityFor(match.getSopClassUID(), SCU) && (noDestinationRestriction || destAE.hasTransferCapabilityFor(match.getSopClassUID(), SCP)))) {
            iter.remove();
            if (restrictRetrieveSilently) {
                ctx.decrementNumberOfMatches();
            } else {
                ctx.incrementFailed();
                ctx.addFailedSOPInstanceUID(match.getSopInstanceUID());
            }
            LOG.info("{}: failed to send {} to {} - no Presentation Context offered", ctx.getRequestAssociation(), match, ctx.getDestinationAETitle());
        }
    }
    return !matches.isEmpty();
}
Also used : InstanceLocations(org.dcm4chee.arc.store.InstanceLocations)

Example 18 with InstanceLocations

use of org.dcm4chee.arc.store.InstanceLocations in project dcm4chee-arc-light by dcm4che.

the class RetrieveServiceImpl method calculateMatches.

@Override
public boolean calculateMatches(RetrieveContext ctx) throws DicomServiceException {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    Collection<InstanceLocations> matches = ctx.getMatches();
    matches.clear();
    try {
        HashMap<Long, StudyInfo> studyInfoMap = new HashMap<>();
        Series.MetadataUpdate metadataUpdate = ctx.getSeriesMetadataUpdate();
        if (metadataUpdate != null && metadataUpdate.instancePurgeState == Series.InstancePurgeState.PURGED) {
            SeriesAttributes seriesAttributes = new SeriesAttributes(em, cb, metadataUpdate.seriesPk);
            studyInfoMap.put(seriesAttributes.studyInfo.getStudyPk(), seriesAttributes.studyInfo);
            ctx.getSeriesInfos().add(seriesAttributes.seriesInfo);
            addLocationsFromMetadata(ctx, metadataUpdate.storageID, metadataUpdate.storagePath, seriesAttributes.attrs);
        } else {
            new LocationQuery(em, cb, ctx, codeCache).execute(studyInfoMap);
            if (ctx.isConsiderPurgedInstances())
                queryLocationsFromMetadata(ctx, cb, studyInfoMap);
        }
        ctx.setNumberOfMatches(matches.size());
        ctx.getStudyInfos().addAll(studyInfoMap.values());
        updateStudyAccessTime(ctx);
        return !matches.isEmpty();
    } catch (IOException e) {
        throw new DicomServiceException(Status.UnableToCalculateNumberOfMatches, e);
    }
}
Also used : InstanceLocations(org.dcm4chee.arc.store.InstanceLocations) IOException(java.io.IOException) DicomServiceException(org.dcm4che3.net.service.DicomServiceException)

Example 19 with InstanceLocations

use of org.dcm4chee.arc.store.InstanceLocations in project dcm4chee-arc-light by dcm4che.

the class RetrieveServiceImpl method queryInstances.

@Override
public Collection<InstanceLocations> queryInstances(StoreSession session, Attributes instanceRefs, String targetStudyIUID) throws IOException {
    Map<String, String> uidMap = session.getUIDMap();
    String sourceStudyUID = instanceRefs.getString(Tag.StudyInstanceUID);
    uidMap.put(sourceStudyUID, targetStudyIUID);
    Sequence refSeriesSeq = instanceRefs.getSequence(Tag.ReferencedSeriesSequence);
    Map<String, Set<String>> refIUIDsBySeriesIUID = new HashMap<>();
    RetrieveContext ctx;
    if (refSeriesSeq == null) {
        ctx = newRetrieveContextIOCM(session.getHttpRequest(), session.getCalledAET(), sourceStudyUID);
    } else {
        for (Attributes item : refSeriesSeq) {
            String seriesIUID = item.getString(Tag.SeriesInstanceUID);
            uidMap.put(seriesIUID, UIDUtils.createUID());
            refIUIDsBySeriesIUID.put(seriesIUID, refIUIDs(item.getSequence(Tag.ReferencedSOPSequence)));
        }
        ctx = newRetrieveContextIOCM(session.getHttpRequest(), session.getCalledAET(), sourceStudyUID, refIUIDsBySeriesIUID.keySet().toArray(StringUtils.EMPTY_STRING));
    }
    ctx.setObjectType(null);
    if (!calculateMatches(ctx))
        return Collections.EMPTY_LIST;
    Collection<InstanceLocations> matches = ctx.getMatches();
    Iterator<InstanceLocations> matchesIter = matches.iterator();
    while (matchesIter.hasNext()) {
        InstanceLocations il = matchesIter.next();
        if (contains(refIUIDsBySeriesIUID, il)) {
            uidMap.put(il.getSopInstanceUID(), UIDUtils.createUID());
            if (refSeriesSeq == null)
                if (!uidMap.containsKey(il.getAttributes().getString(Tag.SeriesInstanceUID)))
                    uidMap.put(il.getAttributes().getString(Tag.SeriesInstanceUID), UIDUtils.createUID());
        } else
            matchesIter.remove();
    }
    return matches;
}
Also used : InstanceLocations(org.dcm4chee.arc.store.InstanceLocations)

Example 20 with InstanceLocations

use of org.dcm4chee.arc.store.InstanceLocations in project dcm4chee-arc-light by dcm4che.

the class CommonCMoveSCP method calculateMatches.

@Override
protected RetrieveTask calculateMatches(Association as, PresentationContext pc, Attributes rq, Attributes keys) throws DicomServiceException {
    LOG.info("{}: Process C-MOVE RQ:\n{}", as, keys);
    EnumSet<QueryOption> queryOpts = as.getQueryOptionsFor(rq.getString(Tag.AffectedSOPClassUID));
    QueryRetrieveLevel2 qrLevel = QueryRetrieveLevel2.validateRetrieveIdentifier(keys, qrLevels, queryOpts.contains(QueryOption.RELATIONAL), relationalRetrieveNegotiationLenient(as));
    ArchiveAEExtension arcAE = as.getApplicationEntity().getAEExtension(ArchiveAEExtension.class);
    if (!arcAE.isAcceptedMoveDestination(rq.getString(Tag.MoveDestination)))
        throw new DicomServiceException(RetrieveService.MOVE_DESTINATION_NOT_ALLOWED, RetrieveService.MOVE_DESTINATION_NOT_ALLOWED_MSG);
    RetrieveContext ctx = newRetrieveContext(arcAE, as, rq, qrLevel, keys);
    String fallbackCMoveSCP = arcAE.fallbackCMoveSCP();
    String fallbackCMoveSCPCallingAET = arcAE.fallbackCMoveSCPCallingAET(as);
    String fallbackCMoveSCPDestination = arcAE.fallbackCMoveSCPDestination();
    if (!retrieveService.calculateMatches(ctx)) {
        if (fallbackCMoveSCP == null)
            return null;
        ctx.setRetryFailedRetrieve(true);
        LOG.info("{}: No objects of study{} found - forward C-MOVE RQ to {}", as, Arrays.toString(ctx.getStudyInstanceUIDs()), fallbackCMoveSCP);
        return moveSCU.newForwardRetrieveTask(ctx, pc, rq, keys, fallbackCMoveSCPCallingAET, fallbackCMoveSCP, fallbackCMoveSCPDestination);
    }
    if (!retrieveService.restrictRetrieveAccordingTransferCapabilities(ctx)) {
        if (ctx.failed() > 0) {
            throw new DicomServiceException(Status.UnableToPerformSubOperations).setNumberOfCompletedFailedWarningSuboperations(ctx.completed(), ctx.failed(), ctx.warning());
        }
        return null;
    }
    Map<String, Collection<InstanceLocations>> notAccessable = retrieveService.removeNotAccessableMatches(ctx);
    String altCMoveSCP = arcAE.alternativeCMoveSCP();
    if (ctx.getMoveOriginatorAETitle().equals(altCMoveSCP)) {
        // mask altCMoveSCP in Move Originator AET in C-STORE RQ - assume Destination originated Move RQ to altCMoveSCP
        ctx.setMoveOriginatorAETitle(ctx.getDestinationAETitle());
        // ignore not accessible matches - assume they are handled by altCMoveSCP
        ctx.setNumberOfMatches(ctx.getMatches().size());
    } else {
        boolean retryFailedRetrieve = fallbackCMoveSCP != null && fallbackCMoveSCPDestination != null && retryFailedRetrieve(ctx, qrLevel);
        // TODO
        Collection<InstanceLocations> notRetrieveable = notAccessable.remove(null);
        Iterator<Map.Entry<String, Collection<InstanceLocations>>> notAccessableIter = notAccessable.entrySet().iterator();
        if (notAccessableIter.hasNext()) {
            Map.Entry<String, Collection<InstanceLocations>> notAccessableNext = notAccessableIter.next();
            String otherCMoveSCP = notAccessableNext.getKey();
            String otherMoveDest = otherCMoveSCP.equals(altCMoveSCP) ? null : arcAE.externalRetrieveAEDestination();
            while (notAccessableIter.hasNext()) {
                LOG.info("{}: {} objects of study{} not locally accessable - send C-MOVE RQ to {}", as, notAccessableNext.getValue().size(), Arrays.toString(ctx.getStudyInstanceUIDs()), otherCMoveSCP);
                moveSCU.forwardMoveRQ(ctx, pc, rq, keys, null, otherCMoveSCP, otherMoveDest);
                notAccessableNext = notAccessableIter.next();
                otherCMoveSCP = notAccessableNext.getKey();
                otherMoveDest = otherCMoveSCP.equals(altCMoveSCP) ? null : arcAE.externalRetrieveAEDestination();
            }
            LOG.info("{}: {} objects of study{} not locally accessable - send C-MOVE RQ to {}", as, notAccessableNext.getValue().size(), Arrays.toString(ctx.getStudyInstanceUIDs()), otherCMoveSCP);
            if (!retryFailedRetrieve && ctx.getMatches().isEmpty()) {
                return moveSCU.newForwardRetrieveTask(ctx, pc, rq, keys, null, otherCMoveSCP, otherMoveDest);
            }
            moveSCU.forwardMoveRQ(ctx, pc, rq, keys, null, otherCMoveSCP, otherMoveDest);
        }
        if (retryFailedRetrieve) {
            ctx.setRetryFailedRetrieve(true);
            LOG.info("{}: Some objects of study{} not found - retry forward C-MOVE RQ to {}", as, Arrays.toString(ctx.getStudyInstanceUIDs()), fallbackCMoveSCP);
            if (ctx.getMatches().isEmpty())
                return moveSCU.newForwardRetrieveTask(ctx, pc, rq, keys, fallbackCMoveSCPCallingAET, fallbackCMoveSCP, fallbackCMoveSCPDestination);
            moveSCU.forwardMoveRQ(ctx, pc, rq, keys, fallbackCMoveSCPCallingAET, fallbackCMoveSCP, fallbackCMoveSCPDestination);
        }
    }
    return storeSCU.newRetrieveTaskMOVE(as, pc, rq, ctx);
}
Also used : InstanceLocations(org.dcm4chee.arc.store.InstanceLocations) ArchiveAEExtension(org.dcm4chee.arc.conf.ArchiveAEExtension) QueryOption(org.dcm4che3.net.QueryOption) QueryRetrieveLevel2(org.dcm4che3.net.service.QueryRetrieveLevel2) DicomServiceException(org.dcm4che3.net.service.DicomServiceException)

Aggregations

InstanceLocations (org.dcm4chee.arc.store.InstanceLocations)34 IOException (java.io.IOException)8 RetrieveContext (org.dcm4chee.arc.retrieve.RetrieveContext)7 StoreService (org.dcm4chee.arc.store.StoreService)6 DicomServiceException (org.dcm4che3.net.service.DicomServiceException)5 ArchiveAEExtension (org.dcm4chee.arc.conf.ArchiveAEExtension)5 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 java.util (java.util)4 Collectors (java.util.stream.Collectors)4 ZipEntry (java.util.zip.ZipEntry)4 Event (javax.enterprise.event.Event)4 Inject (javax.inject.Inject)4 Attributes (org.dcm4che3.data.Attributes)4 HttpServletRequestInfo (org.dcm4chee.arc.keycloak.HttpServletRequestInfo)4 StoreSession (org.dcm4chee.arc.store.StoreSession)4 Map (java.util.Map)3 ZipOutputStream (java.util.zip.ZipOutputStream)3 Tag (org.dcm4che3.data.Tag)3 DicomInputStream (org.dcm4che3.io.DicomInputStream)3