private DestinationHandler handleFRPMessage(MessageItem msg,
                                                TransactionCommon tran,
                                                MessageProducer sender,
                                                boolean msgFRP)

                    throws SINotAuthorizedException,
                    SIMPNotPossibleInCurrentConfigurationException,
                    SIResourceException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "handleFRPMessage", new Object[] { msg, tran, sender, Boolean.valueOf(msgFRP) });

        List<SIDestinationAddress> frp = msg.getMessage().getForwardRoutingPath();

        // Walk down the FRP until we come to a destination that the message needs
        // to go to.
        // e.g. it's the end of the list, it's a topicspace or it's in a foreign bus
        JsDestinationAddress head = null;
        DestinationHandler frpDestination = null;
        DestinationHandler previousDestination = _destination;
        do
        {
            // Pop off first element of FRP
            head = (JsDestinationAddress) frp.get(0);

            String name = head.getDestinationName();
            String busName = head.getBusName();

            //Get the named destination from the destination manager
            try
            {
                frpDestination =
                                _messageProcessor.getDestinationManager().
                                                getDestination(name, busName, false);

                // If security is enabled, then we need to check authority to access
                // the next destination
                if (_messageProcessor.isBusSecure())
                {
                    // Will drive the form of sib.security checkDestinationAccess() that
                    // takes a JsMessage
                    JsMessage jsMsg = msg.getMessage();
                    String discriminator = jsMsg.getDiscriminator();
                    SecurityContext secContext = new SecurityContext(jsMsg,
                                    null, // alt user
                                    discriminator,
                                    _messageProcessor.getAuthorisationUtils());
                    checkDestinationAccess(frpDestination,
                                           secContext);
                }

                previousDestination = frpDestination;

                frp.remove(0);
            } catch (SIException e)
            {
                // No FFDC code Needed

                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                    SibTr.exception(tc, e);

                // Need to throw NotAuthorized exceptions back to the caller.
                if (e instanceof SINotAuthorizedException)
                {
                    // Write an audit record if access is denied
                    SibTr.audit(tc, nls_cwsik.getFormattedMessage(
                                                                  "DELIVERY_ERROR_SIRC_18", // USER_NOT_AUTH_SEND_ERROR_CWSIP0308
                                                                  new Object[] { name,
                                                                                msg.getMessage().getSecurityUserid() },
                                                                  null));

                    // Thrown if user denied access to destination
                    SIMPNotAuthorizedException ex =
                                    new SIMPNotAuthorizedException(e.getMessage());

                    ex.setExceptionReason(SIRCConstants.SIRC0020_USER_NOT_AUTH_SEND_ERROR);
                    ex.setExceptionInserts(new String[] { name,
                                                         msg.getMessage().getSecurityUserid() });
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                        SibTr.exit(tc, "handleFRPMessage", ex);
                    throw ex;
                }

                ExceptionDestinationHandlerImpl excDest = new ExceptionDestinationHandlerImpl(previousDestination);

                final UndeliverableReturnCode rc =
                                excDest.handleUndeliverableMessage(msg,
                                                                   tran,
                                                                   SIRCConstants.SIRC0037_INVALID_ROUTING_PATH_ERROR,
                                                                   new String[] { name,
                                                                                 _messageProcessor.getMessagingEngineName(),
                                                                                 previousDestination.getName(),
                                                                                 SIMPUtils.getStackTrace(e)
                                                                   });

                if (rc == UndeliverableReturnCode.ERROR || rc == UndeliverableReturnCode.BLOCK)
                {
                    SIMPNotPossibleInCurrentConfigurationException ee = new SIMPNotPossibleInCurrentConfigurationException(
                                    nls_cwsik.getFormattedMessage(
                                                                  "DELIVERY_ERROR_SIRC_23", // EXCEPTION_DESTINATION_ERROR_CWSIP0296
                                                                  new Object[] { name, rc, SIMPUtils.getStackTrace(e), _destination.getName() },
                                                                  null),
                                    e);

                    ee.setExceptionReason(SIRCConstants.SIRC0023_EXCEPTION_DESTINATION_ERROR);
                    ee.setExceptionInserts(new String[] { name, rc.toString(), SIMPUtils.getStackTrace(e), _destination.getName() });

                    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                        SibTr.exit(tc, "handleFRPMessage", ee);
                    throw ee;
                }

                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                    SibTr.exit(tc, "handleFRPMessage");
                // Indicate message was delivered to exception destination
                return null;
            }

        } // bypass the destination if its a queue (If the destination
          // is foreign we cannot tell if there is a medition or not, so we err on the side of
          // caution and send it there anyway)
        while ((!previousDestination.isPubSub() && // and it is not PubSub
                !frp.isEmpty() && // and there is more FRP to process
        !(previousDestination.isForeign() || previousDestination.isForeignBus()))); // and it is not foreign

        // Set the remainder of the FRP back into the message
        msg.getMessage().setForwardRoutingPath(frp);

        // Get the InputHandler for the chosen destination 
        ProducerInputHandler handler = null;
        if (frpDestination != null)
        {
            ProtocolType type = ProtocolType.UNICASTINPUT;
            if (frpDestination.isPubSub())
                type = ProtocolType.PUBSUBINPUT;
            handler = (ProducerInputHandler) frpDestination.getInputHandler(type,
                                                                            _messageProcessor.getMessagingEngineUuid(),
                                                                            null);
        }

        // If handler is null, the message went to the exception destination.
        // Otherwise we have a new InputHandler for the next interesting destination
        // in the FRP. Let it process the message.
        if (handler != null)
        {
            try
            {
                // Do some cleanup of the message to make it look like new 
                JsMessage jsMsg = msg.getMessage();

                // Defect 496906: Set the outAddress to "head" - the JsDestinationAddress of the
                // frpDestination we are working with. This variable is used as a base from which
                // to generate the routing address which will be set into the message.
                JsDestinationAddress outAddress = head;
                // Reset the redelivery count
                jsMsg.setRedeliveredCount(0);

                // If the FRP destination is either an alias or is foreign, then update
                // the RFH2 flag.
                if (frpDestination.isAlias() ||
                    frpDestination.isForeign() ||
                    frpDestination.isForeignBus())
                {
                    ProducerSessionImpl.setRFH2Allowed(jsMsg, frpDestination);
                }

                msg.incrementRedirectCount();

                // Generate error if max frp depth is exceeded
                if (msg.getRedirectCount() > _messageProcessor.getCustomProperties().get_max_frp_depth())
                {
                    SibTr.register(PtoPInputHandler.class,
                                   SIMPConstants.MP_TRACE_GROUP,
                                   SIMPConstants.CWSIK_RESOURCE_BUNDLE);

                    SibTr.error(tc, "DELIVERY_ERROR_SIRC_43",
                                new Integer(msg.getRedirectCount()));

                    SibTr.register(PtoPInputHandler.class,
                                   SIMPConstants.MP_TRACE_GROUP,
                                   SIMPConstants.RESOURCE_BUNDLE);

                    //Put the message to the exception destination
                    handleUndeliverableMessage(frpDestination
                                               , null // LinkHandler
                                               , msg
                                               , SIRCConstants.SIRC0043_MAX_FRP_DEPTH_EXCEEDED
                                               , new String[] { frpDestination.getName() },
                                               tran);
                }
                // We haven't hit the loop limit so lets pass the message onto the
                // next InputHandler
                else
                {
                    handler.handleProducerMessage(msg,
                                                  tran,
                                                  outAddress,
                                                  null,
                                                  msgFRP);
                }
            } catch (SIMPNoLocalisationsException e)
            {
                // No FFDC code needed

                // We can't find a suitable localisation.
                // Although a queue must have at least one localisation this is
                // possible if the sender restricted the potential localisations
                // using a fixed ME or a scoping alias (to an out-of-date set of
                // localisation)

                //Put the message to the exception destination
                handleUndeliverableMessage(frpDestination
                                           , null // LinkHandler
                                           , msg
                                           , SIRCConstants.SIRC0026_NO_LOCALISATIONS_FOUND_ERROR
                                           , new String[] { frpDestination.getName() },
                                           tran);
            } catch (Exception e)
            {
                //defect 259323
                //due to an unexpected error we cannot send this message along the
                //FRP. The best we can do is send the message to the exception destination
                //and ffdc/trace this event
                FFDCFilter.processException(
                                            e,
                                            "com.ibm.ws.sib.processor.impl.PtoPInputHandler.handleFRPMessage",
                                            "1:2072:1.323",
                                            this);

                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                {
                    SibTr.debug(tc, "FRP message being put to exception destination",
                                new Object[] { msg, e });
                }
                handleUndeliverableMessage(frpDestination
                                           , null // LinkHandler
                                           , msg
                                           , SIRCConstants.SIRC0001_DELIVERY_ERROR
                                           , new String[] { frpDestination.getName() },
                                           tran);
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "handleFRPMessage");

        return frpDestination;
    }
