[jboss-svn-commits] JBL Code SVN: r25071 - in labs/jbossesb/trunk/product: rosetta/src/org/jboss/soa/esb/client and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Feb 3 06:33:05 EST 2009


Author: kevin.conner at jboss.com
Date: 2009-02-03 06:33:05 -0500 (Tue, 03 Feb 2009)
New Revision: 25071

Added:
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java
Modified:
   labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
   labs/jbossesb/trunk/product/docs/ServicesGuide.odt
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java
Log:
Merged across 4.4CP2_CR4

Modified: labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
===================================================================
(Binary files differ)

Modified: labs/jbossesb/trunk/product/docs/ServicesGuide.odt
===================================================================
(Binary files differ)

Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java	2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java	2009-02-03 11:33:05 UTC (rev 25071)
@@ -308,8 +308,6 @@
         if (sealedObject != null)
         {
             message.getContext().setContext(SecurityService.CONTEXT, sealedObject);
-            // clear the security context from the thread local.
-            SecurityContext.setSecurityContext(null);
         }
         /*
          * Re-attach encrypted AuthenticationRequest to outgoing message.
@@ -318,95 +316,98 @@
         if (encryptedAuthRequest != null)
         {
             message.getContext().setContext(SecurityService.AUTH_REQUEST, encryptedAuthRequest);
-            // clear the auth request from the thread local.
-            AuthenticationRequestImpl.setEncryptedAuthRequest(null);
         }
 
-        //We are removing dead EPRs from the serviceClusterInfo. *Previous* deliveries maybe have
-        //removed EPRs that have now come back to life. We should try once more to pull a fresh list of EPRS
-        //from the registry before we give up (and fail-over to redelivery at a later time in the care
-        //of asyncDeliver). I think the end-user expects the message to be delivered successfully if there
-        //is a healthy EPR out there. So this is really for EPR cache management (serviceClusterInfo will
-        //be empty when going for the 2nd attempt, or else there delivery was successful and there will be
-        //no second attempt!).
-        while (staleEPRCache) {
-            if ((serviceClusterInfo.getEPRs().size() == 0) || (new Date().after(expirationDate))) {
-                loadServiceClusterInfo();
-
-                if (initialPass && (serviceClusterInfo.getEPRs().size() == 0)) // zero from a previous send
-                {
-                	/*
-                	 * We need to check to see if this instance used up all of it's attempts to deliver
-                	 * in a previous deliver or we'll only refresh the cache once per subsequent send
-                	 * because we will have exhausted the EPRs in the cache, i.e., size==0.
-                	 *
-                	 * When the instance is originally created we do an initial cache fetch. Until this
-                	 * check, that cache fetch was not being done again after a complete failure. Unlikely
-                	 * to cause problems anyway, but possible.
-                	 */
-                	initialPass = false;
+        try {
+            //We are removing dead EPRs from the serviceClusterInfo. *Previous* deliveries maybe have
+            //removed EPRs that have now come back to life. We should try once more to pull a fresh list of EPRS
+            //from the registry before we give up (and fail-over to redelivery at a later time in the care
+            //of asyncDeliver). I think the end-user expects the message to be delivered successfully if there
+            //is a healthy EPR out there. So this is really for EPR cache management (serviceClusterInfo will
+            //be empty when going for the 2nd attempt, or else there delivery was successful and there will be
+            //no second attempt!).
+            while (staleEPRCache) {
+                if ((serviceClusterInfo.getEPRs().size() == 0) || (new Date().after(expirationDate))) {
+                    loadServiceClusterInfo();
+    
+                    if (initialPass && (serviceClusterInfo.getEPRs().size() == 0)) // zero from a previous send
+                    {
+                    	/*
+                    	 * We need to check to see if this instance used up all of it's attempts to deliver
+                    	 * in a previous deliver or we'll only refresh the cache once per subsequent send
+                    	 * because we will have exhausted the EPRs in the cache, i.e., size==0.
+                    	 *
+                    	 * When the instance is originally created we do an initial cache fetch. Until this
+                    	 * check, that cache fetch was not being done again after a complete failure. Unlikely
+                    	 * to cause problems anyway, but possible.
+                    	 */
+                    	initialPass = false;
+                    }
+                    else
+                    	staleEPRCache = false;
                 }
-                else
-                	staleEPRCache = false;
-            }
-            Message replyMessage;
-            EPR epr;
-            // Iterate over all the EPRs in the list until delivered
-            while ((epr = loadBalancer.chooseEPR(serviceClusterInfo)) != null) {
-            	try
-            	{
-	                replyMessage = eprInvoker.attemptDelivery(message, epr);
-	                if (replyMessage != null) {
-                        if(eprInvoker.synchronous) {
-                            // remove the security context so that it is not exposed to the action pipeline.
-                            replyMessage.getContext().removeContext(SecurityService.CONTEXT);
-                            replyMessage.getContext().removeContext(SecurityService.AUTH_REQUEST);
-
-                            if (Type.isFaultMessage(replyMessage)) {
-                                Factory.createExceptionFromFault(replyMessage) ;
+                Message replyMessage;
+                EPR epr;
+                // Iterate over all the EPRs in the list until delivered
+                while ((epr = loadBalancer.chooseEPR(serviceClusterInfo)) != null) {
+                	try
+                	{
+    	                replyMessage = eprInvoker.attemptDelivery(message, epr);
+    	                if (replyMessage != null) {
+                            if(eprInvoker.synchronous) {
+                                // remove the security context so that it is not exposed to the action pipeline.
+                                replyMessage.getContext().removeContext(SecurityService.CONTEXT);
+                                replyMessage.getContext().removeContext(SecurityService.AUTH_REQUEST);
+    
+                                if (Type.isFaultMessage(replyMessage)) {
+                                    Factory.createExceptionFromFault(replyMessage) ;
+                                }
+    
+                                // We've delivered it, we're done!
+                                return replyMessage;
+                            } else {
+                                // It was an async delivery.  The replyMessage was just an indicator that
+                                // the delivery succeeded.  Return null...
+                                return null;
                             }
-
-                            // We've delivered it, we're done!
-                            return replyMessage;
                         } else {
-                            // It was an async delivery.  The replyMessage was just an indicator that
-                            // the delivery succeeded.  Return null...
-                            return null;
-                        }
-                    } else {
-	                    logger.info("Unresponsive EPR: " + epr+" for message: "+message.getHeader());
-
-	                    serviceClusterInfo.removeDeadEPR(epr);
-
-	                    /*
-	                     * So far we've only removed the EPR from the cache. Should we
-	                     * also remove it from the registry?
-	                     */
-
-	                    if (removeDeadEprs)
-	                    	RegistryUtil.unregister(service.getCategory(), service.getName(), epr);
-
-	                    /*
-	                     * If the message property is set to fail immediately, or the global property is set,
-	                     * then don't do retries even if there are other EPRs in the list.
-	                     */
-
-	                    if (("true".equals(message.getProperties().getProperty(Environment.EXCEPTION_ON_DELIVERY_FAILURE, "false")) || exceptionOnDeliveryFailure))
-	                	throw new MessageDeliverException("Failed to deliver message ["+message.getHeader()+"] to Service [" + service + "].  Told not to retry.");
-	                }
-            	}
-            	catch (MalformedEPRException ex)  // so we can differentiate failure modes, since returning null is limiting
-            	{
-            		logger.debug("Invalid EPR for service (probably ESB-unaware): ignoring for message: "+message.getHeader());
-
-            		serviceClusterInfo.removeDeadEPR(epr);
-
-            		/*
-            		 * DO NOT remove from the registry - it is not dead!!
-            		 */
-            	}
-
+    	                    logger.info("Unresponsive EPR: " + epr+" for message: "+message.getHeader());
+    
+    	                    serviceClusterInfo.removeDeadEPR(epr);
+    
+    	                    /*
+    	                     * So far we've only removed the EPR from the cache. Should we
+    	                     * also remove it from the registry?
+    	                     */
+    
+    	                    if (removeDeadEprs)
+    	                    	RegistryUtil.unregister(service.getCategory(), service.getName(), epr);
+    
+    	                    /*
+    	                     * If the message property is set to fail immediately, or the global property is set,
+    	                     * then don't do retries even if there are other EPRs in the list.
+    	                     */
+    
+    	                    if (("true".equals(message.getProperties().getProperty(Environment.EXCEPTION_ON_DELIVERY_FAILURE, "false")) || exceptionOnDeliveryFailure))
+    	                	throw new MessageDeliverException("Failed to deliver message ["+message.getHeader()+"] to Service [" + service + "].  Told not to retry.");
+    	                }
+                	}
+                	catch (MalformedEPRException ex)  // so we can differentiate failure modes, since returning null is limiting
+                	{
+                		logger.debug("Invalid EPR for service (probably ESB-unaware): ignoring for message: "+message.getHeader());
+    
+                		serviceClusterInfo.removeDeadEPR(epr);
+    
+                		/*
+                		 * DO NOT remove from the registry - it is not dead!!
+                		 */
+                	}
+    
+                }
             }
+        } finally {
+            message.getContext().removeContext(SecurityService.CONTEXT);
+            message.getContext().removeContext(SecurityService.AUTH_REQUEST);
         }
 
         // Throw exception if delivery failed...

Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java	2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java	2009-02-03 11:33:05 UTC (rev 25071)
@@ -77,7 +77,7 @@
         URI targetURI = getTargetURI(properties, true);
         String factory;
         String scheme = targetURI.getScheme();
-        int port = 80; //default to http;
+        final int port ;
         org.apache.commons.httpclient.protocol.Protocol protocol;
         KeyMaterial keyMaterial = null;
         ProtocolSocketFactory socketFactory;
@@ -92,12 +92,12 @@
             keyMaterial = getKeyMaterial(properties);
             setHttpsProxyHost(httpClient, properties);
 
-            if(port == -1) {
-                port = 443;
-            }
+            port = 443;
         } else {
             factory = properties.getProperty("protocol-socket-factory", DefaultProtocolSocketFactory.class.getName());
             setHttpProxyHost(httpClient, properties);
+
+            port = 80;
         }
         assertPropertySetAndNotBlank(factory, "protocol-socket-factory");
         socketFactory = createFactoryClass(factory, keyMaterial, properties);

Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java	2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java	2009-02-03 11:33:05 UTC (rev 25071)
@@ -32,6 +32,7 @@
 import javax.crypto.SealedObject;
 import javax.security.auth.Subject;
 
