public bool SaveStreamData(DicomMessage message, byte[] data, int offset, int count)
		{
			var importer = new SopInstanceImporter(_importContext);
			var sopInstanceUid = message.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);
			
			if (_fileStream == null)
			{
				if (!importer.GetStreamedFileStorageFolder(message, out _sourceFolder, out _filesystemStreamingFolder))
				{
					Platform.Log(LogLevel.Warn, "Unable to create a folder to save SOP Instance, rejecting: {0}", sopInstanceUid);
					return false;
				}

				_sourceFilename = Path.Combine(_sourceFolder, Guid.NewGuid().ToString() + ServerPlatform.DicomFileExtension);

				try
				{
					_fileStream = FileStreamOpener.OpenForSoleUpdate(_sourceFilename, FileMode.Create);
				}
				catch (Exception x)
				{
					Platform.Log(LogLevel.Warn, x, "Unable to open file for saving filestream: {0}", _sourceFilename);
					return false;
				}
			}

			_fileStream.Write(data, offset, count);

			return true;
		}
		public bool SaveStreamData(DicomMessage message, byte[] data, int offset, int length)
		{
			if (_rejectFile) return true;

			if (_fileStream == null)
			{
				_sourceFolder = _context.StorageConfiguration.FileStoreIncomingFolder;

				_sourceFilename = Path.Combine(_sourceFolder, Guid.NewGuid().ToString() + ".cc");

				try
				{
					_fileStream = FileStreamOpener.OpenForSoleUpdate(_sourceFilename, FileMode.Create);
				}
				catch (Exception x)
				{
					Platform.Log(LogLevel.Warn, x, "Unable to open file for saving filestream: {0}", _sourceFilename);
					return false;
				}
			}

			_fileStream.Write(data, offset, length);

			return true;
		}
Example #3
0
File: Form1.cs Project: nhannd/Xian
		public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
		{
			foreach (byte pcid in association.GetPresentationContextIDs())
			{
				DicomPresContext context = association.GetPresentationContext(pcid);
				if (context.Result == DicomPresContextResult.Accept)
				{
					if (context.AbstractSyntax == SopClass.StudyRootQueryRetrieveInformationModelFind)
					{
						DicomMessage response = new DicomMessage();
						response.DataSet[DicomTags.StudyInstanceUid].SetStringValue("1.2.3");
						response.DataSet[DicomTags.PatientId].SetStringValue("1");
						response.DataSet[DicomTags.PatientsName].SetStringValue("test");
						response.DataSet[DicomTags.StudyId].SetStringValue("1");
						response.DataSet[DicomTags.StudyDescription].SetStringValue("dummy");
						server.SendCFindResponse(presentationID, message.MessageId, response, DicomStatuses.Pending);

						DicomMessage finalResponse = new DicomMessage();
						server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success);
					}
					else if (context.AbstractSyntax == SopClass.VerificationSopClass)
					{
						server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
					}
				}
			}
		}
		public override bool ReceiveMessageAsFileStream(Dicom.Network.DicomServer server, ServerAssociationParameters association, byte presentationId,
		                                                DicomMessage message)
		{
			var sopClassUid = message.AffectedSopClassUid;

			if (sopClassUid.Equals(SopClass.BreastTomosynthesisImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedCtImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedMrColorImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedMrImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedPetImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedUsVolumeStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedXaImageStorageUid)
			    || sopClassUid.Equals(SopClass.EnhancedXrfImageStorageUid)
			    || sopClassUid.Equals(SopClass.UltrasoundMultiFrameImageStorageUid)
			    || sopClassUid.Equals(SopClass.MultiFrameGrayscaleByteSecondaryCaptureImageStorageUid)
			    || sopClassUid.Equals(SopClass.MultiFrameGrayscaleWordSecondaryCaptureImageStorageUid)
			    || sopClassUid.Equals(SopClass.MultiFrameSingleBitSecondaryCaptureImageStorageUid)
			    || sopClassUid.Equals(SopClass.MultiFrameTrueColorSecondaryCaptureImageStorageUid))
			{
				server.DimseDatasetStopTag = DicomTagDictionary.GetDicomTag(DicomTags.ReconstructionIndex); // Random tag at the end of group 20
				server.StreamMessage = true;
				return true;
			}

			return false;
		}
Example #5
0
        /// <summary>
        /// Converts a <see cref="DicomMessage"/> instance into a <see cref="DicomFile"/>.
        /// </summary>
        /// <remarks>This routine sets the Source AE title, </remarks>
        /// <param name="message"></param>
        /// <param name="filename"></param>
        /// <param name="assocParms"></param>
        /// <returns></returns>
        protected static DicomFile ConvertToDicomFile(DicomMessage message, string filename, AssociationParameters assocParms)
        {
            // This routine sets some of the group 0x0002 elements.
            DicomFile file = new DicomFile(message, filename);

            file.SourceApplicationEntityTitle = assocParms.CallingAE;
            file.TransferSyntax = message.TransferSyntax;
            return file;
        }
Example #6
0
        /// <summary>
        /// Populate at the IMAGE level a response message.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
        /// <param name="theInstanceStream"></param>
        private void PopulateInstance(DicomAttributeCollection request, DicomMessage response, List<uint> tagList,
                                      InstanceXml theInstanceStream)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            DicomAttributeCollection sourceDataSet = theInstanceStream.Collection;

            if (false == sourceDataSet.Contains(DicomTags.SpecificCharacterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(sourceDataSet[DicomTags.SpecificCharacterSet].ToString());
                dataSet.SpecificCharacterSet = sourceDataSet[DicomTags.SpecificCharacterSet].ToString(); // this will ensure the data is encoded using the specified character set
            }

            foreach (uint tag in tagList)
            {
                try
                {
                    switch (tag)
                    {
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(request[DicomTags.PatientId].ToString());
                            break;
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                                request[DicomTags.StudyInstanceUid].ToString());
                            break;
                        case DicomTags.SeriesInstanceUid:
                            dataSet[DicomTags.SeriesInstanceUid].SetStringValue(
                                request[DicomTags.SeriesInstanceUid].ToString());
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                            break;
                        default:
                            if (sourceDataSet.Contains(tag))
                                dataSet[tag] = sourceDataSet[tag].Copy();
                            else
                                dataSet[tag].SetNullValue();
                            break;
                        // Meta tags that should have not been in the RQ, but we've already set
                        case DicomTags.RetrieveAeTitle:
                        case DicomTags.InstanceAvailability:
                        case DicomTags.SpecificCharacterSet:
                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    dataSet[tag].SetNullValue();
                }
            }
        }
		public override IDicomFilestreamHandler OnStartFilestream(Dicom.Network.DicomServer server, ServerAssociationParameters association,
		                                                          byte presentationId, DicomMessage message)
		{
			if (_importContext == null)
			{
				LoadImportContext(association);
			}

			return new StorageFilestreamHandler(Context, _importContext);
		}
