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;
}
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();
}
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);
}
}
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;
}
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);
}
Aggregations