+import org.apache.log4j.Logger;
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
 import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
 import org.jboss.soa.esb.common.Configuration;
@@ -61,8 +62,17 @@
 	private static final long serialVersionUID = 1L;
 
 	private static transient ThreadLocal<SealedObject> securityContextTl = new ThreadLocal<SealedObject>();
+	
+	/**
+	 * Logger instance.
+	 */
+	private static final Logger LOGGER = Logger.getLogger(SecurityConfig.class) ;
+	/**
+	 * default timeout value if not set.
+	 */
+	private static final long DEFAULT_TIMEOUT_VALUE = 30000 ;
 
-	private static long globalConfiguredTimeout;
+	private static final long globalConfiguredTimeout = getGlobalConfigurationTimeout() ;
 
 	/**
 	 * The Subject associated with this context.
@@ -72,7 +82,7 @@
     /**
      * Timeout (ms) for the security context. Defaults to 5 mins.
      */
-    private long timeout = 30000;
+    private final long timeout ;
 
     /**
      * Time of creation.
@@ -80,9 +90,26 @@
     private long timeOfCreation = System.currentTimeMillis();
 
 	/**
+	 * Creates a SecurityContext with a default Subject.
+	 */
+	public SecurityContext()
+	{
+		this(new Subject()) ;
+	}
+	
+	/**
 	 * Creates a SecurityContext associating the passed in Subject with it.
 	 *
 	 * @param subject The Subject that is to be associated with this security context.
+	 */
+	public SecurityContext(final Subject subject)
+	{
+		this(subject, globalConfiguredTimeout) ;
+	}
+	/**
+	 * Creates a SecurityContext associating the passed in Subject with it.
+	 *
+	 * @param subject The Subject that is to be associated with this security context.
 	 * @param timeout A timeout which specifies how long this Security Context is valid for. Must be a positiv value.
 	 */
 	public SecurityContext(final Subject subject, final long timeout)