Example #8
0
        private void SendCFind()
        {
            DicomMessage msg = new DicomMessage();
            DicomAttributeCollection cFindDataset = msg.DataSet;

            // set the Query Retrieve Level
            cFindDataset[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY");

            // set the other tags we want to retrieve
            cFindDataset[DicomTags.StudyInstanceUid].SetStringValue("");
            cFindDataset[DicomTags.PatientsName].SetStringValue("");
            cFindDataset[DicomTags.PatientId].SetStringValue("");
            cFindDataset[DicomTags.ModalitiesInStudy].SetStringValue("");
            cFindDataset[DicomTags.StudyDescription].SetStringValue("");


            byte pcid = _dicomClient.AssociationParams.FindAbstractSyntax(SopClass.StudyRootQueryRetrieveInformationModelFind);
            _dicomClient.SendCFindRequest(pcid, _dicomClient.NextMessageID(), msg);

        }
Example #9
0
 public void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
 {
     if (message.Status.Status == DicomState.Pending)
     {
         string studyinstanceuid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, "");
         if (OnResultReceive != null)
             OnResultReceive(message.DataSet);
     }
     else
     {
         _dicomClient.SendReleaseRequest();
     }
 }
Example #10
0
        public void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {

        }
Example #11
0
		private void OnReceiveCancelRequest(DicomMessage message)
		{
			lock (_syncLock)
			{
                foreach (SendOperationInfo info in _sendOperations)
                {
                    if (info.MessageId == message.MessageIdBeingRespondedTo)
                    {
                        RemoveSendOperationInfo(info);
                        WorkItemService.WorkItemService.Instance.Update(new WorkItemUpdateRequest
                                                                            {
                                                                                Cancel = true,
                                                                                Identifier = info.WorkItemData.Identifier
                                                                            });
                    }                    
                }
			}
		}
Example #12
0
        public void OnReceiveRequestMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
        {
            foreach (byte pcid in association.GetPresentationContextIDs())
            {
                DicomPresContext context = association.GetPresentationContext(pcid);
                if (context.Result == DicomPresContextResult.Accept)
                {
                    if (context.AbstractSyntax == SopClass.StudyRootQueryRetrieveInformationModelFind)
                    {
                        DicomMessage response = new DicomMessage();
                        response.DataSet[DicomTags.StudyInstanceUid].SetStringValue("1.2.3");
                        response.DataSet[DicomTags.PatientId].SetStringValue("1");
                        response.DataSet[DicomTags.PatientsName].SetStringValue("test");
                        response.DataSet[DicomTags.StudyId].SetStringValue("1");
                        response.DataSet[DicomTags.StudyDescription].SetStringValue("dummy");
                        server.SendCFindResponse(presentationID, message.MessageId, response, DicomStatuses.Pending);

                        DicomMessage finalResponse = new DicomMessage();
                        server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success);
                    }
                    else if (context.AbstractSyntax == SopClass.VerificationSopClass)
                    {
                        server.SendCEchoResponse(presentationID, message.MessageId, DicomStatuses.Success);
                    }
                }
            }
        }
		public override bool OnReceiveRequest(Dicom.Network.DicomServer server,
		                                      ServerAssociationParameters association, byte presentationID, DicomMessage message)
		{
			string studyInstanceUid;
			string seriesInstanceUid;
			DicomUid sopInstanceUid;

			bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);
			if (ok) ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid);
			if (ok) ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid);

			if (!ok)
			{
				Platform.Log(LogLevel.Error, "Unable to retrieve UIDs from request message, sending failure status.");

				server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
				                          DicomStatuses.ProcessingFailure);

				return true;
			}

			if (_importContext == null)
			{
				LoadImportContext(association);
			}

			var importer = new ImportFilesUtility(_importContext);

			var result = importer.Import(message, BadFileBehaviourEnum.Ignore, FileImportBehaviourEnum.Save);
			if (result.Successful)
			{
				if (!String.IsNullOrEmpty(result.AccessionNumber))
					Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})",
					             result.SopInstanceUid, association.CallingAE, association.CalledAE, result.AccessionNumber,
					             result.StudyInstanceUid);
				else
					Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})",
					             result.SopInstanceUid, association.CallingAE, association.CalledAE,
					             result.StudyInstanceUid);
				server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
			}
			else
			{
				if (result.DicomStatus == DicomStatuses.ProcessingFailure)
					Platform.Log(LogLevel.Error, "Failure importing sop: {0}", result.ErrorMessage);

				//OnReceiveError(message, result.ErrorMessage, association.CallingAE);
				server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid,
				                          result.DicomStatus, result.ErrorMessage);
			}

			return true;
		}