private DestinationHandler handleFRPMessage ( MessageItem msg , TransactionCommon tran , MessageProducer sender , boolean msgFRP ) throws SINotAuthorizedException , SIMPNotPossibleInCurrentConfigurationException , SIResourceException { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . entry ( tc , "handleFRPMessage" , new Object [ ] { msg , tran , sender , Boolean . valueOf ( msgFRP ) } ) ; List < SIDestinationAddress > frp = msg . getMessage ( ) . getForwardRoutingPath ( ) ; JsDestinationAddress head = null ; DestinationHandler frpDestination = null ; DestinationHandler previousDestination = _destination ; do { head = ( JsDestinationAddress ) frp . get ( 0 ) ; String name = head . getDestinationName ( ) ; String busName = head . getBusName ( ) ; try { frpDestination = _messageProcessor . getDestinationManager ( ) . getDestination ( name , busName , false ) ; if ( _messageProcessor . isBusSecure ( ) ) { JsMessage jsMsg = msg . getMessage ( ) ; String discriminator = jsMsg . getDiscriminator ( ) ; SecurityContext secContext = new SecurityContext ( jsMsg , null , discriminator , _messageProcessor . getAuthorisationUtils ( ) ) ; checkDestinationAccess ( frpDestination , secContext ) ; } previousDestination = frpDestination ; frp . remove ( 0 ) ; } catch ( SIException e ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) SibTr . exception ( tc , e ) ; if ( e instanceof SINotAuthorizedException ) { SibTr . audit ( tc , nls_cwsik . getFormattedMessage ( "DELIVERY_ERROR_SIRC_18" , new Object [ ] { name , msg . getMessage ( ) . getSecurityUserid ( ) } , null ) ) ; SIMPNotAuthorizedException ex = new SIMPNotAuthorizedException ( e . getMessage ( ) ) ; ex . setExceptionReason ( SIRCConstants . SIRC0020_USER_NOT_AUTH_SEND_ERROR ) ; ex . setExceptionInserts ( new String [ ] { name , msg . getMessage ( ) . getSecurityUserid ( ) } ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . exit ( tc , "handleFRPMessage" , ex ) ; throw ex ; } ExceptionDestinationHandlerImpl excDest = new ExceptionDestinationHandlerImpl ( previousDestination ) ; final UndeliverableReturnCode rc = excDest . handleUndeliverableMessage ( msg , tran , SIRCConstants . SIRC0037_INVALID_ROUTING_PATH_ERROR , new String [ ] { name , _messageProcessor . getMessagingEngineName ( ) , previousDestination . getName ( ) , SIMPUtils . getStackTrace ( e ) } ) ; if ( rc == UndeliverableReturnCode . ERROR || rc == UndeliverableReturnCode . BLOCK ) { SIMPNotPossibleInCurrentConfigurationException ee = new SIMPNotPossibleInCurrentConfigurationException ( nls_cwsik . getFormattedMessage ( "DELIVERY_ERROR_SIRC_23" , new Object [ ] { name , rc , SIMPUtils . getStackTrace ( e ) , _destination . getName ( ) } , null ) , e ) ; ee . setExceptionReason ( SIRCConstants . SIRC0023_EXCEPTION_DESTINATION_ERROR ) ; ee . setExceptionInserts ( new String [ ] { name , rc . toString ( ) , SIMPUtils . getStackTrace ( e ) , _destination . getName ( ) } ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . exit ( tc , "handleFRPMessage" , ee ) ; throw ee ; } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . exit ( tc , "handleFRPMessage" ) ; return null ; } } while ( ( ! previousDestination . isPubSub ( ) && ! frp . isEmpty ( ) && ! ( previousDestination . isForeign ( ) || previousDestination . isForeignBus ( ) ) ) ) ; msg . getMessage ( ) . setForwardRoutingPath ( frp ) ; ProducerInputHandler handler = null ; if ( frpDestination != null ) { ProtocolType type = ProtocolType . UNICASTINPUT ; if ( frpDestination . isPubSub ( ) ) type = ProtocolType . PUBSUBINPUT ; handler = ( ProducerInputHandler ) frpDestination . getInputHandler ( type , _messageProcessor . getMessagingEngineUuid ( ) , null ) ; } if ( handler != null ) { try { JsMessage jsMsg = msg . getMessage ( ) ; JsDestinationAddress outAddress = head ; jsMsg . setRedeliveredCount ( 0 ) ; if ( frpDestination . isAlias ( ) || frpDestination . isForeign ( ) || frpDestination . isForeignBus ( ) ) { ProducerSessionImpl . setRFH2Allowed ( jsMsg , frpDestination ) ; } msg . incrementRedirectCount ( ) ; if ( msg . getRedirectCount ( ) > _messageProcessor . getCustomProperties ( ) . get_max_frp_depth ( ) ) { SibTr . register ( PtoPInputHandler . class , SIMPConstants . MP_TRACE_GROUP , SIMPConstants . CWSIK_RESOURCE_BUNDLE ) ; SibTr . error ( tc , "DELIVERY_ERROR_SIRC_43" , new Integer ( msg . getRedirectCount ( ) ) ) ; SibTr . register ( PtoPInputHandler . class , SIMPConstants . MP_TRACE_GROUP , SIMPConstants . RESOURCE_BUNDLE ) ; handleUndeliverableMessage ( frpDestination , null , msg , SIRCConstants . SIRC0043_MAX_FRP_DEPTH_EXCEEDED , new String [ ] { frpDestination . getName ( ) } , tran ) ; } else { handler . handleProducerMessage ( msg , tran , outAddress , null , msgFRP ) ; } } catch ( SIMPNoLocalisationsException e ) { handleUndeliverableMessage ( frpDestination , null , msg , SIRCConstants . SIRC0026_NO_LOCALISATIONS_FOUND_ERROR , new String [ ] { frpDestination . getName ( ) } , tran ) ; } catch ( Exception e ) { FFDCFilter . processException ( e , "com.ibm.ws.sib.processor.impl.PtoPInputHandler.handleFRPMessage" , "1:2072:1.323" , this ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { SibTr . debug ( tc , "FRP message being put to exception destination" , new Object [ ] { msg , e } ) ; } handleUndeliverableMessage ( frpDestination , null , msg , SIRCConstants . SIRC0001_DELIVERY_ERROR , new String [ ] { frpDestination . getName ( ) } , tran ) ; } } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . exit ( tc , "handleFRPMessage" ) ; return frpDestination ; }
Puts a message to the forward routing path destination of a message.
Will throw an SINotAuthorizedException if the user is not allowed
to put a message to the destination along the forward routing path

@param msg
@param tran
@param sourceCellule
@return
@throws SINotAuthorizedException
@throws SIMPNotPossibleInCurrentConfigurationException