@@ -230,15 +257,11 @@
 
     /**
      * Get the globally configured security context timeout.
-     * @return
+     * @return the configuration context timeout
      * @throws SecurityServiceException
      */
     public static long getConfigurationTimeout() throws SecurityServiceException
     {
-        if (globalConfiguredTimeout == 0l)
-        {
-            globalConfiguredTimeout = getGlobalConfigurationTimeout();
-        }
         return globalConfiguredTimeout;
     }
 
@@ -252,12 +275,16 @@
         return SecurityContext.securityContextTl.get();
     }
 
-    private static long getGlobalConfigurationTimeout() throws SecurityServiceException
+    private static long getGlobalConfigurationTimeout()
     {
         final String timeoutStr = Configuration.getSecurityServiceContextTimeout();
         if (timeoutStr == null)
         {
-            throw new SecurityServiceException("No timeout was configured for the security context. Please set the value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' to the timeout you desire");
+            if (LOGGER.isDebugEnabled())
+            {
+                LOGGER.debug("No timeout was configured for the security context, using the default value. Please set the value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' to the timeout you desire");
+            }
+            return DEFAULT_TIMEOUT_VALUE ;
         }
         else
         {
@@ -267,7 +294,8 @@
            }
            catch(final NumberFormatException e)
            {
-                throw new SecurityServiceException("The value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' must be specified as a long");
+               LOGGER.warn("The value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' is invalid, using default value") ;
+               return DEFAULT_TIMEOUT_VALUE ;
            }
         }
     }