Example #14
0
        /// <summary>
        /// Method for processing Image level queries.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="presentationId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private void OnReceiveImageLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();
            var matchingTagList = new List<uint>();

            DicomAttributeCollection data = message.DataSet;
            string studyInstanceUid = data[DicomTags.StudyInstanceUid].GetString(0, String.Empty);
            string seriesInstanceUid = data[DicomTags.SeriesInstanceUid].GetString(0, String.Empty);

            StudyStorageLocation location;
        	try
        	{
        		FilesystemMonitor.Instance.GetReadableStudyStorageLocation(Partition.Key, studyInstanceUid, StudyRestore.True,
        		                                                           StudyCache.True, out location);
        	}
        	catch (Exception e)
        	{
        	    Platform.Log(LogLevel.Error, "Unable to load storage location for study {0}: {1}", studyInstanceUid, e.Message);
                var failureResponse = new DicomMessage();
                failureResponse.DataSet[DicomTags.InstanceAvailability].SetStringValue("NEARLINE");
                failureResponse.DataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                failureResponse.DataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
                failureResponse.DataSet[DicomTags.StudyInstanceUid].SetStringValue(studyInstanceUid);
				failureResponse.DataSet[DicomTags.SeriesInstanceUid].SetStringValue(seriesInstanceUid);
				server.SendCFindResponse(presentationId, message.MessageId, failureResponse,
                                         DicomStatuses.QueryRetrieveUnableToProcess);

				AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);

            	return;
            }
            try
            {
                // Will always return a value, although it may be an empty StudyXml file
                StudyXml studyXml = LoadStudyXml(location);

                SeriesXml seriesXml = studyXml[seriesInstanceUid];
                if (seriesXml == null)
                {
                    var failureResponse = new DicomMessage();
                    failureResponse.DataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                    server.SendCFindResponse(presentationId, message.MessageId, failureResponse,
                                             DicomStatuses.QueryRetrieveUnableToProcess);
                    AuditLog(server.AssociationParams,
                             EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);
                    return;
                }

                foreach (DicomAttribute attrib in message.DataSet)
                {
                    if (attrib.Tag.TagValue.Equals(DicomTags.SpecificCharacterSet)
                        || attrib.Tag.TagValue.Equals(DicomTags.QueryRetrieveLevel))
                        continue;

                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                        matchingTagList.Add(attrib.Tag.TagValue);
                }

                int resultCount = 0;

                foreach (InstanceXml theInstanceStream in seriesXml)
                {
                    if (CompareInstanceMatch(message, matchingTagList, theInstanceStream))
                    {
                        if (CancelReceived)
                        {
                            var failureResponse = new DicomMessage();
                            failureResponse.DataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                            server.SendCFindResponse(presentationId, message.MessageId, failureResponse,
                                                     DicomStatuses.Cancel);

                            AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success,
                                     message);
                            return;
                        }
                        resultCount++;
                        if (DicomSettings.Default.MaxQueryResponses != -1
                            && DicomSettings.Default.MaxQueryResponses < resultCount)
                        {
                            SendBufferedResponses(server, presentationId, message);
                            Platform.Log(LogLevel.Warn, "Maximum Configured Query Responses Exceeded: " + resultCount);
                            break;
                        }

                        var response = new DicomMessage();
                        PopulateInstance(message, response, tagList, theInstanceStream);
                        _responseQueue.Enqueue(response);

                        if (_responseQueue.Count >= DicomSettings.Default.BufferedQueryResponses)
                            SendBufferedResponses(server, presentationId, message);
                    }
                }

                SendBufferedResponses(server, presentationId, message);

                var finalResponse = new DicomMessage();
                server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);

                AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e, "Unexepected exception processing IMAGE level query for study {0}: {1}", studyInstanceUid, e.Message);
                var failureResponse = new DicomMessage();
                failureResponse.DataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");
                failureResponse.DataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                failureResponse.DataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
                failureResponse.DataSet[DicomTags.StudyInstanceUid].SetStringValue(studyInstanceUid);
                failureResponse.DataSet[DicomTags.SeriesInstanceUid].SetStringValue(seriesInstanceUid);
                server.SendCFindResponse(presentationId, message.MessageId, failureResponse,
                                         DicomStatuses.QueryRetrieveUnableToProcess);

                AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);
            }
            return;
        }
Example #15
0
		/// <summary>
		/// Helper method for logging audit information.
		/// </summary>
		/// <param name="parms"></param>
		/// <param name="outcome"></param>
		/// <param name="msg">The query message to be audited</param>
		private static void AuditLog(AssociationParameters parms, EventIdentificationContentsEventOutcomeIndicator outcome, DicomMessage msg)
		{
		    try
		    {
                var helper = new QueryAuditHelper(ServerPlatform.AuditSource,
                                              outcome, parms, msg.AffectedSopClassUid, msg.DataSet);
                ServerPlatform.LogAuditMessage(helper);
		    }
		    catch (Exception e)
		    {
		        Platform.Log(LogLevel.Warn, "Unexpected exception logging DICOM Query audit message: {0}", e.Message);
		    }
		}
Example #16
0
        public void OnReceiveResponseMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {
            if (message.Status.Status != DicomState.Success)
            {
                Logger.LogError("Failure status received in sending C-STORE: {0}", message.Status.Description);
            }

            bool ok = false;
            while (ok == false)
            {
                _fileListIndex++;
                if (_fileListIndex >= _fileList.Count)
                {
                    Logger.LogInfo("Completed sending C-STORE-RQ messages, releasing association.");
                    client.SendReleaseRequest();
                    return;
                }

                ok = SendCStore(client, association);
            }
        }
Example #17
0
        public void OnReceiveRequestMessage(DicomClient client, ClientAssociationParameters association, byte presentationID, DicomMessage message)
        {
            Logger.LogError("Unexpected OnReceiveRequestMessage callback on client.");

            throw new Exception("The method or operation is not implemented.");
        }
Example #18
0
        /// <summary>
        /// Generic routine to send the next C-STORE-RQ message in the _fileList.
        /// </summary>
        /// <param name="client">DICOM Client class</param>
        /// <param name="association">Association Parameters</param>
        public bool SendCStore(DicomClient client, ClientAssociationParameters association)
        {
            FileToSend fileToSend = _fileList[_fileListIndex];

            DicomFile dicomFile = new DicomFile(fileToSend.filename);

            try
            {
                dicomFile.Load(DicomReadOptions.Default);
            }
            catch (DicomException e)
            {
                Logger.LogErrorException(e, "Unexpected exception when loading DICOM file {0}",fileToSend.filename);

                return false;
            }

            DicomMessage msg = new DicomMessage(dicomFile);

            byte pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.sopClass, dicomFile.TransferSyntax);
			if (pcid == 0)
			{
				if (dicomFile.TransferSyntax.Equals(TransferSyntax.ImplicitVrLittleEndian))
					pcid = association.FindAbstractSyntaxWithTransferSyntax(fileToSend.sopClass, TransferSyntax.ExplicitVrLittleEndian);
				if (pcid == 0)
				{
					Logger.LogError(
						"Unable to find matching negotiated presentation context for sop {0} and syntax {1}",
						dicomFile.SopClass.Name, dicomFile.TransferSyntax.Name);
					return false;
				}
			}
        	client.SendCStoreRequest(pcid, client.NextMessageID(), DicomPriority.Medium, msg);
            return true;
        }
		public bool CompleteStream(DicomServer server, ServerAssociationParameters assoc, byte presentationId, DicomMessage message)
		{

			DicomProcessingResult result;
			try
			{
				if (_fileStream != null)
				{
					_fileStream.Flush(true);
					_fileStream.Close();
					_fileStream.Dispose();
					_fileStream = null;
				}

				var importer = new SopInstanceImporter(_importContext);
				result = importer.ImportFile(message, _sourceFilename);

				if (result.Successful)
				{
					if (!String.IsNullOrEmpty(result.AccessionNumber))
						Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})",
						             result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE, result.AccessionNumber,
						             result.StudyInstanceUid);
					else
						Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})",
						             result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE,
						             result.StudyInstanceUid);
				}
			}
			catch (Exception e)
			{
				result = new DicomProcessingResult { DicomStatus = DicomStatuses.ProcessingFailure, ErrorMessage = e.Message };
			}

			if (!result.Successful)
			{
				Platform.Log(LogLevel.Warn, "Failure importing sop: {0}", result.ErrorMessage);
			}

			CleanupDirectory();
			
			server.SendCStoreResponse(presentationId, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
			return true;
		}
