public boolean ami_callback_request()

in yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java [792:1027]


    public boolean ami_callback_request(OutputStream out, ReplyHandler reply, org.apache.yoko.orb.OCI.ProfileInfo info) throws RemarshalException {
        //
        // We should have an InvocationContext associated with the
        // OutputStream
        //
        org.apache.yoko.orb.CORBA.OutputStream o = (org.apache.yoko.orb.CORBA.OutputStream) out;
        InvocationContext ctx = (InvocationContext) o._OB_invocationContext();
        Assert._OB_assert(ctx != null);

        //
        // If the DowncallStub has changed, then remarshal
        //
        if (ctx.downcallStub != this)
            throw new RemarshalException();

        org.apache.yoko.orb.CORBA.InputStream tmpIn = (org.apache.yoko.orb.CORBA.InputStream) out.create_input_stream();

        //
        // Unmarshal the message header
        //
        MessageHeader_1_1 msgHeader = MessageHeader_1_2Helper.read(tmpIn);

        //
        // Check the GIOP version
        //
        if (!(msgHeader.GIOP_version.major >= 1 && msgHeader.GIOP_version.minor >= 2)) {
            //
            // Report error - throw exception?
            //
            return false;
        }

        //
        // Check the message type
        //
        if (msgHeader.message_type != (byte) MsgType_1_1._Request) {
            //
            // Report error - throw exception
            //
            return false;
        }

        //
        // Create and populate a RequestInfo to send to the router
        //
        RequestInfo requestInfo = new RequestInfo();

        //
        // Unmarshal the request header
        // 
        RequestHeader_1_2 requestHeader = RequestHeader_1_2Helper.read(tmpIn);

        //
        // Create and populate a RequestInfo structure to send to the
        // Router
        //
        RouterListHolder configRouterList = new RouterListHolder();
        configRouterList.value = new Router[0];

        //
        // Populate the configRouterList
        //
        org.apache.yoko.orb.OB.MessageRoutingUtil.getRouterListFromComponents(orbInstance_, info, configRouterList);

        requestInfo.visited = new Router[0];
        requestInfo.to_visit = new Router[0];

        //
        // Get the target for this request
        //
        org.apache.yoko.orb.OB.ObjectFactory objectFactory = orbInstance_.getObjectFactory();
        //
        // REVISIT: Should we be using IOR_ or origIOR_?
        //
        requestInfo.target = objectFactory.createObject(IOR_);

        //
        // Get the index of the profile being used
        //
        requestInfo.profile_index = (short) info.index;

        //
        // Get the reply destination for this request
        //
        ReplyDestination replyDest = new ReplyDestination();
        replyDest.handler_type = ReplyDisposition.TYPED;
        replyDest.handler = reply;
        requestInfo.reply_destination = replyDest;

        //
        // Get the selected qos for this request
        //
        PolicyValueSeqHolder invocPoliciesHolder = new PolicyValueSeqHolder();
        invocPoliciesHolder.value = new PolicyValue[0];
        org.apache.yoko.orb.OB.MessageRoutingUtil.getInvocationPolicyValues(policies_, invocPoliciesHolder);
        requestInfo.selected_qos = invocPoliciesHolder.value;

        //
        // Create payload (RequestMessage) for this request
        //
        RequestMessage requestMessage = new RequestMessage();
        requestMessage.giop_version = new org.omg.GIOP.Version();
        requestMessage.giop_version.major = info.major;
        requestMessage.giop_version.minor = info.minor;

        //
        // Get the service contexts for this request
        //
        requestMessage.service_contexts = requestHeader.service_context;

        //
        // Add the invocation policies service context for this request.
        // Note that this can change from request to request
        //
        ServiceContext invocPoliciesSC = new ServiceContext();
        invocPoliciesSC.context_id = INVOCATION_POLICIES.value;

        //
        // Create an output stream an write the PolicyValueSeq
        //
        if (invocPoliciesHolder.value != null) {
            org.apache.yoko.orb.OCI.Buffer scBuf = new org.apache.yoko.orb.OCI.Buffer();
            org.apache.yoko.orb.CORBA.OutputStream scOut = new org.apache.yoko.orb.CORBA.OutputStream(
                    scBuf);
            scOut._OB_writeEndian();
            PolicyValueSeqHelper.write(scOut, invocPoliciesHolder.value);
            invocPoliciesSC.context_data = new byte[scOut._OB_pos()];
            System.arraycopy(invocPoliciesSC.context_data, 0, scBuf.data(), 0, scBuf.length());
        }

        //
        // Add the service context to the list of current service contexts
        //
        int scLength = requestMessage.service_contexts.length;
        ServiceContext[] scList = new ServiceContext[scLength + 1];
        System.arraycopy(requestMessage.service_contexts, 0, scList, 0, scLength);
        scList[scLength] = invocPoliciesSC;

        //
        // Get the response flags for the request
        //
        requestMessage.response_flags = requestHeader.response_flags;

        //
        // Reserved octets
        //
        requestMessage.reserved = new byte[3];
        requestMessage.reserved[0] = requestHeader.reserved[0];
        requestMessage.reserved[1] = requestHeader.reserved[1];
        requestMessage.reserved[2] = requestHeader.reserved[2];

        //
        // Get the object key for the request
        //
        int keyLen = info.key.length;
        requestMessage.object_key = new byte[keyLen];
        System.arraycopy(info.key, 0, requestMessage.object_key, 0, keyLen);

        //
        // Get the operation name for the request
        //
        requestMessage.operation = requestHeader.operation;

        //
        // Get the body of the request message
        //
        MessageBody messageBody = new MessageBody();

        //
        // Java is always big endian
        //
        messageBody.byte_order = false;

        org.apache.yoko.orb.OCI.Buffer buf = tmpIn._OB_buffer();

        //
        // Align to an 8 byte boundary if we have something left
        //
        if (buf.rest_length() > 0) {
            buf.pos((buf.pos() + 7) & ~7);
        }

        //
        // Copy in the rest of the message body
        //
        messageBody.body = new byte[buf.rest_length()];
        System.arraycopy(buf.data_, buf.pos(), messageBody.body, 0, buf.rest_length());
        requestMessage.body = messageBody;

        //
        // Add the payload to the RequestInfo
        //
        requestInfo.payload = requestMessage;

        //
        // Now we have to try send the request to a router
        //
        boolean delivered = false;
        int numRouters = configRouterList.value.length;

        for (int i = numRouters - 1; (delivered == false) && (i >= 0); --i) {
            Router curRouter = configRouterList.value[i];

            //
            // We only add the routers that we have attempted to contact to
            // the to_visit list. This ensures that if a router accepts
            // the request, then the lower priority routers are not added
            //
            int curLength = requestInfo.to_visit.length;
            Router[] toVisit = new Router[curLength + 1];
            if (curLength > 0) {
                System.arraycopy(requestInfo.to_visit, 0, toVisit, 1, curLength);
            }
            toVisit[0] = curRouter;
            requestInfo.to_visit = toVisit;

            try {
                curRouter.send_request(requestInfo);

                //
                // Success: stop processing
                //
                delivered = true;
            } catch (SystemException ex) {
                logger.log(Level.FINE, "Failed to contact router: " + ex.getMessage(), ex); 
                //
                // Failure: try the next router in the list
                //
            }
        }

        //
        // return whether we were successful or not
        //
        return delivered;
    }