Copied: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java (from rev 25025, labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java)
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java	2009-02-03 11:33:05 UTC (rev 25071)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * 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.soa.esb.services.security;
+
+import java.util.Properties;
+
+import javax.crypto.SealedObject;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertNull;
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.internal.soa.esb.couriers.MockCourier;
+import org.jboss.internal.soa.esb.couriers.MockCourierFactory;
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.soa.esb.addressing.MalformedEPRException;
+import org.jboss.soa.esb.client.ServiceInvoker;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.couriers.CourierException;
+import org.jboss.soa.esb.message.ByReferenceMessage;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.services.security.auth.AuthenticationRequestImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for security propagation.
+ * 
+ * @author <a href="mailto:Kevin.Conner at jboss.com">Kevin Conner</a>
+ */
+public class SecurityPropagationUnitTest
+{
+    private Properties props ;
+
+    @Before
+    public void setup()
+    {
+        props = System.getProperties() ;
+        final Properties newProps = new Properties(props) ;
+        newProps.setProperty(Environment.SECURITY_SERVICE_SEAL_ALGORITHM, "TripleDES") ;
+        newProps.setProperty(Environment.SECURITY_SERVICE_SEAL_KEYSIZE, "168") ;
+        System.setProperties(newProps) ;
+        MockCourierFactory.install() ;
+        MockRegistry.install() ;
+    }
+
+    @After
+    public void tearDown()
+    {
+        MockRegistry.uninstall() ;
+        MockCourierFactory.uninstall() ;
+        System.setProperties(props) ;
+    }
+
+    @Test
+    public void securityContextPropagation()
+        throws Exception
+    {
+        final String category = "test" ;
+        final String service = "securityContextPropagation" ;
+        final MockCourier mockCourier = new PropagationMockCourier() ;
+        MockRegistry.register(category, service, mockCourier) ;
+        
+        final ServiceInvoker si = new ServiceInvoker(category, service) ;
+        final Message message = MessageFactory.getInstance().getMessage() ;
+        
+        assertNull("securityContext", SecurityContext.getSecurityContext()) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        
+        final SealedObject securityContext = SecurityContext.encryptContext(new SecurityContext()) ;
+        SecurityContext.setSecurityContext(securityContext) ;
+        
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+        
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+        
+        mockCourier.reset();
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+    }
+
+    @Test
+    public void authenticationRequestPropagation()
+        throws Exception
+    {
+        final String category = "test" ;
+        final String service = "authenticationRequestPropagation" ;
+        final MockCourier mockCourier = new PropagationMockCourier() ;
+        MockRegistry.register(category, service, mockCourier) ;
+        
+        final ServiceInvoker si = new ServiceInvoker(category, service) ;
+        final Message message = MessageFactory.getInstance().getMessage() ;
+        
+        assertNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        
+        final byte[] authenticationRequest = new byte[0] ;
+        AuthenticationRequestImpl.setEncryptedAuthRequest(authenticationRequest) ;
+        
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        
+        mockCourier.reset();
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+    }
+
+    private static final class PropagationMockCourier extends MockCourier
+    {
+        PropagationMockCourier()
+        {
+            super(true) ;
+        }
+        
+        @Override
+        public boolean deliver(final Message message)
+            throws CourierException, MalformedEPRException
+        {
+            return super.deliver(((ByReferenceMessage)message).reference());
+        }
+    }
+    
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(SecurityPropagationUnitTest.class);
+    }
+}




More information about the jboss-svn-commits mailing list