Example #20
0
        private void UpdateProgress(WorkItemData workItem)
        {
            try
            {
				SendOperationInfo sendOperationInfo = GetSendOperationInfo(workItem);
                if (sendOperationInfo == null)
                {
                    return;
                }

				sendOperationInfo.WorkItemData = workItem;

                var progress = GetProgressByMessageId(sendOperationInfo.MessageId);

                var msg = new DicomMessage();
                DicomStatus status;

				if (workItem.Status == WorkItemStatusEnum.Failed)
                {
                    sendOperationInfo.Complete = true;
                }
				else if (progress.RemainingSubOperations == 0 && workItem.Status != WorkItemStatusEnum.Pending)
                {
                    sendOperationInfo.Complete = true;
                }

                if (SendOperationsComplete(sendOperationInfo.MessageId))
                {
                    status = DicomStatuses.Success;

                    foreach (SendOperationInfo info in GetSendOperationInfo(sendOperationInfo.MessageId))
                    {
                        foreach (string sopInstanceUid in info.FailedSopInstanceUids)
                            msg.DataSet[DicomTags.FailedSopInstanceUidList].AppendString(sopInstanceUid);
						if (workItem.Status == WorkItemStatusEnum.Canceled)
                            status = DicomStatuses.Cancel;
						else if (workItem.Status == WorkItemStatusEnum.Failed)
                            status = DicomStatuses.QueryRetrieveUnableToProcess;
                        else if (progress.FailureSubOperations > 0 && status == DicomStatuses.Success)
                            status = DicomStatuses.QueryRetrieveSubOpsOneOrMoreFailures;
                    }
                }
                else
                {
                    status = DicomStatuses.Pending;
                    if ((progress.RemainingSubOperations%5) != 0)
                        return;

                    // Only send a RSP every 5 to reduce network load
                }

                if (sendOperationInfo.Server.NetworkActive)
                {
                    sendOperationInfo.Server.SendCMoveResponse(sendOperationInfo.PresentationId,
                                                               sendOperationInfo.MessageId,
                                                               msg, status,
                                                               (ushort) progress.SuccessSubOperations,
                                                               (ushort) progress.RemainingSubOperations,
                                                               (ushort) progress.FailureSubOperations,
                                                               (ushort) progress.WarningSubOperations);
                }

                if (status != DicomStatuses.Pending || !sendOperationInfo.Server.NetworkActive)
                {
                    foreach (SendOperationInfo info in GetSendOperationInfo(sendOperationInfo.MessageId))
                    {
                        RemoveSendOperationInfo(info);
                    }
                }
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e, "Unexpected error processing C-MOVE Responses");
            }
        }
		public bool CompleteStream(Dicom.Network.DicomServer server, ServerAssociationParameters assoc, byte presentationId, DicomMessage message)
		{
			DicomProcessingResult result;
			var importer = new ImportFilesUtility(_importContext);

			if (_rejectFile)
			{
				result = new DicomProcessingResult();
				result.SetError(DicomStatuses.StorageStorageOutOfResources, string.Format("Import failed, disk space usage exceeded"));

				string studyInstanceUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
				WorkItem workItem;
				lock (_importContext.StudyWorkItemsSyncLock)
					_importContext.StudyWorkItems.TryGetValue(studyInstanceUid, out workItem);

				importer.InsertFailedWorkItemUid(workItem, message, result);

				_importContext.FatalError = true;
				importer.AuditFailure(result);

				Platform.Log(LogLevel.Warn, "Failure receiving sop, out of disk space: {0}", message.AffectedSopInstanceUid);
				server.SendCStoreResponse(presentationId, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
				return true;
			}

			try
			{
				if (_fileStream != null)
				{
					_fileStream.Flush(true);
					_fileStream.Close();
					_fileStream.Dispose();
					_fileStream = null;
				}

				// Convert to file to pass in the source filename
				var theFile = new DicomFile(message,_sourceFilename);

				result = importer.Import(theFile, BadFileBehaviourEnum.Delete, FileImportBehaviourEnum.Move);

				if (result.Successful)
				{
					if (!String.IsNullOrEmpty(result.AccessionNumber))
						Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})",
									 result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE, result.AccessionNumber,
									 result.StudyInstanceUid);
					else
						Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})",
									 result.SopInstanceUid, assoc.CallingAE, assoc.CalledAE,
									 result.StudyInstanceUid);
				}
			}
			catch (Exception e)
			{
				result = new DicomProcessingResult { DicomStatus = DicomStatuses.ProcessingFailure, ErrorMessage = e.Message };
			}

			if (!result.Successful)
			{
				Platform.Log(LogLevel.Warn, "Failure importing sop: {0}", result.ErrorMessage);
			}

			CleanupFile();

			server.SendCStoreResponse(presentationId, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
			return true;
		}
Example #22
0
        private void OnReceiveMoveSeriesRequest(ClearCanvas.Dicom.Network.DicomServer server, byte presentationID, DicomMessage message, IDicomServiceNode remoteAEInfo)
		{
			string studyInstanceUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, "");
			var seriesUids = (string[])message.DataSet[DicomTags.SeriesInstanceUid].Values;

            lock (_syncLock)
            {

                int subOperations = 0;
                using (var context = new DataAccessContext())
                {
                    var results = context.GetStudyStoreQuery().SeriesQuery(new SeriesIdentifier
                                                                               {
                                                                                   StudyInstanceUid =
                                                                                       studyInstanceUid,
                                                                               });
                    foreach (SeriesIdentifier series in results)
                    {
                        foreach (string seriesUid in seriesUids)
                            if (series.SeriesInstanceUid.Equals(seriesUid) &&
                                series.NumberOfSeriesRelatedInstances.HasValue)
                            {
                                subOperations += series.NumberOfSeriesRelatedInstances.Value;
                                break;
                            }
                    }

                    var s =
                        context.GetStudyStoreQuery().StudyQuery(new StudyRootStudyIdentifier
                                                                    {StudyInstanceUid = studyInstanceUid});
                    var identifier = CollectionUtils.FirstElement(s);
                    var client = new DicomSendBridge();

                    client.SendSeries(remoteAEInfo, identifier, seriesUids, WorkItemPriorityEnum.High);
                    _sendOperations.Add(new SendOperationInfo(client.WorkItem, message.MessageId, presentationID,
                                                              server)
                                            {
                                                SubOperations = subOperations
                                            });
                }
            }
		}
