How to reuse Request in DispatchInterceptor?

bglmmzbglmmz Joey LvOrganization: PersonalProject: CA systemMember

ENV
ICE: 3.7.1
JDK: 10.0
WINDOWS 10

My case:
Node_A will send a request to Node_B,then the Node_B will handle the request locally, and it will forward the request to Node_C.
Here is my code sample:

public class ForwardInterceptor extends DispatchInterceptor {
    @Override
    public CompletionStage<OutputStream> dispatch(Request request) throws UserException{


        Identity identity = request.getCurrent().id;
        String serviceName = request.getCurrent().id.name;
        String operation = request.getCurrent().operation;
        Map<String, String> context = request.getCurrent().ctx;

        //get all dest node ids
        List<String> destNodeIdList = JSON.parseArray(context.get("DestNodeId"));



        Object servant = NodeContext.findServant(identity);
        if (servant != null) {
            if(destNodeList.size()<=1){
                //just only dispatch the request to local servant
                return servant.ice_dispatch(request);

            }else{

                //step 1: dispatch the request to local servant
                servant.ice_dispatch(request);              

                //step 2:remove current node Id from destNodeIdList

                //step 3: forward the request to other-nodes
                for(String destNodeId : destNodeIdList){
                    Session destSession = SessionManager.getSession(destNodeId);
                    ObjectPrx base = destSession.getProxy(serviceName);

                    //Error, How to retrieve byte[] inParams from request object?
                    byte[] inParams = getInParams(request); 
                    base.ice_invoke(operation, com.zeroc.Ice.OperationMode.Normal, inParams, context);  

              }
            }
        }
    }


    private byte[] getInParams(Request request){
      Incoming in = (Incoming)request;
      byte[] inParams = in.readParamEncaps();
      in.startOver();
      return inParams;
    }
}

Best Answers

  • benoitbenoit Rennes, FranceBenoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    Accepted Answer

    Hi,

    You're using un-documented IceInternal APIs here. You can't use dispatch interceptors for your use case. Instead of dispatch interceptors, you should use the Blobjects API:

    • implement a blobject servant and install it as a default servant (like you did for the dispatch interceptor)
    • the implementation of this blobject servant will forward the request to a number of proxies which can point to a local Ice object from Node_B and a remote Ice object on Node_C.

    On Node_B, you can create an object adapter without endpoints to host the Ice objects that the blobject will invoke on.

    Let us know if you need additional information on this.

    Cheers,
    Benoit.

  • bglmmzbglmmz Joey LvOrganization: PersonalProject: CA system
    Accepted Answer

    I resolved this problem, and I still used dispatch interceptor.

    ...
      ((Incoming)request).startOver();
      to do something with request;
      ((Incoming)request).startOver();
      ...
      ObjectPrx.ice_invoke(operation, OperationMode.Normal, ((Incoming)request).readParamEncaps(), context);
    

Answers

  • bglmmzbglmmz Joey LvOrganization: PersonalProject: CA systemMember
    edited May 2018

    the exception on Node_B:

        at com.zeroc.IceInternal.OutgoingAsyncBaseI.waitForResponse(OutgoingAsyncBaseI.java:92) ~[ice-3.7.1.jar:?]
        at com.zeroc.IceInternal.ProxyIceInvoke.waitForResponse(ProxyIceInvoke.java:73) ~[ice-3.7.1.jar:?]
        at com.zeroc.Ice._ObjectPrxI.ice_invoke(_ObjectPrxI.java:145) ~[ice-3.7.1.jar:?]
    

    the exception on Node_C:

      com.zeroc.Ice.UnmarshalOutOfBoundsException
         reason = ""
        at com.zeroc.Ice.InputStream.readInt(InputStream.java:1299)
        at com.zeroc.Ice.InputStream.readEncapsulation(InputStream.java:686)
        at com.zeroc.IceInternal.Incoming.readParamEncaps(Incoming.java:437)
    
  • benoitbenoit Rennes, FranceBenoit FoucherOrganization: ZeroC, Inc.Project: IceAdministrators, ZeroC Staff ZeroC Staff
    Accepted Answer

    Hi,

    You're using un-documented IceInternal APIs here. You can't use dispatch interceptors for your use case. Instead of dispatch interceptors, you should use the Blobjects API:

    • implement a blobject servant and install it as a default servant (like you did for the dispatch interceptor)
    • the implementation of this blobject servant will forward the request to a number of proxies which can point to a local Ice object from Node_B and a remote Ice object on Node_C.

    On Node_B, you can create an object adapter without endpoints to host the Ice objects that the blobject will invoke on.

    Let us know if you need additional information on this.

    Cheers,
    Benoit.

  • bglmmzbglmmz Joey LvOrganization: PersonalProject: CA systemMember
    Accepted Answer

    I resolved this problem, and I still used dispatch interceptor.

    ...
      ((Incoming)request).startOver();
      to do something with request;
      ((Incoming)request).startOver();
      ...
      ObjectPrx.ice_invoke(operation, OperationMode.Normal, ((Incoming)request).readParamEncaps(), context);
    
Sign In or Register to comment.