Package org.jboss.test.deployment.test

Source Code of org.jboss.test.deployment.test.DeploymentServiceUnitTestCase

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, 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.test.deployment.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.sql.Connection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Properties;

import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.services.deployment.MBeanData;
import org.jboss.test.JBossTestCase;

/**
* DeploymentService tests
*
* @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis </a>
* @author <a href="mailto:peter.johnson2@unisys.com">Peter Johnson </a>
* @version $Revision: 104649 $
*/
public class DeploymentServiceUnitTestCase extends JBossTestCase
{
   private ObjectName deploymentService = ObjectNameFactory
         .create("jboss:service=DeploymentService");

   private ObjectName mainDeployer = ObjectNameFactory
         .create("jboss.system:service=MainDeployer");

   public DeploymentServiceUnitTestCase(String name)
   {
      super(name);
   }

   /**
    * Check if I can get the available templates
    */
   public void testListModuleTemplates() throws Exception
   {
      log.info("+++ testListModuleTemplates");
      MBeanServerConnection server = getServer();
      try
      {
         boolean isRegistered = server.isRegistered(deploymentService);
         assertTrue(deploymentService + " is registered", isRegistered);
         log.info("Loaded templates: "
               + server.invoke(deploymentService, "listModuleTemplates",
                     new Object[] {}, new String[] {}));
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to create, remove and re-create a jms topic (don't deploy)
    */
   public void testCreateAndRemoveAndCreateTopic() throws Exception
   {
      log.info("+++ testCreateAndRemoveAndCreateTopic");
      try
      {
         String module = "testTopic1-service.xml";

         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("TopicName", "testTopic1"); // the topic name (mandatory)
         props.put("InMemory", new Boolean(true)); // set this to true to
         // persist the topic in
         // memory
         props.put("MaxDepth", new Integer(5)); // set the MaxDepth property
         // to 5

         String template = "jms-topic";

         // Create a topic destination module, in case of any problem an
         // exception will be thrown
         module = createModule(module, template, props);

         // remove the module
         removeModule(module);

         // Re-create the topic destination module with the same module name.
         // In case of any problem an exception will be thrown
         module = createModule(module, template, props);
      }
      catch (Exception e)
      {
         super.fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to create a no-tx-datasource (don't deploy)
    */
   public void testCreateNoTxDataSource() throws Exception
   {
      log.info("+++ testCreateNoTxDataSource");
      try
      {
         String module = "test-no-tx-hsqldb-ds.xml";

         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", "TestNoTxDataSource");
         props.put("connection-url", "jdbc:hsqldb:hsql://localhost:1701");
         props.put("driver-class", "org.hsqldb.jdbcDriver");

         // Add some fake connection properties
         Hashtable ht = new Hashtable();
         ht.put("property1", "someString");
         ht.put("property2", new Boolean(true));
         ht.put("property3", new Integer(666));
         props.put("connection-properties", ht);

         props.put("user-name", "sa");
         props.put("password", "");

         props.put("min-pool-size", new Integer(5));
         props.put("max-pool-size", new Integer(20));
         props.put("track-statements", "NOWARN");
         props.put("security-config", "APPLICATION-MANAGED-SECURITY");
         props.put("type-mapping", "Hypersonic SQL");
         props.put("dependencies", new ObjectName[] { new ObjectName(
               "jboss:service=Hypersonic") });

         String template = "no-tx-datasource";

         // In case of any problem an exception will be thrown
         module = createModule(module, template, props);
      }
      catch (Exception e)
      {
         super.fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to create an xa-datasource (don't deploy)
    */
   public void testCreateXaDataSource() throws Exception
   {
      log.info("+++ testCreateXaDataSource");
      try
      {
         String module = "test-xa-oracle-ds.xml";

         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", "TestOracleXaDataSource");
         props.put("track-connection-by-tx", new Boolean(true));
         props.put("is-same-RM-override-value", new Boolean(false));
         props.put("xa-datasource-class",
               "oracle.jdbc.xa.client.OracleXADataSource");

         // Add some xa-datasource-properties
         Hashtable ht = new Hashtable();
         ht.put("URL", "jdbc:oracle:oci8:@tc");
         ht.put("User", "scott");
         ht.put("Password", "tiger");
         props.put("xa-datasource-properties", ht);

         props.put("exception-sorter-class-name",
               "org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter");
         props.put("no-tx-separate-pools", new Boolean(true));
         props.put("type-mapping", "Oracle9i");

         String template = "xa-datasource";

         // In case of any problem an exception will be thrown
         module = createModule(module, template, props);
      }
      catch (Exception e)
      {
         super.fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to create and deploy a local-tx-datasource
    */
   public void testCreateAndDeployLocalTxDataSource() throws Exception
   {
      log.info("+++ testCreateAndDeployLocalTxDataSource");
      try
      {
         String module = "test-local-tx-hsqldb-ds.xml";
         String jndiName = "TestLocalTxHsqlDataSource";

         // undeploye module in case it's deployed
         undeployModule(module);
         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", jndiName); // use a name other than default
         props.put("use-java-context", new Boolean(false)); // set this to
         // false to allow
         // remote lookup
         props.put("connection-url", "jdbc:hsqldb:hsql://localhost:1701"); // using
         // hsqldb
         props.put("driver-class", "org.hsqldb.jdbcDriver");
         props.put("user-name", "sa");
         props.put("password", "");
         props.put("min-pool-size", new Integer(5));
         props.put("max-pool-size", new Integer(20));
         props.put("idle-timeout-minutes", new Integer(0));
         props.put("track-statements", "TRUE");
         props.put("security-config", "APPLICATION-MANAGED-SECURITY");
         props.put("type-mapping", "Hypersonic SQL");
         props.put("dependencies", new ObjectName[] { new ObjectName(
               "jboss:service=Hypersonic") });

         String template = "local-tx-datasource";

         // In case of any problem an exception will be thrown
         module = createModule(module, template, props);

         boolean isDeployed = deployModule(module);

         // was deployment succesful?
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // see if we can get a connection
         InitialContext ic = new InitialContext();
         DataSource ds = (DataSource) ic.lookup(jndiName);
         Connection connection = ds.getConnection();
         connection.close();

         // undeploy module
         undeployModule(module);
         // remove module
         removeModule(module);

         // regenerate with wrong usename
         props.put("user-name", "rogue-admin");
         module = createModule(module, template, props);

         // deploy again
         isDeployed = deployModule(module);

         // was deployment succesful?
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // lookup the datasource again and see if we can get a connection
         // it should fail this time
         try
         {
            ds = (DataSource) ic.lookup(jndiName);
            connection = ds.getConnection();
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // ok
         }
         // undeploy module
         undeployModule(module);
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to update an mbean with a standard set of properties. In this case,
    * the mbean name is bad and an error should be returned from the deployment
    * service.
    */
   public void testUpdateMBeanBadName() throws Exception
   {
      log.info("+++ testUpdateMBeanBadName");

      // Establish the property values
      Properties attrs = new Properties();
      attrs.put("Attr1", "aaaaa");
      attrs.put("Attr2", "bbbbb");
      ;

      // Set up the MBean configuration bean:
      MBeanData data = new MBeanData();
      data.setTemplateName("mbean-update");
      data.setAttributes(attrs);

      // Try with a null mbean name:
      try
      {
         data.setName(null);
         updateMBean(data);
         String msg = "Unexpectedly found mbean with invalid name: " + data;
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }

      // Try with an empty mbean name:
      try
      {
         data.setName("");
         updateMBean(data);
         String msg = "Unexpectedly found mbean with invalid name: " + data;
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }

      // Try with an unknown mbean name:
      try
      {
         data.setName("jboss.xxx:service=NoneSuch");
         updateMBean(data);
         String msg = "Unexpectedly found mbean with name: " + data;
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }

      // Try with an unknown mbean name with multiple attributes::
      try
      {
         data.setName("jboss.xxx:service=NoneSuch,type=Unknown,Alias=whatever");
         updateMBean(data);
         String msg = "Unexpectedly found mbean with name: " + data;
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }
   }

   /**
    * Try to update an mbean with a standard set of properties. In this case, no
    * template is given for doing the update. The update should fail.
    */
   public void testUpdateMBeanBadTemplate() throws Exception
   {
      log.info("+++ testUpdateMBeanBadTemplate");

      // Establish the property values
      Properties attrs = new Properties();
      attrs.put("Attr1", "aaaaa");
      attrs.put("Attr2", "bbbbb");
      ;

      // Set up the MBean configuration bean:
      MBeanData data = new MBeanData();
      data.setName("jboss.mq:service=MessageCache");
      data.setAttributes(attrs);

      // Try with a null template name:
      try
      {
         data.setTemplateName(null);
         log.info("Template=" + data.getTemplateName());
         updateMBean(data);
         String msg = "Update was successful with null template name: "
               + data.getTemplateName();
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }

      // Try again, but with an empty template name:
      try
      {
         data.setTemplateName("");
         log.info("Template=" + data.getTemplateName());
         updateMBean(data);
         String msg = "Update was successful with empty template name "
               + data.getTemplateName();
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }

      // Try again, but with an unknown template name:
      try
      {
         data.setTemplateName("nonesuch");
         log.info("Template=" + data.getTemplateName());
         updateMBean(data);
         String msg = "Update was successful with null template "
               + data.getTemplateName();
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }
   }

   /**
    * Try to update an mbean with a standard set of properties. In this case,
    * the mbean attributes are bad. The update should succeed.
    */
   public void testUpdateMBeanBadAttributes() throws Exception
   {
      log.info("+++ testUpdateMBeanBadAttributes");

      // Set up the MBean configuration bean:
      MBeanData data = new MBeanData();
      data.setName("jboss.mq:service=MessageCache");
      data.setTemplateName("mbean-update");
      data.setAttributes(null);

      // Update the mbean
      boolean result = updateMBean(data);
      // Yes, I could have used assertTrue, but I want to log all errors:
      if (result)
      {
         log.info("passed");
      }
      else
      {
         String msg = "Failed to update mbean when attributes were null: "
               + data;
         log.error(msg);
         fail(msg);
      }
   }

   /**
    * Try to update an mbean with a standard set of properties. In this case,
    * the mbean data is bad. The update should fail.
    */
   public void testUpdateMBeanBadData() throws Exception
   {
      log.info("+++ testUpdateMBeanBadData");

      // Attempt to update the mbean with no data
      try
      {
         updateMBean(null);
         String msg = "Update was successful with null data";
         log.error(msg);
         fail(msg);
      }
      catch (MBeanException e)
      {
         // expected
         log.info("passed");
      }
   }

   /**
    * Try to update an mbean with a standard set of properties. The mbean we use
    * is the MessageCache mbean for the messaging service. The mbean properties
    * are changed to innocuous values that should cause no problems. This test
    * might have to be updated when the new messing service is rolled out.
    */
   public void testUpdateMBeanStandard() throws Exception
   {
      log.info("+++ testUpdateMBeanStandard");

      // Establish the property values
      String value = "999";
      Properties attrs = new Properties();
      attrs.put("MaxMemoryMark", value);
      attrs.put("HighMemoryMark", value);
      attrs.put("CacheStore", "jboss.mq:service=PersistenceManager");
      attrs.put("MaximumHard", value);
      attrs.put("MinimumHard", value);
      attrs.put("SoftenAtLeastEveryMillis", value);
      attrs.put("SoftenNoMoreOftenThanMillis", value);
      attrs.put("MakeSoftReferences", "true");
      // For some reason, the following value is rounded up to 1000 if set to
      // 999, so we will use 1000 as the value:
      attrs.put("SoftenWaitMillis", "1000");

      // Set up the MBean configuration bean:
      MBeanData data = new MBeanData();
      String name = "jboss.mq:service=MessageCache";
      data.setName(name);
      data.setTemplateName("mbean-update");
      data.setAttributes(attrs);

      // Update and verify the mbean:
      boolean result = updateMBean(data);
      // Yes, I could have used assertTrue, but I want to log all errors:
      if (!result)
      {
         String msg = "Failed to update mbean " + data;
         log.error(msg);
         fail(msg);
      }
      verifyMBean(data, null);
   }

   /**
    * Try to update an mbean where one of the properties has a value expressed
    * as a nested XML property rather than as simple text. The mbean we use is
    * the SecurityManager mbean for the messaging service. The mbean property
    * that is of interest is the DefaultSecurityConfig. This test might have to
    * be updated when the new messing service is rolled out.
    */
   public void testUpdateMBeanNested() throws Exception
   {
      log.info("+++ testUpdateMBeanNested");

      // Establish the property values
      Properties attrs = new Properties();
      String nestedAttr = "DefaultSecurityConfig";
      attrs
            .put(
                  nestedAttr,
                  "<security><role name=\"guest\" read=\"true\" write=\"false\" create=\"false\"/></security>");
      attrs.put("SecurityDomain", "java:/jaas/jbossmq");

      // Establish the dependency values
      Properties depends = new Properties();
      depends.put("NextInterceptor", "jboss.mq:service=DestinationManager");

      // Set up the MBean configuration bean:
      MBeanData data = new MBeanData();
      String name = "jboss.mq:service=SecurityManager";
      data.setName(name);
      data.setTemplateName("mbean-update");
      data.setAttributes(attrs);
      data.setDepends(depends);

      // Update and verify the mbean:
      boolean result = updateMBean(data);
      // Yes, I could have used assertTrue, but I want to log all errors:
      if (!result)
      {
         String msg = "Failed to update mbean " + data;
         log.error(msg);
         fail(msg);
      }
      verifyMBean(data, nestedAttr);
   }

   /**
    * Try to update an mbean that has a name with multiple attributes. We will
    * update the mbean twice, each time presenting the name attributes in a
    * different order. We will use one of the InvocationLayer mbeans from the
    * uil2-service.xml file.
    */
   public void testUpdateMBeanXpath() throws Exception
   {
      log.info("+++ testUpdateMBeanXpath");

      // Establish the property values
      Properties attrs = new Properties();
      attrs.put("FromName", "XXXXXXXXX");
      attrs.put("ToName", "AAAAAAAAAA");

      // Establish the dependency values
      Properties depends = new Properties();
      depends.put("", "jboss:service=Naming");

      // Set up the MBean configuration bean, this time with the attributes
      // in the order in which they appear when asking the mbean for the name
      MBeanData data = new MBeanData();
      data
            .setName("jboss.mq:alias=UIL2XAConnectionFactory,service=InvocationLayer,type=UIL2XA");
      data.setTemplateName("mbean-update");
      data.setAttributes(attrs);
      data.setDepends(depends);

      // Update and verify the mbean:
      if (!updateMBean(data))
      {
         String msg = "Failed to update mbean: " + data;
         log.error(msg);
         fail(msg);
      }
      verifyMBean(data, null);

      // Try again, but with the name attributes in a different order. This
      // time in the order in which they appear in the xml file:
      attrs = new Properties();
      attrs.put("FromName", "RRRRRRRRRRR");
      attrs.put("ToName", "QQQQQQQQQQQQQ");
      data
            .setName("jboss.mq:service=InvocationLayer,type=UIL2XA,alias=UIL2XAConnectionFactory");
      data.setAttributes(attrs);

      // Update and verify the mbean:
      if (!updateMBean(data))
      {
         String msg = "Failed to update mbean: " + data;
         log.error(msg);
         fail(msg);
      }
      verifyMBean(data, null);

      // Try again, but with the name attributes in another order. This
      // time in the order is different that the mbean name or xml file:
      attrs = new Properties();
      attrs.put("FromName", "LLLLLLLLLLLL");
      attrs.put("ToName", "KKKKKKKKKKKK");
      data
            .setName("jboss.mq:type=UIL2XA,alias=UIL2XAConnectionFactory,service=InvocationLayer");
      data.setAttributes(attrs);

      // Update and verify the mbean:
      if (!updateMBean(data))
      {
         String msg = "Failed to update mbean: " + data;
         log.error(msg);
         fail(msg);
      }
      verifyMBean(data, null);
   }

   /**
    * Try to update a local transaction data source. This test case uses the
    * DefaultDS data source.
    */
   public void testUpdateDataSourceLocal() throws Exception
   {
      log.info("+++ testUpdateDataSourceLocal");

      try
      {
         String jndiName = "DefaultDS";

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", jndiName);
         props.put("use-java-context", new Boolean(false)); // set this to
         // false to allow
         // remote lookup
         props.put("connection-url", "jdbc:hsqldb:hsql://localhost:1701"); // using
         // hsqldb
         props.put("driver-class", "org.hsqldb.jdbcDriver");
         props.put("user-name", "sa");
         props.put("password", "");
         props.put("min-pool-size", new Integer(9));
         props.put("max-pool-size", new Integer(99));
         props.put("idle-timeout-minutes", new Integer(99));
         props.put("track-statements", "TRUE");
         props.put("security-config", "APPLICATION-MANAGED-SECURITY");
         props.put("type-mapping", "Hypersonic SQL");
         props.put("dependencies", new ObjectName[] { new ObjectName(
               "jboss:service=Hypersonic") });

         String template = "local-tx-datasource";

         // In case of any problem an exception will be thrown
         boolean isDeployed = updateDataSource("hsqldb-ds.xml", template, props);
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // see if we can get a connection
         boolean connected = connectToDataSource(jndiName);
         assertTrue("Data source " + jndiName + " connected successful : "
               + connected, connected);

         // Try with the other module name
         isDeployed = updateDataSource("hsqldb", template, props);
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // see if we can get a connection
         connected = connectToDataSource(jndiName);
         assertTrue("Data source " + jndiName + " connected successful : "
               + connected, connected);

         log.info("passed");
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to update a no transaction data source. This test case uses the data
    * source created by testCreateNoTxDataSource. This test is hidden for now,
    * the test-no-tx-hsqldb data source is never deployed and is thus not
    * visible.
    */
   public void hide_testUpdateDataSourceNo() throws Exception
   {
      log.info("+++ testUpdateDataSourceNo");

      try
      {

         String module = "test-no-tx-hsqldb-ds.xml";

         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", "TestNoTxDataSource");
         props.put("connection-url", "jdbc:hsqldb:hsql://localhost:1701");
         props.put("driver-class", "org.hsqldb.jdbcDriver");

         // Add some fake connection properties
         Hashtable ht = new Hashtable();
         ht.put("property1", "someString");
         ht.put("property2", new Boolean(true));
         ht.put("property3", new Integer(666));
         props.put("connection-properties", ht);

         props.put("user-name", "sa");
         props.put("password", "");

         props.put("min-pool-size", new Integer(5));
         props.put("max-pool-size", new Integer(20));
         props.put("track-statements", "NOWARN");
         props.put("security-config", "APPLICATION-MANAGED-SECURITY");
         props.put("type-mapping", "Hypersonic SQL");
         props.put("dependencies", new ObjectName[] { new ObjectName(
               "jboss:service=Hypersonic,") });

         String template = "no-tx-datasource";

         // In case of any problem an exception will be thrown
         boolean isDeployed = updateDataSource(module, template, props);
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // We don't try to get a connection because the original
         // data source was never deployed.

         log.info("passed");
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to update an XA transaction data source. This test case uses the data
    * source created by testCreateXaDataSource. This test is hidden for now, the
    * test-xa-oracle data source is never deployed and is thus not visible.
    */
   public void hide_testUpdateDataSourceXa() throws Exception
   {
      log.info("+++ testUpdateDataSourceNo");

      try
      {
         String module = "test-xa-oracle-ds.xml";

         // remove module in case it exists
         removeModule(module);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", "TestOracleXaDataSource");
         props.put("track-connection-by-tx", new Boolean(true));
         props.put("is-same-RM-override-value", new Boolean(false));
         props.put("xa-datasource-class",
               "oracle.jdbc.xa.client.OracleXADataSource");

         // Add some xa-datasource-properties
         Hashtable ht = new Hashtable();
         ht.put("URL", "jdbc:oracle:oci8:@tc");
         ht.put("User", "scott");
         ht.put("Password", "tiger");
         props.put("xa-datasource-properties", ht);

         props.put("exception-sorter-class-name",
               "org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter");
         props.put("no-tx-separate-pools", new Boolean(true));
         props.put("type-mapping", "Oracle9i");

         String template = "xa-datasource";

         // In case of any problem an exception will be thrown
         boolean isDeployed = updateDataSource(module, template, props);
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // We don't try to get a connection because the original
         // data source was never deployed.

         log.info("passed");
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
      finally
      {
         // empty
      }
   }

   /**
    * Try to remove a data source using the removeDataSource() method. This test
    * case uses the "TestLocalTxHsqlDataSource" created by
    * testCreateAndDeployLocalTxDataSource().
    *
    * Note that the "TestLocalTxHsqlDataSource" will be removed from the
    * test-local-tx-hsqldb-ds.xml file, thus further reference to this data
    * source may be in-appropriate.
    */
   public void testRemoveDataSource() throws Exception
   {
      log.info("+++ testRemoveDataSource");

      try
      {

         String module = "test-local-tx-hsqldb-ds.xml";
         String jndiName = "TestLocalTxHsqlDataSource";

         // Deploy the module
         boolean isDeployed = deployModule(module);

         // Was deployment succesful?
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // Prepare the template properties
         HashMap props = new HashMap();
         props.put("jndi-name", jndiName);

         String template = "datasource-remove";

         // In case of any problem an exception will be thrown
         isDeployed = removeDataSource(module, template, props);

         // The module should be deployed
         assertTrue("removed successful : " + isDeployed, isDeployed);

         // But we should NOT be able to get a connection
         try
         {
            InitialContext ic = new InitialContext();
            DataSource ds = (DataSource) ic.lookup(jndiName);
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // Ok, undeploy the module
            undeployModule(module);
         }

         log.info("passed");
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
   }

   /**
    * Try to remove a data source using the removeDataSource() method from a
    * module with multiple data sources configured. This test case uses the
    * testMultipleDataSources-ds.xml module located under the
    * "testsuite/src/etc/deployment-test" directory.
    */
   public void testRemoveDataSourceFromMultiNodesModule() throws Exception
   {
      log.info("+++ testRemoveDataSourceFromMultiNodesModule");

      try
      {
         String module = "testMultipleDataSources-ds.xml";
         String jndiName1 = "TestDataSource1";
         String jndiName2 = "TestDataSource2";
         String delim = File.separator;

         // Find the server directory
         MBeanServerConnection server = getServer();
         ObjectName serverConfig = new ObjectName(
               "jboss.system:type=ServerConfig");
         String serverHome = ((File) server.getAttribute(serverConfig,
               "ServerHomeDir")).getCanonicalPath();
         log.info("serverHome = " + serverHome);

         // Find the directory where the test module resides
         String myPath = new File("").getAbsolutePath();
         log.info("myPath = " + myPath);
         int inx = myPath.lastIndexOf(delim);
         if (inx >= 0)
            myPath = myPath.substring(0, myPath.lastIndexOf(delim));

         // Copy the module to the deploy directory
         String source = myPath + delim + "src" + delim + "etc" + delim
               + "deployment-test" + delim + module;
         String target = serverHome + delim + "deploy" + delim + module;
         log.info("source = " + source);
         log.info("target = " + target);

         FileChannel srcChannel = new FileInputStream(source).getChannel();
         FileChannel destChannel = new FileOutputStream(target).getChannel();
         srcChannel.transferTo(0, srcChannel.size(), destChannel);
         srcChannel.close();
         destChannel.close();

         // See if we can get connection to the data sources:
         boolean connected = connectToDataSource(jndiName1);
         assertTrue("Data source " + jndiName1 + " connected successful : "
               + connected, connected);
         connected = connectToDataSource(jndiName2);
         assertTrue("Data source " + jndiName2 + " connected successful : "
               + connected, connected);

         // Prepare the template properties for removing "TestDataSource1"
         HashMap props = new HashMap();
         props.put("jndi-name", jndiName1);

         String template = "datasource-remove";

         // In case of any problem an exception will be thrown
         boolean isDeployed = removeDataSource(module, template, props);

         // The module should be deployed
         assertTrue("removed successful : " + isDeployed, isDeployed);

         // We should be able to connect to TestDataSource2
         connected = connectToDataSource(jndiName2);
         assertTrue("Data source " + jndiName2 + " connected successful : "
               + connected, connected);

         // But we should NOT be able connect to TestDataSource1
         try
         {
            InitialContext ic = new InitialContext();
            DataSource ds1 = (DataSource) ic.lookup(jndiName1);
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // Ok, remove the file
            File targetFile = new File(target);
            targetFile.delete();

         }

         log.info("passed");
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
   }

   /**
    * Try to remove a data source using the removeDataSource() method. In this
    * case, the module name is bad and an error should be returned from the
    * deployment service.
    */
   public void testRemoveDataSourceBadModule() throws Exception
   {
      log.info("+++ testRemoveDataSourceBadModule");

      // Setup the data
      String module = null;
      String template = "datasource-remove";
      HashMap props = new HashMap();

      // Try with a null module name:
      try
      {
         removeDataSource(module, template, props);
         fail("Shouldn't reach this point");
      }
      catch (Exception e)
      {
         // expected
         log.info("passed");
      }

      // Try with an empty module name:
      try
      {
         module = "";
         removeDataSource(module, template, props);
         fail("Shouldn't reach this point");
      }
      catch (Exception e)
      {
         // expected
         log.info("passed");
      }

      // Try with an unknown module name:
      try
      {
         module = "unknoenModule";
         removeDataSource(module, template, props);
         fail("Shouldn't reach this point");
      }
      catch (Exception e)
      {
         // expected
         log.info("passed");
      }
   }

   /**
    * Try to remove a data source using the removeDataSource() method. In this
    * case, the template name is bad and an error should be returned from the
    * deployment service.
    */
   public void testRemoveDataSourceBadTemplate() throws Exception
   {
      log.info("+++ testRemoveDataSourceBadTemplate");

      try
      {
         String module = "test-local-tx-hsqldb-ds.xml";
         String template = null;
         HashMap props = new HashMap();

         // Deploy the module
         boolean isDeployed = deployModule(module);

         // Was deployment succesful?
         assertTrue("deployed successful : " + isDeployed, isDeployed);

         // Try with a null template name:
         try
         {
            removeDataSource(module, template, props);
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // expected
            log.info("passed");
         }

         // Try with an empty template name:
         try
         {
            template = "";
            removeDataSource(module, template, props);
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // expected
            log.info("passed");
         }

         // Try with an unknown template name:
         try
         {
            template = "unknownTemplate";
            removeDataSource(module, template, props);
            fail("Shouldn't reach this point");
         }
         catch (Exception e)
         {
            // expected
            log.info("passed");
         }

         // Undeploy the module:
         undeployModule(module);
      }
      catch (Exception e)
      {
         log.error("failed", e);
         fail("Caught exception, message: " + e.getMessage());
      }
   }

   private String createModule(String module, String template, HashMap props)
         throws Exception
   {
      MBeanServerConnection server = getServer();

      // create the module
      module = (String) server
            .invoke(deploymentService, "createModule", new Object[] { module,
                  template, props }, new String[] { "java.lang.String",
                  "java.lang.String", "java.util.HashMap" });

      log.info("Module '" + module + "' created: " + module);
      return module;
   }

   private boolean removeModule(String module) throws Exception
   {
      MBeanServerConnection server = getServer();

      // remove the module, in case it exists
      Boolean removed = (Boolean) server.invoke(deploymentService,
            "removeModule", new Object[] { module },
            new String[] { "java.lang.String" });

      log.info("Module '" + module + "' removed: " + removed);

      return removed.booleanValue();
   }

   private boolean deployModule(String module) throws Exception
   {
      MBeanServerConnection server = getServer();

      // Deploy the module (move to ./deploy)
      server.invoke(deploymentService, "deployModuleAsynch",
            new Object[] { module }, new String[] { "java.lang.String" });

      return verifyDeploy(server, module);
   }

   private boolean undeployModule(String module) throws Exception
   {
      MBeanServerConnection server = getServer();
      try
      {
         // Get the deployed URL
         URL deployedURL = (URL) server.invoke(deploymentService,
               "getDeployedURL", new Object[] { module },
               new String[] { "java.lang.String" });

         // Undeploy the module (move to ./undeploy)
         server.invoke(deploymentService, "undeployModuleAsynch",
               new Object[] { module }, new String[] { "java.lang.String" });

         // Ask the MainDeployer every 3 secs, 5 times (15secs max wait) if
         // the module was undeployed
         Boolean isDeployed = new Boolean(false);
         for (int tries = 0; tries < 5; tries++)
         {
            // sleep for 3 secs
            Thread.sleep(3000);
            isDeployed = (Boolean) server
                  .invoke(mainDeployer, "isDeployed",
                        new Object[] { deployedURL },
                        new String[] { "java.net.URL" });

            if (!isDeployed.booleanValue())
            {
               break;
            }
         }
         log.info("Module '" + module + "' deployed: " + isDeployed);
         return isDeployed.booleanValue();
      }
      catch (Exception e)
      {
         // the module does not exist
         log.info("Ignoring caught exception, message: " + e.getMessage());
         return false;
      }
   }

   /**
    * Proxy method that makes the deployment service call to update an mbean.
    *
    * @param data
    *           The data used to update the mbean
    * @return True if the mbean was updated, false otherwise.
    * @throws Exception
    *            Bad things happened.
    */
   private boolean updateMBean(MBeanData data) throws Exception
   {
      MBeanServerConnection server = getServer();
      log.info("Updating MBean '" + data + "'");

      // create the module
      boolean result = false;
      result = ((Boolean) server.invoke(deploymentService, "updateMBean",
            new Object[] { data },
            new String[] { "org.jboss.services.deployment.MBeanData" }))
            .booleanValue();

      log.info("MBean '" + data + "' update result: " + result);
      return result;
   }

   /**
    * Verifies that the mbean was updated successfully by comparing the values
    * of all of the attributes.
    *
    * @param data
    *           The mbean data that was set.
    * @param nestedAttr
    *           If any of the mbean attribuets were nested xml data, set this to
    *           the name of said attribute. If not, set to null.
    */
   private void verifyMBean(MBeanData data, String nestedAttr)
   {
      try
      {
         // Wait for the changes to be deployed (assume 5 second scan delay):
         log.info("Wait 10 seconds for changes to deploy");
         Thread.sleep(10000);

         // Compare all of the changed attribute values to the actual values.
         // They must all match for the test to pass.
         InitialContext ic = new InitialContext();
         MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
         ObjectName objectName = new ObjectName(data.getName());
         Properties attrs = data.getAttributes();
         Enumeration keys = attrs.keys();
         log.info("Verifying MBean attribute values:");
         while (keys.hasMoreElements())
         {
            String attr = (String) keys.nextElement();
            String expected = (String) attrs.get(attr);
            Object obj = server.getAttribute(objectName, attr);
            String actual = obj.toString();
            log.info("-- attribute    = " + attr);
            log.info("   expect value = " + expected);
            log.info("   actual value = " + actual);
            log.info("   actual type  = " + obj.getClass().getName());
            // Note that the value for the nested attribute is not returned
            // as expected, so we will not verify that it is correct:
            if (!actual.equals(expected) && nestedAttr != null
                  && !attr.equals(nestedAttr))
            {
               String msg = "Attribute '" + attr + "' has actual value '"
                     + actual + "', expected value " + expected + "'";
               log.error(msg);
               fail(msg);
            }
         }
         log.info("passed");
      }
      catch (Exception e)
      {
         log.error(e);
         fail("Unexpected error: " + e.getMessage());
      }
   }

   /**
    * Calls the deployment service to update the data source.
    */
   private boolean updateDataSource(String module, String template,
         HashMap props) throws Exception
   {
      log.info("updateDataSource('" + module + "', '" + template + "', "
            + props);
      MBeanServerConnection server = getServer();

      // update the data source
      module = (String) server
            .invoke(deploymentService, "updateDataSource", new Object[] {
                  module, template, props }, new String[] { "java.lang.String",
                  "java.lang.String", "java.util.HashMap" });

      // sleep for 3 secs to allow the old datasource to be undeployed first
      // before we verify deployment
      Thread.sleep(3000);
      return verifyDeploy(server, module);
   }

   /**
    * Calls the deployment service to remove the data source.
    */
   private boolean removeDataSource(String module, String template,
         HashMap props) throws Exception
   {
      log.info("removeDataSource('" + module + "', '" + template + "', "
            + props);
      MBeanServerConnection server = getServer();

      // remove the data source
      module = (String) server
            .invoke(deploymentService, "removeDataSource", new Object[] {
                  module, template, props }, new String[] { "java.lang.String",
                  "java.lang.String", "java.util.HashMap" });

      // sleep for 3 secs to allow the datasource to be undeployed first
      // before we verify deployment
      Thread.sleep(3000);
      return verifyDeploy(server, module);
   }

   /**
    * Try to connect to the specified data source. Try the connection every 3
    * seconds, maximum 5 times.
    */
   private boolean connectToDataSource(String jndiName) throws Exception
   {
      boolean connected = false;
      InitialContext ic = new InitialContext();
      DataSource ds = null;
      Connection connection = null;

      // See if we can get a connection
      for (int tries = 0; tries < 5; tries++)
      {
         try
         {
            ds = (DataSource) ic.lookup(jndiName);
            connection = ds.getConnection();
            connection.close();
            connected = true;
            log.info("Connected to data source: " + jndiName);
            break;
         }
         catch (Exception e)
         {
            log.info("Unable to connect to data source: " + jndiName
                  + ". Try again");
            // Sleep for 3 secs then try again
            Thread.sleep(3000);
         }
      }

      return connected;
   }

   /**
    * Verifies that a given module is acutally deployed. Waits for a while,
    * checking every few seconds, to see if the module has deployed yet.
    *
    * @param server
    *           User to invoke methods on the dpeloyment service.
    * @param module
    *           The name of the module (must include the suffix).
    * @return
    */
   private boolean verifyDeploy(MBeanServerConnection server, String module)
         throws Exception
   {
      // Get the deployed URL
      URL deployedURL = (URL) server.invoke(deploymentService,
            "getDeployedURL", new Object[] { module },
            new String[] { "java.lang.String" });

      // Ask the MainDeployer every 3 secs, 5 times (15secs max wait) if the
      // module was deployed
      Boolean isDeployed = new Boolean(false);
      for (int tries = 0; tries < 5; tries++)
      {
         // sleep for 3 secs
         Thread.sleep(3000);
         isDeployed = (Boolean) server.invoke(mainDeployer, "isDeployed",
               new Object[] { deployedURL }, new String[] { "java.net.URL" });

         if (isDeployed.booleanValue())
         {
            break;
         }
      }
      log.info("Module '" + module + "' deployed: " + isDeployed);
      return isDeployed.booleanValue();
   }
}
TOP

Related Classes of org.jboss.test.deployment.test.DeploymentServiceUnitTestCase

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.