Example #23
0
        /// <summary>
        /// Extension method called when a new DICOM Request message has been called that the 
        /// extension will process.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="association"></param>
        /// <param name="presentationId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public override bool OnReceiveRequest(DicomServer server, ServerAssociationParameters association,
                                              byte presentationId, DicomMessage message)
        {
            String level = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, string.Empty);

			if (message.CommandField == DicomCommandField.CCancelRequest)
			{
				Platform.Log(LogLevel.Info,"Received C-FIND-CANCEL-RQ message.");
				CancelReceived = true;
				return true;
			}

			CancelReceived = false;

            if (message.AffectedSopClassUid.Equals(SopClass.StudyRootQueryRetrieveInformationModelFindUid))
            {
                if (level.Equals("STUDY"))
                {
					// We use the ThreadPool to process the thread requests. This is so that we return back
					// to the main message loop, and continue to look for cancel request messages coming
					// in.  There's a small chance this may cause delays in responding to query requests if
					// the .NET Thread pool fills up.
                	ThreadPool.QueueUserWorkItem(delegate
													{
													    try
													    {
                                                            OnReceiveStudyLevelQuery(server, presentationId, message);
													    }
													    catch (Exception x)
													    {
                                                            Platform.Log(LogLevel.Error, x, "Unexpected exception in OnReceiveStudyLevelQuery.");
													    }
													});
                	return true;
                }
            	if (level.Equals("SERIES"))
            	{
            		ThreadPool.QueueUserWorkItem(delegate
            		                             	{
                                                        try
                                                        {
                                                            OnReceiveSeriesLevelQuery(server, presentationId, message);
                                                        }
                                                        catch (Exception x)
                                                        {
                                                            Platform.Log(LogLevel.Error, x,
                                                                         "Unexpected exception in OnReceiveSeriesLevelQuery.");
                                                        }
            		                             	});
            		return true;
            	}
            	if (level.Equals("IMAGE"))
            	{
            	    ThreadPool.QueueUserWorkItem(delegate
            	                                     {
            	                                         try
            	                                         {
            	                                             OnReceiveImageLevelQuery(server, presentationId, message);
            	                                         }
            	                                         catch (Exception x)
            	                                         {
            	                                             Platform.Log(LogLevel.Error, x,
            	                                                          "Unexpected exception in OnReceiveImageLevelQuery.");
            	                                         }
            	                                     });
            		return true;
            	}
            	Platform.Log(LogLevel.Error, "Unexpected Study Root Query/Retrieve level: {0}", level);

            	server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
            	                         DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
            	return true;
            }
        	if (message.AffectedSopClassUid.Equals(SopClass.PatientRootQueryRetrieveInformationModelFindUid))
        	{
        		if (level.Equals("PATIENT"))
        		{
        		    ThreadPool.QueueUserWorkItem(delegate
        		                                     {
        		                                         try
        		                                         {
        		                                             OnReceivePatientQuery(server, presentationId, message);
        		                                         }
        		                                         catch (Exception x)
        		                                         {
        		                                             Platform.Log(LogLevel.Error, x,
        		                                                          "Unexpected exception in OnReceivePatientQuery.");
        		                                         }
        		                                     });

        			return true;
        		}
        		if (level.Equals("STUDY"))
        		{
        		    ThreadPool.QueueUserWorkItem(delegate
        		                                     {
        		                                         try
        		                                         {
        		                                             OnReceiveStudyLevelQuery(server, presentationId, message);
        		                                         }
        		                                         catch (Exception x)
        		                                         {
        		                                             Platform.Log(LogLevel.Error, x,
        		                                                          "Unexpected exception in OnReceiveStudyLevelQuery.");
        		                                         }
        		                                     });
        			return true;
        		}
        		if (level.Equals("SERIES"))
        		{
        		    ThreadPool.QueueUserWorkItem(delegate
        		                                     {
        		                                         try
        		                                         {
        		                                             OnReceiveSeriesLevelQuery(server, presentationId, message);
        		                                         }
        		                                         catch (Exception x)
        		                                         {
        		                                             Platform.Log(LogLevel.Error, x,
        		                                                          "Unexpected exception in OnReceiveSeriesLevelQuery.");
        		                                         }
        		                                     });
        			return true;
        		}
        		if (level.Equals("IMAGE"))
        		{
        		    ThreadPool.QueueUserWorkItem(delegate
        		                                     {
        		                                         try
        		                                         {
        		                                             OnReceiveImageLevelQuery(server, presentationId, message);
        		                                         }
        		                                         catch (Exception x)
        		                                         {
        		                                             Platform.Log(LogLevel.Error, x,
        		                                                          "Unexpected exception in OnReceiveImageLevelQuery.");
        		                                         }
        		                                     });
        			return true;
        		}
        		Platform.Log(LogLevel.Error, "Unexpected Patient Root Query/Retrieve level: {0}", level);

        		server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
        		                         DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
        		return true;
        	}

        	// Not supported message type, send a failure status.
            server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(),
                                     DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
            return true;
        }
Example #24
0
 public void OnReceiveResponseMessage(DicomServer server, ServerAssociationParameters association, byte presentationID, ClearCanvas.Dicom.DicomMessage message)
 {
     server.SendAssociateAbort(DicomAbortSource.ServiceUser, DicomAbortReason.UnexpectedPDU);
 }
Example #25
0
        /// <summary>
        /// Creates a new DicomFile instance from an existing <see cref="DicomMessage"/> instance.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This routine assigns the existing <see cref="DicomMessage.DataSet"/> into the new 
        /// DicomFile instance.
        /// </para>
        /// <para>
        /// A new <see cref="DicomAttributeCollection"/> is created for the MetaInfo.  The 
        /// Media Storage SOP Instance UID, Media Storage SOP Class UID, Implementation Version Name,
        /// and Implementation Class UID tags are automatically set in the meta information.
        /// </para>
        /// </remarks>
        /// <param name="msg"></param>
        /// <param name="filename"></param>
        public DicomFile(DicomMessage msg, String filename)
        {
            MetaInfo = new DicomAttributeCollection(0x00020000, 0x0002FFFF);
            DataSet = msg.DataSet;

            MediaStorageSopInstanceUid = msg.AffectedSopInstanceUid;
            MediaStorageSopClassUid = msg.AffectedSopClassUid;
            ImplementationVersionName = DicomImplementation.Version;
            ImplementationClassUid = DicomImplementation.ClassUID.UID;
            if (msg.TransferSyntax.Encapsulated)
                MetaInfo[DicomTags.TransferSyntaxUid].SetStringValue(msg.TransferSyntax.UidString);
            else
                MetaInfo[DicomTags.TransferSyntaxUid].SetStringValue(TransferSyntax.ExplicitVrLittleEndian.UidString);
            MetaInfo[DicomTags.FileMetaInformationVersion].Values = new byte[] { 0x00, 0x01 };
            
            _filename = filename;
        }
Example #26
0
		private void SendBufferedResponses(DicomServer server, byte presentationId, DicomMessage requestMessage)
		{
			while (_responseQueue.Count > 0)
			{
				DicomMessage response = _responseQueue.Dequeue();
				server.SendCFindResponse(presentationId, requestMessage.MessageId, response,
						 DicomStatuses.Pending);

				if (CancelReceived)
					throw new DicomException("DICOM C-Cancel Received");

				if (!server.NetworkActive)
					throw new DicomException("Association is no longer valid.");
			}
		}
