Class DICOM.BP.MoveProcess Extends EnsLib.DICOM.Process { /// This parameter names the operation used to provide storage Parameter SETTINGS = "OperationDuplexName"; /// This keeps track of the OriginatingMessageID Property OriginatingMessageID As %Integer; /// This is the incoming document from the business Sservice Property DocumentFromService As EnsLib.DICOM.Document; /// This keeps track of the current state of the process Property CurrentState As %String [ InitialExpression = "OperationNotConnected" ]; /// This is the name of the operation providing storage Property OperationDuplexName; /// Messages received here are instances of EnsLib.DICOM.Document sent to this /// process by the service or operation config items. In this demo, the process is ever /// in one of two states, the Operation is connected or not. Method OnMessage(pSourceConfigName As %String, pInput As %Library.Persistent) As %Status { #dim tSC As %Status = $$$OK #dim tMsgType As %String #dim tFindRequest As EnsLib.DICOM.Document #; Do not process any other incoming messages rather than DICOM documents if $IsObject(pInput),'pInput.%IsA("EnsLib.DICOM.Document") Quit $$$OK do { #; If its a document sent from the service If pSourceConfigName'=..OperationDuplexName { #; If the operation has not been connected yet If ..CurrentState="OperationNotConnected" { #; We are in the process of establishing the connection to the operation, #; Keep hold of the incoming document set ..DocumentFromService=pInput set tSC=..EstablishAssociation(..OperationDuplexName) } elseif ..CurrentState="OperationConnected" { #; We can forward the document to the operation do ..DocumentFromService.SetValueAt(..%SessionId,"CommandSet.MessageID") set tSC=..SendRequestAsync(..OperationDuplexName,..DocumentFromService,0) } } elseif pSourceConfigName=..OperationDuplexName { #; We have received a document from the operation Set tMsgType=pInput.GetValueAt("CommandSet.CommandField",,.tSC) If $$$ISERR(tSC) Quit #; Should only EVER get a C-MOVE-RSP $$$ASSERT(tMsgType="C-MOVE-RSP") #; If Status = 0 we are done if pInput.GetValueAt("CommandSet.Status",,.tSC)=0 { set tSC=..ReleaseAssociation(..OperationDuplexName) /// TODO: AFT! quit /* #; C-MOVE completed, process stored files set tDocReceivedMsg = ##class(epat.Msg.DocReceivedReq).%New() set tDocReceivedMsg.MessageId = ..%SessionId do tDocReceivedMsg.%Save() do ..SendRequestAsync("DocReceivedProcess",tDocReceivedMsg) quit */ } } } while (0) Quit tSC } /// This method is called by the framework on successful establishment of an association Method OnAssociationEstablished(pSourceConfigName As %String, pInput As EnsLib.DICOM.Notify.Established) As %Status { #dim tSC As %Status = $$$OK If pSourceConfigName=..OperationDuplexName { #; The association with the operation has been completed, operation is now connected Set ..CurrentState="OperationConnected" Set tSC=..OnMessage(..ServiceDuplexName,"") } else { #; Need to establish an associaton with the operation (we will be called back here at #; OnAssociationEstablished() Set tSC=..EstablishAssociation(..OperationDuplexName) } Quit tSC } Method OnAssociationReleased(pSourceConfigName As %String, pInput As EnsLib.DICOM.Notify.Released) As %Status { #dim tSC As %Status = $$$OK #; The association between this process and the operation has been released, so we are now #; not connected to the operation Set ..CurrentState="OperationNotConnected" Quit tSC } /// This callback is called by the framework when an Association is rejected Method OnAssociationRejected(pSourceConfigName As %String, pInput As EnsLib.DICOM.Notify.Rejected) As %Status [ Final ] { Quit $$$ERROR($$$EnsDICOMPeerRejectedAssociation) } /// This callback is called by the framework when an association encounters an error Method OnAssociationErrored(pSourceConfigName As %String, pInput As EnsLib.DICOM.Notify.Errored) As %Status [ Final ] { Quit pInput.Status } /// This callback is called by the framework when an association is aborted Method OnAssociationAborted(pSourceConfigName As %String, pInput As EnsLib.DICOM.Notify.Aborted) As %Status [ Final ] { Quit $$$ERROR($$$EnsDICOMPeerRequestedAbort) } /// This method is called when any error occurs. Returning the same error will cause the BusinessProcess to set its /// status to error and close down Method OnError(request As %Library.Persistent, ByRef response As %Library.Persistent, callrequest As %Library.Persistent, pErrorStatus As %Status, pCompletionKey As %String) As %Status { #; If we are in conversation with the operation, we neet to tell the operation to ABORT its association If ..CurrentState="OperationConnected" { #; Form an abort message Set tCommandAbort=##class(EnsLib.DICOM.Command.Abort).%New($$$ABORTSOURCESERVICEUSER,$$$ABORTREASONNOTSPECIFIED) #; Send it to the operation Do ..AbortAssociation(..OperationDuplexName,tCommandAbort) } Quit pErrorStatus } Storage Default { "MoveProcess" OriginatingMessageID DocumentFromService CurrentState OperationDuplexName MoveProcessDefaultData %Storage.Persistent } }