MINA
  1. MINA
  2. DIRMINA-92

Utility classes for asynchronous request-response protocols.

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.7.0
    • Fix Version/s: 2.0.0-M1
    • Component/s: None
    • Labels:
      None

      Description

      There are so many existing asynchronous protocols whose messages have request-response structure. A request message usually has a message ID, and the corresponding response message, which makes a pair, contains the message ID in the request message.

      It would be great if we can provide a common interface and classes to help users implement this type of protocols easily.

      1. Protocol.zip
        113 kB
        Trustin Lee
      2. queryreply.zip
        2 kB
        Julien Vermillard
      3. requestResponse.zip
        5 kB
        Johannes Zillmann

        Activity

        Hide
        Emmanuel Lecharny added a comment -

        Doom it.

        I don't like it when the framework take care of a part of the protocol for you...

        Show
        Emmanuel Lecharny added a comment - Doom it. I don't like it when the framework take care of a part of the protocol for you...
        Hide
        Ashish Paliwal added a comment -

        Based on our ML List discussion (http://mina.markmail.org/thread/rodcslkrhgjcpikn), we are to deleting reqres filter. Do we plan to do this? We can close https://issues.apache.org/jira/browse/DIRMINA-593 along with this as well

        Show
        Ashish Paliwal added a comment - Based on our ML List discussion ( http://mina.markmail.org/thread/rodcslkrhgjcpikn ), we are to deleting reqres filter. Do we plan to do this? We can close https://issues.apache.org/jira/browse/DIRMINA-593 along with this as well
        Hide
        Trustin Lee added a comment -

        Alternatively, you can use awaitResponse() method:

        Request req = ...;
        session.write(req);

        try

        { Response res = req.awaitResponse(); // Do something the the response. ...... }

        catch (RequestTimeoutException e)

        { ...... }
        Show
        Trustin Lee added a comment - Alternatively, you can use awaitResponse() method: Request req = ...; session.write(req); try { Response res = req.awaitResponse(); // Do something the the response. ...... } catch (RequestTimeoutException e) { ...... }
        Hide
        Trustin Lee added a comment -

        This feature has been implemented finally. Please refer to the following ViewVC page to browse the source code.

        http://tinyurl.com/3ahxg6

        I didn't write the JavaDoc and the tutorial yet (I will do soon). Meanwhile, the following step-by-step example will help you understand how to use the RequestResponseFilter.

        0) Scenario: A client sends a MyRequest message with a certain ID, then the server will respond with MyResponse message with the same ID, to identify that the response message related to the request message with the same ID.

        1) Implement ResponseInspector.

        public class MyResponseInspector implements ResponseInspector {
        public Object getRequestId(Object message) {
        if (!(message instanceof MyResponse))

        { return null; }

        MyResponse response = (MyResponse) message;
        return response.getId();
        }

        public ResponseType getResponseType(Object message)

        { // You can return PARTIAL or PARTIAL_LAST if the protocol has multiple responses per request. return ResponseType.WHOLE; }

        }

        2) Insert the RequestResponseFilter.

        connector.getFilterChain().addLast(
        "reqres", new RequestResponseFilter(new MyResponseInspector()));

        3) Implement IoHandler.

        import org.apache.mina.filter.reqres.Request;
        import org.apache.mina.filter.reqres.Response;

        public class MyHandler extends IoHandlerAdapter {
        public void sessionOpened(IoSession session) throws Exception

        { MyRequest req = ...; // Send the request with 5 seconds timeout. session.write(new Request(req.getId(), req, 5, TimeUnit.SECONDS)); }

        public void messageReceived(IoSession session, Object message) throws Exception

        { Response res = (Response) message; MyRequest req = res.getRequest().getMessage(); MyResponse res = res.getMessage(); // Do something with the messages. ...... }

        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        if (cause instanceof RequestTimeoutException)

        { RequestTimeoutException rte = (RequestTimeoutException) cause; rte.getRequest(); // Do something with the failed request. // RequestTimeoutException is thrown also when // a connection is closed but the related response is not received yet. ...... }

        }
        }

        Please give me feedback if the API doesn't make sense or needs improvement.

        Show
        Trustin Lee added a comment - This feature has been implemented finally. Please refer to the following ViewVC page to browse the source code. http://tinyurl.com/3ahxg6 I didn't write the JavaDoc and the tutorial yet (I will do soon). Meanwhile, the following step-by-step example will help you understand how to use the RequestResponseFilter. 0) Scenario: A client sends a MyRequest message with a certain ID, then the server will respond with MyResponse message with the same ID, to identify that the response message related to the request message with the same ID. 1) Implement ResponseInspector. public class MyResponseInspector implements ResponseInspector { public Object getRequestId(Object message) { if (!(message instanceof MyResponse)) { return null; } MyResponse response = (MyResponse) message; return response.getId(); } public ResponseType getResponseType(Object message) { // You can return PARTIAL or PARTIAL_LAST if the protocol has multiple responses per request. return ResponseType.WHOLE; } } 2) Insert the RequestResponseFilter. connector.getFilterChain().addLast( "reqres", new RequestResponseFilter(new MyResponseInspector())); 3) Implement IoHandler. import org.apache.mina.filter.reqres.Request; import org.apache.mina.filter.reqres.Response; public class MyHandler extends IoHandlerAdapter { public void sessionOpened(IoSession session) throws Exception { MyRequest req = ...; // Send the request with 5 seconds timeout. session.write(new Request(req.getId(), req, 5, TimeUnit.SECONDS)); } public void messageReceived(IoSession session, Object message) throws Exception { Response res = (Response) message; MyRequest req = res.getRequest().getMessage(); MyResponse res = res.getMessage(); // Do something with the messages. ...... } public void exceptionCaught(IoSession session, Throwable cause) throws Exception { if (cause instanceof RequestTimeoutException) { RequestTimeoutException rte = (RequestTimeoutException) cause; rte.getRequest(); // Do something with the failed request. // RequestTimeoutException is thrown also when // a connection is closed but the related response is not received yet. ...... } } } Please give me feedback if the API doesn't make sense or needs improvement.
        Hide
        Klaus Stake added a comment -

        Hi Julien,

        I tried to use the stuff in queryreply.zip. How should I use the classes? I did the following:

        • ... chain.addFirst( "queryReply", new RequestResponseFilter(new BasicRequestFactory(10000))); //timeout == 10 secs

        ... and then what to do? I guess that I must call the RequestResponseFilter's query() method somewhere. I did that in my customized IoHandler for sending a message. The problem is that the query method blocks the application because of the following line in the query method:
        ...
        try

        { lastRequest.wait(lastRequest.getResponseTimeout()); }

        catch (InterruptedException e)

        { throw new RuntimeException(e); }

        ...

        Mina does not send the message after the set response timeout. I set the response timeout to 10000 (10 secs) and the application blocks for 10 seconds

        Do you have a test case for your RequestResponseFilter? Did I do something wrong?

        Another comment on RequestImpl's getReplyMessage(): it should be renamed to getResponseMessage according to the method setResponseMessage()

        Klaus

        Show
        Klaus Stake added a comment - Hi Julien, I tried to use the stuff in queryreply.zip. How should I use the classes? I did the following: ... chain.addFirst( "queryReply", new RequestResponseFilter(new BasicRequestFactory(10000))); //timeout == 10 secs ... and then what to do? I guess that I must call the RequestResponseFilter's query() method somewhere. I did that in my customized IoHandler for sending a message. The problem is that the query method blocks the application because of the following line in the query method: ... try { lastRequest.wait(lastRequest.getResponseTimeout()); } catch (InterruptedException e) { throw new RuntimeException(e); } ... Mina does not send the message after the set response timeout. I set the response timeout to 10000 (10 secs) and the application blocks for 10 seconds Do you have a test case for your RequestResponseFilter? Did I do something wrong? Another comment on RequestImpl's getReplyMessage(): it should be renamed to getResponseMessage according to the method setResponseMessage() Klaus
        Hide
        Julien Vermillard added a comment -

        a good idea whould be to add a "request without reply" counter, for detect dead connection.

        Show
        Julien Vermillard added a comment - a good idea whould be to add a "request without reply" counter, for detect dead connection.
        Hide
        Julien Vermillard added a comment -

        attached queryreply.zip, the filter based on trustin ideas I use in my apps. WDYT ? I whould like to have comments before finishing it and integrate it in MINA.

        Julien

        Show
        Julien Vermillard added a comment - attached queryreply.zip, the filter based on trustin ideas I use in my apps. WDYT ? I whould like to have comments before finishing it and integrate it in MINA. Julien
        Hide
        Johannes Zillmann added a comment -

        I have attached a zip with some classes for a 'synchronious' request-response model. May out of topic, may it help...
        The solution only wokrs with object serialization i guess.

        Show
        Johannes Zillmann added a comment - I have attached a zip with some classes for a 'synchronious' request-response model. May out of topic, may it help... The solution only wokrs with object serialization i guess.
        Hide
        Trustin Lee added a comment -

        His implementation is very impressive and provides a lot of features, but it seems like it is designed to be very specific to a specific protocol and management environment IMHO.

        Here's my implementation plan:

        • RequestMessage which has a method 'getMessageId()' which returns an Object. The messageId type will have to implement equals and hashCode methods properly.
        • ResponseMessage which has a method 'getRequestMessageId()' which returns an Object. The constraint is same with that of RequestMessage.
        • RequestResponseProtocolFilter that remembers sent RequestMessages and fires an 'exceptionCaught' event with an appropriate 'RequestTimeoutException' to ProtocolHandler if the ResponseMessage is not arriving for certain specified time.

        WDYT?

        Show
        Trustin Lee added a comment - His implementation is very impressive and provides a lot of features, but it seems like it is designed to be very specific to a specific protocol and management environment IMHO. Here's my implementation plan: RequestMessage which has a method 'getMessageId()' which returns an Object. The messageId type will have to implement equals and hashCode methods properly. ResponseMessage which has a method 'getRequestMessageId()' which returns an Object. The constraint is same with that of RequestMessage. RequestResponseProtocolFilter that remembers sent RequestMessages and fires an 'exceptionCaught' event with an appropriate 'RequestTimeoutException' to ProtocolHandler if the ResponseMessage is not arriving for certain specified time. WDYT?
        Hide
        Trustin Lee added a comment -

        This attachment (Protocol.zip) is the contribution from Thomas Muller. We have to review it and create our one.

        Show
        Trustin Lee added a comment - This attachment (Protocol.zip) is the contribution from Thomas Muller. We have to review it and create our one.

          People

          • Assignee:
            Trustin Lee
            Reporter:
            Trustin Lee
          • Votes:
            3 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development