Example #27
0
	    private void OnReceiveMoveStudiesRequest(ClearCanvas.Dicom.Network.DicomServer server, byte presentationID, DicomMessage message, IDicomServiceNode remoteAEInfo)
		{
			IEnumerable<string> studyUids = (string[])message.DataSet[DicomTags.StudyInstanceUid].Values;

            foreach (string studyUid in studyUids)
            {
                lock (_syncLock)
                {
                    int subOperations = 0;
                    using (var context = new DataAccessContext())
                    {
                        var s =
                            context.GetStudyStoreQuery().StudyQuery(new StudyRootStudyIdentifier
                                                                        {StudyInstanceUid = studyUid});
                        var identifier = CollectionUtils.FirstElement(s);
                        if (identifier.NumberOfStudyRelatedInstances.HasValue)
                            subOperations = identifier.NumberOfStudyRelatedInstances.Value;

                        var client = new DicomSendBridge();
                        client.SendStudy(remoteAEInfo, identifier, WorkItemPriorityEnum.High);
                        _sendOperations.Add(new SendOperationInfo(client.WorkItem, message.MessageId,
                                                                  presentationID,
                                                                  server)
                                                {
                                                    SubOperations = subOperations
                                                });
                    }
                }
            }
		}
Example #28
0
        /// <summary>
        /// Method for processing Patient level queries.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="presentationId"></param>
        /// <param name="message">The Patient level query message.</param>
        /// <returns></returns>
        private void OnReceivePatientQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (IReadContext read = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
            {
                var find = read.GetBroker<IPatientEntityBroker>();

                var criteria = new PatientSelectCriteria();
                criteria.ServerPartitionKey.EqualTo(Partition.GetKey());

                DicomAttributeCollection data = message.DataSet;
            	var studySelect = new StudySelectCriteria();
            	bool studySubSelect = false;
                foreach (DicomAttribute attrib in message.DataSet)
                {
                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                        switch (attrib.Tag.TagValue)
                        {
                            case DicomTags.PatientsName:
								QueryHelper.SetStringCondition(criteria.PatientsName, data[DicomTags.PatientsName].GetString(0, string.Empty));
                                break;
                            case DicomTags.PatientId:
								QueryHelper.SetStringCondition(criteria.PatientId, data[DicomTags.PatientId].GetString(0, string.Empty));
                                break;
                            case DicomTags.IssuerOfPatientId:
                                QueryHelper.SetStringCondition(criteria.IssuerOfPatientId,
												   data[DicomTags.IssuerOfPatientId].GetString(0, string.Empty));
                                break;
							case DicomTags.PatientsSex:
								// Specify a subselect on Patients Sex in Study
								QueryHelper.SetStringArrayCondition(studySelect.PatientsSex,
														(string[])data[DicomTags.PatientsSex].Values);
								if (!studySubSelect)
								{
									criteria.StudyRelatedEntityCondition.Exists(studySelect);
									studySubSelect = true;
								}
                        		break;

							case DicomTags.PatientsBirthDate:
								// Specify a subselect on Patients Birth Date in Study
								QueryHelper.SetStringArrayCondition(studySelect.PatientsBirthDate,
														(string[])data[DicomTags.PatientsBirthDate].Values);
								if (!studySubSelect)
								{
									criteria.StudyRelatedEntityCondition.Exists(studySelect);
									studySubSelect = true;
								}
								break;
                            default:
                                foreach (var q in _queryExtensions)
                                {
                                    bool extensionSubSelect;
                                    q.OnReceivePatientLevelQuery(message, attrib.Tag, criteria, studySelect, out extensionSubSelect);
                                    if (extensionSubSelect && !studySubSelect)
                                    {
                                        criteria.StudyRelatedEntityCondition.Exists(studySelect);
                                        studySubSelect = true;
                                    }
                                }
                                break;
                        }
                }

				int resultCount = 0;
                try
                {
                    find.Find(criteria, delegate(Patient row)
                                            {
												if (CancelReceived)
													throw new DicomException("DICOM C-Cancel Received");

                                            	resultCount++;
												if (DicomSettings.Default.MaxQueryResponses != -1
													&& DicomSettings.Default.MaxQueryResponses < resultCount)
												{
													SendBufferedResponses(server, presentationId, message);
													throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
												}

                                            	var response = new DicomMessage();
												PopulatePatient(response, tagList, row);
                                            	_responseQueue.Enqueue(response);

												if (_responseQueue.Count >= DicomSettings.Default.BufferedQueryResponses)
													SendBufferedResponses(server, presentationId, message);
                                            });

                	SendBufferedResponses(server, presentationId, message);

                }
                catch (Exception e)
                {
					if (CancelReceived)
					{
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Cancel);
					}
					else if (DicomSettings.Default.MaxQueryResponses != -1 
						  && DicomSettings.Default.MaxQueryResponses < resultCount)
					{
						Platform.Log(LogLevel.Warn, "Maximum Configured Query Responses Exceeded: {0} on query from {1}", resultCount, server.AssociationParams.CallingAE);
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Success);
						AuditLog(server.AssociationParams,
								 EventIdentificationContentsEventOutcomeIndicator.Success, message);
					}
					else
					{
						Platform.Log(LogLevel.Error, e, "Unexpected exception when processing FIND request.");
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
						                         DicomStatuses.QueryRetrieveUnableToProcess);
						AuditLog(server.AssociationParams,
								 EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);
					}
                	return;
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);
			AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        	return;
        }
Example #29
0
        private void OnReceiveMoveImageRequest(ClearCanvas.Dicom.Network.DicomServer server, byte presentationID, DicomMessage message, IDicomServiceNode remoteAEInfo)
		{
			string studyInstanceUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
			string seriesInstanceUid = message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
			var sopInstanceUids = (string[])message.DataSet[DicomTags.SopInstanceUid].Values;

            lock (_syncLock)
            {

                using (var context = new DataAccessContext())
                {
                    var s = context.GetStudyStoreQuery().StudyQuery(new StudyRootStudyIdentifier
                                                                    {StudyInstanceUid = studyInstanceUid});
                    var identifier = CollectionUtils.FirstElement(s);

                    var client = new DicomSendBridge();
                    client.SendSops(remoteAEInfo, identifier, seriesInstanceUid, sopInstanceUids, WorkItemPriorityEnum.High);
                    _sendOperations.Add(new SendOperationInfo(client.WorkItem, message.MessageId, presentationID, server)
                                            {
                                                SubOperations = sopInstanceUids.Length
                                            });
                }
            }
		}
