Package org.jboss.ws.extensions.wsrm.transport

Source Code of org.jboss.ws.extensions.wsrm.transport.RMSender

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ws.extensions.wsrm.transport;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletResponse;

import org.jboss.logging.Logger;
import org.jboss.remoting.transport.http.HTTPMetadataConstants;
import org.jboss.ws.extensions.wsrm.api.RMException;
import org.jboss.ws.extensions.wsrm.config.RMMessageRetransmissionConfig;

/**
* RM sender ensures reliable message delivery. The QoS is specified in the JAX-WS client Sconfiguration file.
*
* @author richard.opalka@jboss.com
*/
public final class RMSender
{
  
   private static final Logger logger = Logger.getLogger(RMSender.class);
   private static RMSender instance = new RMSender();
   private static final ThreadFactory rmThreadPool = new RMThreadPoolFactory();
   private static final int maxCountOfThreads = 5;
   private static final ExecutorService rmTasksQueue = Executors.newFixedThreadPool(maxCountOfThreads, rmThreadPool);
  
   /**
    * Generates worker threads (daemons)
    */
   private static final class RMThreadPoolFactory implements ThreadFactory
   {
      final ThreadGroup group;
      final AtomicInteger threadNumber = new AtomicInteger(1);
      final String namePrefix = "rm-pool-worker-thread-";
   
      private RMThreadPoolFactory()
      {
         SecurityManager sm = System.getSecurityManager();
         group = (sm != null) ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup();
      }
     
      public Thread newThread(Runnable r)
      {
         Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
         if (false == t.isDaemon())
            t.setDaemon(true);
         if (Thread.NORM_PRIORITY != t.getPriority())
            t.setPriority(Thread.NORM_PRIORITY);
         return t;
      }
   }

   private RMSender()
   {
      // forbidden inheritance
   }
  
   public static final RMSender getInstance()
   {
      return instance;
   }

   public final RMMessage send(RMMessage request) throws Throwable
   {
      RMMessageRetransmissionConfig qos = RMTransportHelper.getSequence(request).getRMConfig().getMessageRetransmission();
      if (qos == null)
         throw new RMException("User must specify message retransmission configuration in JAX-WS WS-RM config");
     
      int countOfAttempts = qos.getCountOfAttempts();
      int inactivityTimeout = qos.getMessageTimeout();
      int retransmissionInterval = qos.getRetransmissionInterval();
      RMChannelResponse result = null;
      long startTime = 0L;
      long endTime = 0L;
      int attemptNumber = 1;
     
      for (int i = 0; i < countOfAttempts; i++)
      {
         logger.debug("Sending RM request - attempt no. " + attemptNumber++);
         Future<RMChannelResponse> futureResult = rmTasksQueue.submit(new RMChannelTask(request));
         try
         {
            startTime = System.currentTimeMillis();
            result = futureResult.get(inactivityTimeout, TimeUnit.SECONDS);
            if (result != null)
            {
               Throwable t = result.getFault();
               if (t != null)
               {
                  logger.warn(result.getFault().getClass().getName(), result.getFault());
               }
               else
               {
                  endTime = System.currentTimeMillis();
                  if (result.getResponse() != null)
                  {
                     Map<String, Object> remotingCtx = result.getResponse().getMetadata().getContext(RMChannelConstants.REMOTING_INVOCATION_CONTEXT);
                     if (remotingCtx != null)
                     {
                        if (Integer.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).equals(remotingCtx.get(HTTPMetadataConstants.RESPONSE_CODE)))
                        {
                           logger.debug("Response message received in " + (endTime - startTime) + " miliseconds, but contains internal server code, going to resend the request message");
                           continue;
                        }
                     }
                  }
                  logger.debug("Response message received in " + (endTime - startTime) + " miliseconds");
                  break;
               }
               try
               {
                  Thread.sleep(retransmissionInterval * 1000);
               }
               catch (InterruptedException ie)
               {
                  logger.warn(ie.getMessage(), ie);
               }
            }
         }
         catch (TimeoutException te)
         {
            endTime = System.currentTimeMillis();
            logger.warn("Timeout - response message not received in " + (endTime - startTime) + " miliseconds");
            try
            {
               Thread.sleep(retransmissionInterval * 1000);
            }
            catch (InterruptedException ie)
            {
               logger.warn(ie.getMessage(), ie);
            }
         }
      }

      if (result == null)
         throw new RMException("Unable to deliver message with addressing id: " + RMTransportHelper.getAddressingMessageId(request) + ". Count of attempts to deliver the message was: " + countOfAttempts);
     
      Throwable fault = result.getFault();
      if (fault != null)
      {
         throw new RMException("Unable to deliver message with addressing id: " + RMTransportHelper.getAddressingMessageId(request) + ". Count of attempts to deliver the message was: " + countOfAttempts, fault);
      }
      else
      {
         return result.getResponse();
      }
   }
  
}
TOP

Related Classes of org.jboss.ws.extensions.wsrm.transport.RMSender

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');