/// <summary>reads an incoming Giop reply message from the Message input stream msgInput</summary> /// <remarks>Precondition: sourceStream contains a Giop reply Msg</remarks> /// <returns>the .NET reply Msg created from the Giop Reply</returns> internal IMessage ParseIncomingReplyMessage(CdrMessageInputStream msgInput, IMethodCallMessage requestMessage, GiopClientConnectionDesc conDesc) { Debug.WriteLine("receive reply message at client side"); CdrInputStream msgBody = msgInput.GetMessageContentReadingStream(); GiopClientRequest request = new GiopClientRequest(requestMessage, conDesc, m_interceptionOptions); if (request.IsAsyncRequest) { try { // with respec to interception, this is a new request -> call again send_request interception before reply request.PrepareSecondAscyncInterception(); request.InterceptSendRequest(); } catch (Exception ex) { request.Reply = new ReturnMessage(ex, requestMessage); Exception newException = request.InterceptReceiveException(ex); if (newException == ex) { throw; } else { throw newException; // exeption has been changed by interception point } } } // deserialize message body IMessage result = m_ser.DeserialiseReply(msgBody, msgInput.Header.Version, request, conDesc); return(result); }
/// <summary>serialises an outgoing .NET request Message on client side</summary> internal void SerialiseOutgoingRequestMessage(IMessage msg, IIorProfile target, GiopClientConnectionDesc conDesc, Stream targetStream, uint requestId) { if (msg is IConstructionCallMessage) { // not supported in CORBA, TBD: replace through do nothing instead of exception throw new NotSupportedException("client activated objects are not supported with this channel"); } else if (msg is IMethodCallMessage) { GiopVersion version = target.Version; // write a CORBA request message into the stream targetStream GiopHeader header = new GiopHeader(version.Major, version.Minor, m_headerFlags, GiopMsgTypes.Request); CdrMessageOutputStream msgOutput = new CdrMessageOutputStream(targetStream, header); // serialize the message, this insert some data into msg, e.g. request-id msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = requestId; // set request-id msg.Properties[SimpleGiopMsg.TARGET_PROFILE_KEY] = target; GiopClientRequest request = new GiopClientRequest((IMethodCallMessage)msg, conDesc, m_interceptionOptions); m_ser.SerialiseRequest(request, msgOutput.GetMessageContentWritingStream(), target, conDesc); msgOutput.CloseStream(); if ((request.IsAsyncRequest) || (request.IsOneWayCall)) { // after successful serialisation, call for oneway and async requests receive other, // see corba 2.6, page 21-12. request.InterceptReceiveOther(); } } else { throw new NotImplementedException("handling for this type of .NET message is not implemented at the moment, type: " + msg.GetType()); } }
/// <summary>reads an incoming Giop reply message from the Message input stream msgInput</summary> /// <remarks>Precondition: sourceStream contains a Giop reply Msg</remarks> /// <returns>the .NET reply Msg created from the Giop Reply</returns> internal IMessage ParseIncomingReplyMessage(CdrMessageInputStream msgInput, IMethodCallMessage requestMessage, GiopClientConnectionDesc conDesc) { Debug.WriteLine("receive reply message at client side"); CdrInputStream msgBody = msgInput.GetMessageContentReadingStream(); GiopClientRequest request = new GiopClientRequest(requestMessage, conDesc, m_interceptionOptions); if (request.IsAsyncRequest) { try { // with respec to interception, this is a new request -> call again send_request interception before reply request.PrepareSecondAscyncInterception(); request.InterceptSendRequest(); } catch (Exception ex) { request.Reply = new ReturnMessage(ex, requestMessage); Exception newException = request.InterceptReceiveException(ex); if (newException == ex) { throw; } else { throw newException; // exeption has been changed by interception point } } } // deserialize message body IMessage result = m_ser.DeserialiseReply(msgBody, msgInput.Header.Version, request, conDesc); return result; }
public void TestWCharSetDefinedClient() { MethodInfo methodToCall = typeof(TestStringInterface).GetMethod("EchoWString"); object[] args = new object[] { "test" }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri Ior target = m_iiopUrlUtil.CreateIorForUrl(uri, ""); IIorProfile targetProfile = target.Profiles[0]; TestMessage msg = new TestMessage(methodToCall, args, uri); msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = (uint)5; // set request-id msg.Properties[SimpleGiopMsg.TARGET_PROFILE_KEY] = targetProfile; // prepare connection context GiopClientConnectionDesc conDesc = new GiopClientConnectionDesc(null, null, new GiopRequestNumberGenerator(), null); GiopMessageBodySerialiser ser = new GiopMessageBodySerialiser( new ArgumentsSerializerFactory(m_serFactory)); GiopClientRequest request = new GiopClientRequest(msg, conDesc, new IInterceptionOption[0]); MemoryStream baseStream = new MemoryStream(); CdrOutputStreamImpl targetStream = new CdrOutputStreamImpl(baseStream, 0, new GiopVersion(1,2)); ser.SerialiseRequest(request, targetStream, targetProfile, conDesc); Assert.AreEqual( new byte[] { 0, 0, 0, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 116, 101, 115, 116, 117, 114, 105, 0, 0, 0, 0, 12, 69, 99, 104, 111, 87, 83, 116, 114, 105, 110, 103, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 12, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 9, 0, 0, 0, 8, 0, 116, 0, 101, 0, 115, 0, 116}, baseStream.ToArray(),"serialised message"); }
public void TestWCharSetNotDefinedClient() { MethodInfo methodToCall = typeof(TestStringInterface).GetMethod("EchoWString"); object[] args = new object[] { "test" }; string uri = "IOR:000000000000000100000000000000010000000000000020000102000000000A6C6F63616C686F73740004D2000000047465737400000000"; Ior target = m_iiopUrlUtil.CreateIorForUrl(uri, ""); IIorProfile targetProfile = target.Profiles[0]; TestMessage msg = new TestMessage(methodToCall, args, uri); msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = (uint)5; // set request-id msg.Properties[SimpleGiopMsg.TARGET_PROFILE_KEY] = targetProfile; // prepare connection context GiopClientConnectionDesc conDesc = new GiopClientConnectionDesc(null, null, new GiopRequestNumberGenerator(), null); GiopMessageBodySerialiser ser = new GiopMessageBodySerialiser( new ArgumentsSerializerFactory(m_serFactory)); GiopClientRequest request = new GiopClientRequest(msg, conDesc, new IInterceptionOption[0]); CdrOutputStreamImpl targetStream = new CdrOutputStreamImpl(new MemoryStream(), 0, new GiopVersion(1,2)); ser.SerialiseRequest(request, targetStream, targetProfile, conDesc); }
/// <summary> /// deserialise the location fwd /// </summary> private LocationForwardMessage DeserialiseLocationFwdReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request) { AlignBodyIfNeeded(cdrStream, version); // read the Location fwd IOR Serializer ser = m_serFactory.Create(request.MethodToCall.DeclaringType, Util.AttributeExtCollection.EmptyCollection); MarshalByRefObject newProxy = ser.Deserialize(cdrStream) as MarshalByRefObject; if (newProxy == null) { throw new OBJECT_NOT_EXIST(2402, CompletionStatus.Completed_No); } return new LocationForwardMessage(newProxy); }
/// <summary>deserialize response with ok-status.</summary> private IMessage DeserialiseNormalReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request) { // body // clarification from CORBA 2.6, chapter 15.4.2: no padding, when no arguments are serialised TryAlignBodyIfNeeded(cdrStream, version); // read alignement, if present // read the parameters object[] outArgs; object retVal = null; ArgumentsSerializer ser = m_argSerFactory.Create(request.MethodToCall.DeclaringType); retVal = ser.DeserializeResponseArgs(request.RequestMethodName, out outArgs, cdrStream); ReturnMessage response = new ReturnMessage(retVal, outArgs, outArgs.Length, null, request.Request); return response; }
internal IMessage DeserialiseReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request, GiopConnectionDesc conDesc) { ServiceContextList cntxColl = null; IMessage response = null; try { if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1, the service context is placed here cntxColl = DeserialiseContext(cdrStream); // deserialize the service contexts } cdrStream.ReadULong(); // skip request id, already handled by transport uint responseStatus = cdrStream.ReadULong(); if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here cntxColl = DeserialiseContext(cdrStream); // deserialize the service contexts } // set codeset for stream SetCodeSet(cdrStream, conDesc); switch (responseStatus) { case 0 : Trace.WriteLine("deserializing normal reply for methodCall: " + request.MethodToCall); response = DeserialiseNormalReply(cdrStream, version, request); UpdateClientRequestWithReplyData(request, response, cntxColl); request.InterceptReceiveReply(); break; case 1 : Exception userEx = DeserialiseUserException(cdrStream, version); // the error .NET message for this exception is created in the formatter UpdateClientRequestWithReplyData(request, new ReturnMessage(userEx, request.Request), cntxColl); userEx = request.InterceptReceiveException(userEx); response = new ReturnMessage(userEx, request.Request); // definitive exception only available here, because interception chain may change exception break; case 2 : Exception systemEx = DeserialiseSystemError(cdrStream, version); // the error .NET message for this exception is created in the formatter UpdateClientRequestWithReplyData(request, new ReturnMessage(systemEx, request.Request), cntxColl); systemEx = request.InterceptReceiveException(systemEx); response = new ReturnMessage(systemEx, request.Request); // definitive exception only available here, because interception chain may change exception break; case 3 : case 4 : // LOCATION_FORWARD / LOCATION_FORWARD_PERM: // --> deserialise it and return location fwd message response = DeserialiseLocationFwdReply(cdrStream, version, request); UpdateClientRequestWithReplyData(request, response, cntxColl); request.InterceptReceiveOther(); break; default : // deseralization of reply error, unknown reply status: responseStatus // the error .NET message for this exception is created in the formatter throw new MARSHAL(2401, CompletionStatus.Completed_MayBe); } } catch (Exception ex) { Trace.WriteLine("exception while deserialising reply: " + ex); try { cdrStream.SkipRest(); } catch (Exception) { // ignore this one, already problems. } if (!request.IsReplyInterceptionChainCompleted()) { // reply interception chain not yet called for this reply // deserialisation not ok: interception not called; // call interceptors with this exception. request.Reply = new ReturnMessage(ex, request.Request as IMethodCallMessage); Exception newException = request.InterceptReceiveException(ex); // exception may be changed by interception point if (ex != newException) { throw newException; // exception have been changed by interception point } } throw; } return response; }
/// <summary> /// helper method to update the GiopClientRequest with the new data from the reply /// </summary> private void UpdateClientRequestWithReplyData(GiopClientRequest request, IMessage response, ServiceContextList cntxColl) { request.Reply = response; request.ResponseServiceContext = cntxColl; // store the deserialised service context for handling in interceptors }
/// <summary>serializes the request body</summary> /// <param name="targetStream"></param> /// <param name="clientRequest">the request to serialise</param> /// <param name="version">the GIOP-version</param> private void SerialiseRequestBody(CdrOutputStream targetStream, GiopClientRequest clientRequest, GiopVersion version, ArgumentsSerializer ser) { // body of request msg: serialize arguments // clarification from CORBA 2.6, chapter 15.4.1: no padding, when no arguments are serialised --> // for backward compatibility, do it nevertheless AlignBodyIfNeeded(targetStream, version); ser.SerializeRequestArgs(clientRequest.RequestMethodName, clientRequest.RequestArguments, targetStream, clientRequest.RequestCallContext); }
/// <summary> /// serialises the message body for a GIOP request /// </summary> /// <param name="clientRequest">the giop request Msg</param> /// <param name="targetStream"></param> /// <param name="version">the Giop version to use</param> /// <param name="conDesc">the connection used for this request</param> internal void SerialiseRequest(GiopClientRequest clientRequest, CdrOutputStream targetStream, IIorProfile targetProfile, GiopConnectionDesc conDesc) { Trace.WriteLine(String.Format("serializing request for method {0}; uri {1}; id {2}", clientRequest.MethodToCall, clientRequest.CalledUri, clientRequest.RequestId)); try { clientRequest.SetRequestPICurrentFromThreadScopeCurrent(); // copy from thread scope picurrent before processing request ArgumentsSerializer ser = m_argSerFactory.Create(clientRequest.MethodToCall.DeclaringType); // determine the request method to send string idlRequestName = ser.GetRequestNameFor(clientRequest.MethodToCall); clientRequest.RequestMethodName = idlRequestName; clientRequest.InterceptSendRequest(); GiopVersion version = targetProfile.Version; ServiceContextList cntxColl = clientRequest.RequestServiceContext; // set code-set for the stream PerformCodeSetEstablishmentClient(targetProfile, conDesc, cntxColl); SetCodeSet(targetStream, conDesc); if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1 SerialiseContext(targetStream, cntxColl); // service context } targetStream.WriteULong(clientRequest.RequestId); byte responseFlags = 0; if (version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1 responseFlags = 1; } else { // reply-expected, no DII-call --> must be 0x03, no reply --> must be 0x00 responseFlags = 3; } if (clientRequest.IsOneWayCall) { responseFlags = 0; } // check if one-way // write response-flags targetStream.WriteOctet(responseFlags); targetStream.WritePadding(3); // reserved bytes WriteTarget(targetStream, targetProfile.ObjectKey, version); // write the target-info targetStream.WriteString(clientRequest.RequestMethodName); // write the method name if (version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1 targetStream.WriteULong(0); // no principal } else { // GIOP 1.2 SerialiseContext(targetStream, cntxColl); // service context } SerialiseRequestBody(targetStream, clientRequest, version, ser); } catch (Exception ex) { Debug.WriteLine("exception while serialising request: " + ex); Exception newException = clientRequest.InterceptReceiveException(ex); // interception point may change exception if (newException == ex) { throw; } else { throw newException; // exception has been changed by interception point } } }
/// <summary> /// construct a client request info based on the ClientRequest data. /// </summary> /// <remarks>delegates client requests normally to the serverRequest instance.</remarks> internal ClientRequestInfoImpl(GiopClientRequest clientRequest) : base(clientRequest) { m_clientRequest = clientRequest; }