Example #30
0
        /// <summary>
        /// Method for processing Study level queries.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="presentationId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private void OnReceiveStudyLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            var tagList = new List<DicomTag>();

            using (IReadContext read = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
            {
                var find = read.GetBroker<IStudyEntityBroker>();

                var criteria = new StudySelectCriteria();
                criteria.ServerPartitionKey.EqualTo(Partition.GetKey());

                DicomAttributeCollection data = message.DataSet;
                foreach (DicomAttribute attrib in message.DataSet)
                {
                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                        switch (attrib.Tag.TagValue)
                        {
                            case DicomTags.StudyInstanceUid:
                                QueryHelper.SetStringArrayCondition(criteria.StudyInstanceUid,
                                                        (string[]) data[DicomTags.StudyInstanceUid].Values);
                                break;
                            case DicomTags.PatientsName:
								QueryHelper.SetStringCondition(criteria.PatientsName, data[DicomTags.PatientsName].GetString(0, string.Empty));
                                break;
                            case DicomTags.PatientId:
								QueryHelper.SetStringCondition(criteria.PatientId, data[DicomTags.PatientId].GetString(0, string.Empty));
                                break;
                            case DicomTags.PatientsBirthDate:
                                QueryHelper.SetRangeCondition(criteria.PatientsBirthDate,
												  data[DicomTags.PatientsBirthDate].GetString(0, string.Empty));
                                break;
                            case DicomTags.PatientsSex:
								QueryHelper.SetStringCondition(criteria.PatientsSex, data[DicomTags.PatientsSex].GetString(0, string.Empty));
                                break;
                            case DicomTags.StudyDate:
								QueryHelper.SetRangeCondition(criteria.StudyDate, data[DicomTags.StudyDate].GetString(0, string.Empty));
                                break;
                            case DicomTags.StudyTime:
								QueryHelper.SetRangeCondition(criteria.StudyTime, data[DicomTags.StudyTime].GetString(0, string.Empty));
                                break;
                            case DicomTags.AccessionNumber:
                                QueryHelper.SetStringCondition(criteria.AccessionNumber,
												   data[DicomTags.AccessionNumber].GetString(0, string.Empty));
                                break;
                            case DicomTags.StudyId:
								QueryHelper.SetStringCondition(criteria.StudyId, data[DicomTags.StudyId].GetString(0, string.Empty));
                                break;
                            case DicomTags.StudyDescription:
                                QueryHelper.SetStringCondition(criteria.StudyDescription,
												   data[DicomTags.StudyDescription].GetString(0, string.Empty));
                                break;
                            case DicomTags.ReferringPhysiciansName:
                                QueryHelper.SetStringCondition(criteria.ReferringPhysiciansName,
												   data[DicomTags.ReferringPhysiciansName].GetString(0, string.Empty));
                                break;
                            case DicomTags.ModalitiesInStudy:
                                // Specify a subselect on Modality in series
                                var seriesSelect = new SeriesSelectCriteria();
                                QueryHelper.SetStringArrayCondition(seriesSelect.Modality,
                                                        (string[]) data[DicomTags.ModalitiesInStudy].Values);
                                criteria.SeriesRelatedEntityCondition.Exists(seriesSelect);
                                break;
                            default:
                                foreach (var q in _queryExtensions)
                                    q.OnReceiveStudyLevelQuery(message, attrib.Tag, criteria);
                                break;
                        }
                }

				int resultCount = 0;
				try
                {
                    // Open another read context, in case additional queries are required.
					using (IReadContext subRead = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
                    {
						// First find the Online studies
                    	var storageCriteria = new StudyStorageSelectCriteria();
                    	storageCriteria.StudyStatusEnum.NotEqualTo(StudyStatusEnum.Nearline);
						storageCriteria.QueueStudyStateEnum.NotIn(new[] {QueueStudyStateEnum.DeleteScheduled, QueueStudyStateEnum.WebDeleteScheduled, QueueStudyStateEnum.EditScheduled});
                    	criteria.StudyStorageRelatedEntityCondition.Exists(storageCriteria);

                        find.Find(criteria, delegate(Study row)
                                                {
													if (CancelReceived)
														throw new DicomException("DICOM C-Cancel Received");

													resultCount++;
													if (DicomSettings.Default.MaxQueryResponses != -1
														&& DicomSettings.Default.MaxQueryResponses < resultCount)
													{
														SendBufferedResponses(server, presentationId, message);
														throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
													}

                                                    var response = new DicomMessage();
                                                    PopulateStudy(subRead, response, tagList, row, "ONLINE");
													_responseQueue.Enqueue(response);

													if (_responseQueue.Count >= DicomSettings.Default.BufferedQueryResponses)
														SendBufferedResponses(server, presentationId, message);
											
                                                });

						// Now find the Nearline studies
						storageCriteria = new StudyStorageSelectCriteria();
						storageCriteria.StudyStatusEnum.EqualTo(StudyStatusEnum.Nearline);
						storageCriteria.QueueStudyStateEnum.NotIn(new[] { QueueStudyStateEnum.DeleteScheduled, QueueStudyStateEnum.WebDeleteScheduled, QueueStudyStateEnum.EditScheduled });
						criteria.StudyStorageRelatedEntityCondition.Exists(storageCriteria);

						find.Find(criteria, delegate(Study row)
												{
													if (CancelReceived)
														throw new DicomException("DICOM C-Cancel Received");

													resultCount++;
													if (DicomSettings.Default.MaxQueryResponses != -1
														&& DicomSettings.Default.MaxQueryResponses < resultCount)
													{
														SendBufferedResponses(server, presentationId, message);
														throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
													}

													var response = new DicomMessage();
													PopulateStudy(subRead, response, tagList, row, "NEARLINE");
													_responseQueue.Enqueue(response);

													if (_responseQueue.Count >= DicomSettings.Default.BufferedQueryResponses)
														SendBufferedResponses(server, presentationId, message);

												});

						SendBufferedResponses(server, presentationId, message);
					}
                }
                catch (Exception e)
                {
					if (CancelReceived)
					{
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Cancel);
						AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
					}
					else if (DicomSettings.Default.MaxQueryResponses != -1
						  && DicomSettings.Default.MaxQueryResponses < resultCount)
					{
						Platform.Log(LogLevel.Warn, "Maximum Configured Query Responses Exceeded: {0} on query from {1}", resultCount, server.AssociationParams.CallingAE);
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Success);
						AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
					}
					else
					{
						Platform.Log(LogLevel.Error, e, "Unexpected exception when processing FIND request.");
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
						                         DicomStatuses.ProcessingFailure);
						AuditLog(server.AssociationParams,
								 EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);

					}
                	return;
                }
            }

            var finalResponse = new DicomMessage();
            server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);

			AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
        	return;
        }
Example #31
0
		public override bool OnReceiveRequest(ClearCanvas.Dicom.Network.DicomServer server, ServerAssociationParameters association, byte presentationID, DicomMessage message)
		{
			//// Check for a Cancel message, and cancel the SCU.
			if (message.CommandField == DicomCommandField.CCancelRequest)
			{
				OnReceiveCancelRequest(message);
				return true;
			}

		    // TODO (CR Jun 2012): Log when there's more than 1.

		    var remoteAE = ServerDirectory.GetRemoteServersByAETitle(message.MoveDestination).FirstOrDefault();
            if (remoteAE == null)
			{
				server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
					DicomStatuses.QueryRetrieveMoveDestinationUnknown);
				return true;
			}

			String level = message.DataSet[DicomTags.QueryRetrieveLevel].GetString(0, string.Empty);

			try
			{
				if (level.Equals("STUDY"))
				{
                    OnReceiveMoveStudiesRequest(server, presentationID, message, remoteAE);
				}
				else if (level.Equals("SERIES"))
				{
                    OnReceiveMoveSeriesRequest(server, presentationID, message, remoteAE);
				}
				else if (level.Equals("IMAGE"))
				{
                    OnReceiveMoveImageRequest(server, presentationID, message, remoteAE);
				}
				else
				{
					Platform.Log(LogLevel.Error, "Unexpected Study Root Move Query/Retrieve level: {0}", level);

					server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
					                         DicomStatuses.QueryRetrieveIdentifierDoesNotMatchSOPClass);
					return true;
				}
			}
			catch(Exception e)
			{
				Platform.Log(LogLevel.Error, e, "Unexpected exception when processing C-MOVE-RQ");
				try
				{
					server.SendCMoveResponse(presentationID, message.MessageId, new DicomMessage(),
											 DicomStatuses.QueryRetrieveUnableToProcess, e.Message);
				}
				catch (Exception ex)
				{
					Platform.Log(LogLevel.Error, ex,
								 "Unable to send final C-MOVE-RSP message on association from {0} to {1}",
								 association.CallingAE, association.CalledAE);
				}
			}

			return true;
		}
Example #32
0
        /// <summary>
        /// Method for processing Series level queries.
        /// </summary>
        /// <param name="server"></param>
        /// <param name="presentationId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private void OnReceiveSeriesLevelQuery(DicomServer server, byte presentationId, DicomMessage message)
        {
            //Read context for the query.
            using (IReadContext read = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
            {
                var tagList = new List<DicomTag>();

                var selectSeries = read.GetBroker<ISeriesEntityBroker>();

                var criteria = new SeriesSelectCriteria();
                criteria.ServerPartitionKey.EqualTo(Partition.GetKey());

                DicomAttributeCollection data = message.DataSet;
                foreach (DicomAttribute attrib in message.DataSet)
                {
                    tagList.Add(attrib.Tag);
                    if (!attrib.IsNull)
                        switch (attrib.Tag.TagValue)
                        {
                            case DicomTags.StudyInstanceUid:
                                List<ServerEntityKey> list =
                                    LoadStudyKey(read, (string[]) data[DicomTags.StudyInstanceUid].Values);
                                if (list.Count == 0)
                                {
                                    server.SendCFindResponse(presentationId, message.MessageId, new DicomMessage(), 
                                                             DicomStatuses.Success);
                                    AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
                                    return;
                                }
                                QueryHelper.SetKeyCondition(criteria.StudyKey, list.ToArray());
                                break;
                            case DicomTags.SeriesInstanceUid:
                                QueryHelper.SetStringArrayCondition(criteria.SeriesInstanceUid,
                                                        (string[]) data[DicomTags.SeriesInstanceUid].Values);
                                break;
                            case DicomTags.Modality:
                                QueryHelper.SetStringCondition(criteria.Modality, data[DicomTags.Modality].GetString(0, string.Empty));
                                break;
                            case DicomTags.SeriesNumber:
								QueryHelper.SetStringCondition(criteria.SeriesNumber, data[DicomTags.SeriesNumber].GetString(0, string.Empty));
                                break;
                            case DicomTags.SeriesDescription:
                                QueryHelper.SetStringCondition(criteria.SeriesDescription,
												   data[DicomTags.SeriesDescription].GetString(0, string.Empty));
                                break;
                            case DicomTags.PerformedProcedureStepStartDate:
                                QueryHelper.SetRangeCondition(criteria.PerformedProcedureStepStartDate,
												  data[DicomTags.PerformedProcedureStepStartDate].GetString(0, string.Empty));
                                break;
                            case DicomTags.PerformedProcedureStepStartTime:
                                QueryHelper.SetRangeCondition(criteria.PerformedProcedureStepStartTime,
												  data[DicomTags.PerformedProcedureStepStartTime].GetString(0, string.Empty));
                                break;
                            case DicomTags.RequestAttributesSequence: // todo
                                break;
                            default:
                                foreach (var q in _queryExtensions)
                                    q.OnReceiveSeriesLevelQuery(message, attrib.Tag, criteria);
                                break;
                        }
                }

				int resultCount = 0;
				try
                {
                    // Open a second read context, in case other queries are required.
					using (IReadContext subRead = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
                    {
                        selectSeries.Find(criteria, delegate(Series row)
                                                        {
															if (CancelReceived)
																throw new DicomException("DICOM C-Cancel Received");

															resultCount++;
															if (DicomSettings.Default.MaxQueryResponses != -1
																&& DicomSettings.Default.MaxQueryResponses < resultCount)
															{
																SendBufferedResponses(server, presentationId, message);
																throw new DicomException("Maximum Configured Query Responses Exceeded: " + resultCount);
															}

                                                        	var response = new DicomMessage();
                                                            PopulateSeries(subRead, message, response, tagList, row);
															_responseQueue.Enqueue(response);

															if (_responseQueue.Count >= DicomSettings.Default.BufferedQueryResponses)
																SendBufferedResponses(server, presentationId, message);
														});
						SendBufferedResponses(server, presentationId, message);
					}
                }
                catch (Exception e)
                {
					if (CancelReceived)
					{
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Cancel);
						AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
					}
					else if (DicomSettings.Default.MaxQueryResponses != -1
						  && DicomSettings.Default.MaxQueryResponses < resultCount)
					{
						Platform.Log(LogLevel.Warn, "Maximum Configured Query Responses Exceeded: {0} on query from {1}",resultCount,server.AssociationParams.CallingAE);

						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
												 DicomStatuses.Success);
						AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
					}
					else
					{
						Platform.Log(LogLevel.Error, e, "Unexpected exception when processing FIND request.");
						var errorResponse = new DicomMessage();
						server.SendCFindResponse(presentationId, message.MessageId, errorResponse,
						                         DicomStatuses.ProcessingFailure);
						AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.SeriousFailureActionTerminated, message);
        
					}
                	return;
                }

                var finalResponse = new DicomMessage();
                server.SendCFindResponse(presentationId, message.MessageId, finalResponse, DicomStatuses.Success);

				AuditLog(server.AssociationParams, EventIdentificationContentsEventOutcomeIndicator.Success, message);
        
            	return;
            }
        }