[jboss-cvs] JBossAS SVN: r87905 - in projects/ejb-book/trunk: ch05-encryption and 20 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Apr 27 19:00:16 EDT 2009


Author: ALRubinger
Date: 2009-04-27 19:00:16 -0400 (Mon, 27 Apr 2009)
New Revision: 87905

Added:
   projects/ejb-book/trunk/ch05-encryption/
   projects/ejb-book/trunk/ch05-encryption/README
   projects/ejb-book/trunk/ch05-encryption/pom.xml
   projects/ejb-book/trunk/ch05-encryption/src/
   projects/ejb-book/trunk/ch05-encryption/src/main/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBean.java
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBeanBase.java
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionCommonBusiness.java
   projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionRemoteBusiness.java
   projects/ejb-book/trunk/ch05-encryption/src/main/resources/
   projects/ejb-book/trunk/ch05-encryption/src/main/resources/META-INF/
   projects/ejb-book/trunk/ch05-encryption/src/main/resources/META-INF/ejb-jar.xml
   projects/ejb-book/trunk/ch05-encryption/src/test/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionIntegrationTestCase.java
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionTestCaseSupport.java
   projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionUnitTestCase.java
   projects/ejb-book/trunk/ch05-encryption/src/test/resources/
   projects/ejb-book/trunk/ch05-encryption/src/test/resources/jndi.properties
   projects/ejb-book/trunk/ch05-encryption/src/test/resources/log4j.xml
Log:
[EJBBOOK-4] Added Chapter 5 Examples


Property changes on: projects/ejb-book/trunk/ch05-encryption
___________________________________________________________________
Name: svn:ignore
   + target
.settings
.classpath
.project


Added: projects/ejb-book/trunk/ch05-encryption/README
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/README	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/README	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,9 @@
+Some author notes on this example for the workbook section:
+
+* Shows use of SLSB for non-conversational processing
+* Introduces @PostConstruct lifecycle callback
+* Introduces @Resource injection
+* Introduces env-entry
+* Introduces SessionContext
+
+Possible Exercise: Extend this example such that the iteration count is configurable 
\ No newline at end of file

Added: projects/ejb-book/trunk/ch05-encryption/pom.xml
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/pom.xml	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/pom.xml	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,202 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <!-- Parent Information -->
+  <parent>
+    <groupId>org.jboss.ejb3.examples</groupId>
+    <artifactId>jboss-ejb3-examples-build</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+
+  <!-- Model Version -->
+  <modelVersion>4.0.0</modelVersion>
+
+  <!-- Artifact Information -->
+  <artifactId>jboss-ejb3-examples-ch05-encryption</artifactId>
+  <name>JBoss EJB 3.x Examples - Chapter 5: Encryption Service EJBs</name>
+  <description>Example to accompany O'Reilly "Enterprise Java Beans 6th Edition" Chapter 5</description>
+
+  <!-- Build -->
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <includeScope>runtime</includeScope>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <stripVersion>true</stripVersion>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+
+  <!-- Properties -->
+  <properties>
+
+    <!-- Versioning -->
+    <version.commons.codec_commons.codec>1.3</version.commons.codec_commons.codec>
+
+  </properties>
+
+  <!-- Dependencies -->
+  <dependencies>
+
+    <dependency>
+      <groupId>org.jboss.ejb3</groupId>
+      <artifactId>jboss-ejb3-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging-log4j</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging-spi</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>${version.commons.codec_commons.codec}</version>
+    </dependency>
+
+  </dependencies>
+
+  <profiles>
+
+    <profile>
+
+      <!-- Declare the "Integration Test" Profile -->
+      <id>it</id>
+
+      <build>
+
+        <plugins>
+
+          <!--
+
+            Configure Surefire to run in integration-test phase
+          -->
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>surefire-it</id>
+                <phase>integration-test</phase>
+                <goals>
+                  <goal>test</goal>
+                </goals>
+                <configuration>
+                  <skip>false</skip>
+                  <!-- Include jbossall-client.jar on the CP -->
+                  <additionalClasspathElements>
+                    <additionalClasspathElement>${jboss.home}/client/jbossall-client.jar</additionalClasspathElement>
+                  </additionalClasspathElements>
+                  <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                  <printSummary>true</printSummary>
+                  <forkMode>always</forkMode>
+                  <includes>
+                    <include>**/*IntegrationTestCase.java</include>
+                  </includes>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+
+          <!--
+
+            Define the JBossAS Maven Control Plugin
+          -->
+          <plugin>
+
+            <groupId>org.jboss.maven.plugins.jbossas</groupId>
+            <artifactId>maven-jboss-as-control-plugin</artifactId>
+            <version>0.1.2-SNAPSHOT</version>
+
+            <!-- Executions -->
+            <executions>
+
+              <!--
+
+                Start JBossAS with our new configuration
+              -->
+              <execution>
+                <id>start-jbossas</id>
+                <goals>
+                  <goal>start</goal>
+                </goals>
+                <phase>pre-integration-test</phase>
+                <configuration>
+                  <jvmArgs>
+                    <jvmArg>-Xmx512M</jvmArg>
+                  </jvmArgs>
+                  <serverConfigName>default</serverConfigName>
+                  <jboss.test.run>true</jboss.test.run>
+                </configuration>
+              </execution>
+
+              <!--
+
+                Deploy into our custom JBossAS Configuration
+              -->
+              <execution>
+                <id>deploy-test-slsb</id>
+                <goals>
+                  <goal>deploy</goal>
+                </goals>
+                <phase>pre-integration-test</phase>
+                <configuration>
+                  <serverConfigName>default</serverConfigName>
+                  <files>${project.build.directory}/lib/commons-codec.jar,${project.build.directory}/${project.build.finalName}.${project.packaging}
+                  </files>
+                  <jboss.test.run>true</jboss.test.run>
+                </configuration>
+              </execution>
+
+              <!--
+
+                Stop JBossAS
+              -->
+              <execution>
+                <id>stop-jbossas</id>
+                <goals>
+                  <goal>stop</goal>
+                </goals>
+                <phase>post-integration-test</phase>
+                <configuration>
+                  <serverConfigName>default</serverConfigName>
+                  <jboss.test.run>true</jboss.test.run>
+                </configuration>
+              </execution>
+
+            </executions>
+
+          </plugin>
+
+        </plugins>
+
+      </build>
+
+    </profile>
+
+  </profiles>
+
+</project>

Added: projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBean.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBean.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBean.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,257 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.ejb.Remote;
+import javax.ejb.SessionContext;
+import javax.ejb.Stateless;
+
+import org.jboss.logging.Logger;
+
+/**
+ * EncryptionBean
+ * 
+ * Bean implementation class of the EncryptionEJB.  Shows
+ * how lifecycle callbacks are implemented (@PostConstruct),
+ * and two ways of obtaining externalized environment
+ * entries. 
+ *
+ * @author <a href="mailto:alr at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at Stateless(name = EncryptionBean.EJB_NAME)
+ at Remote(EncryptionRemoteBusiness.class)
+public class EncryptionBean extends EncryptionBeanBase implements EncryptionRemoteBusiness
+{
+   // ---------------------------------------------------------------------------||
+   // Class Members -------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(EncryptionBean.class);
+
+   /**
+    * Name we'll assign to this EJB, will be referenced in the corresponding 
+    * META-INF/ejb-jar.xml file
+    */
+   static final String EJB_NAME = "EncryptionEJB";
+
+   /**
+    * Name of the environment entry representing the ciphers' passphrase supplied
+    * in ejb-jar.xml
+    */
+   private static final String ENV_ENTRY_NAME_CIPHERS_PASSPHRASE = "ciphersPassphrase";
+
+   // ---------------------------------------------------------------------------||
+   // Instance Members ----------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * SessionContext of this EJB; this will be injected by the EJB 
+    * Container as it's marked w/ @Resource
+    */
+   @Resource
+   private SessionContext context;
+
+   /**
+    * Passphrase to use  for the key in cipher operations; lazily initialized
+    * and loaded via SessionContext.lookup
+    */
+   private String ciphersPassphrase;
+
+   //TODO https://jira.jboss.org/jira/browse/EJBTHREE-1813
+   //TODO https://jira.jboss.org/jira/browse/EJBBOOK-5
+   /*
+    * injection-target in XML should *NOT* be required here.
+    */
+   /**
+    * Algorithm to use in message digest (hash) operations, injected
+    * via @Resource annotation
+    */
+   @Resource
+   private String messageDigestAlgorithm;
+
+   // ---------------------------------------------------------------------------||
+   // Lifecycle -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+   /**
+    * Here we extend the implementation 
+    * of {@link EncryptionBeanBase#initialize()} to:
+    * 
+    * 1) Apply the @PostConstruct annotation such that the method
+    *       is fired by the EJB Container as part of the SLSB lifecycle
+    * 2) Provide some logging to show when its called
+    */
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionBeanBase#initialize()
+    */
+   @Override
+   @PostConstruct
+   public void initialize() throws Exception
+   {
+      // Log that we're here
+      log.info("Initializing, part of " + PostConstruct.class.getName() + " lifecycle");
+
+      // Call super implementation
+      super.initialize();
+   }
+
+   /*
+    * We'll override the methods that return the some configuration
+    * so that we may externalize these values by way of EJB Environment Entries.
+    * Later we may look these up via a SessionContext that the Container will
+    * supply to this SLSB Bean instance (@see the @Resource annotation above
+    * the SessionContext member above)
+    */
+
+   /**
+    * Override the way we get the ciphers' passphrase so that we may 
+    * define it in a secure location on the server.  Now our production
+    * systems will use a different key for encoding than our development
+    * servers, and we may limit the likelihood of a security breach 
+    * while still allowing our programmer to use the default passphrase
+    * transparently during development.  
+    * 
+    * If not provided as an env-entry, fall back upon the default.
+    * 
+    * Note that a real system won't expose this method in the public API, ever.  We
+    * do here for testing and to illustrate the example.
+    * 
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionBeanBase#getCiphersPassphrase()
+    */
+   @Override
+   public String getCiphersPassphrase()
+   {
+      // Obtain current
+      String passphrase = this.ciphersPassphrase;
+
+      // If not set
+      if (passphrase == null)
+      {
+
+         // Do a lookup via SessionContext
+         passphrase = this.getEnvironmentEntryAsString(ENV_ENTRY_NAME_CIPHERS_PASSPHRASE);
+
+         // See if provided
+         if (passphrase == null)
+         {
+
+            // Log a warning
+            log.warn("No encryption passphrase has been supplied explicitly via "
+                  + "an env-entry, falling back on the default...");
+
+            // Set
+            passphrase = super.getCiphersPassphrase();
+         }
+
+         // Set the passphrase to be used so we don't have to do this lazy init again
+         this.ciphersPassphrase = passphrase;
+      }
+
+      // In a secure system, we don't log this. ;)
+      log.info("Using encryption passphrase for ciphers keys: " + passphrase);
+
+      // Return 
+      return passphrase;
+   }
+
+   /**
+    * Obtains the message digest algorithm as injected from the env-entry element
+    * defined in ejb-jar.xml.  If not specified, fall back onto the default, logging a warn 
+    * message
+    * 
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionRemoteBusiness#getMessageDigestAlgorithm()
+    */
+   @Override
+   public String getMessageDigestAlgorithm()
+   {
+      // First see if this has been injected/set
+      if (this.messageDigestAlgorithm == null)
+      {
+         // Log a warning
+         log.warn("No message digest algorithm has been supplied explicitly via "
+               + "an env-entry, falling back on the default...");
+
+         // Set
+         this.messageDigestAlgorithm = super.getMessageDigestAlgorithm();
+      }
+
+      // Log
+      log.info("Configured MessageDigest one-way hash algorithm is: " + this.messageDigestAlgorithm);
+
+      // Return
+      return this.messageDigestAlgorithm;
+   }
+
+   // ---------------------------------------------------------------------------||
+   // Internal Helper Methods ---------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+   /**
+    * Obtains the environment entry with the specified name, casting to a String,
+    * and returning the result.  If the entry is not assignable 
+    * to a String, an {@link IllegalStateException} will be raised.  In the event that the 
+    * specified environment entry cannot be found, a warning message will be logged
+    * and we'll return null.
+    * 
+    * @param envEntryName
+    * @return
+    * @throws IllegalStateException
+    */
+   private String getEnvironmentEntryAsString(final String envEntryName) throws IllegalStateException
+   {
+      // Lookup in the Private JNDI ENC via the injected SessionContext
+      Object lookupValue = null;
+      try
+      {
+         lookupValue = this.context.lookup(envEntryName);
+         log.debug("Obtained environment entry \"" + envEntryName + "\": " + lookupValue);
+      }
+      catch (final IllegalArgumentException iae)
+      {
+         // Not found defined within this EJB's Component Environment, 
+         // so return null and let the caller handle it
+         log.warn("Could not find environment entry with name: " + envEntryName);
+         return null;
+      }
+
+      // Cast
+      String returnValue = null;
+      try
+      {
+         returnValue = String.class.cast(lookupValue);
+      }
+      catch (final ClassCastException cce)
+      {
+         throw new IllegalStateException("The specified environment entry, " + lookupValue
+               + ", was not able to be represented as a " + String.class.getName(), cce);
+      }
+
+      // Return
+      return returnValue;
+   }
+
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBeanBase.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBeanBase.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionBeanBase.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,431 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.KeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.jboss.logging.Logger;
+
+/**
+ * EncryptionBeanBase
+ * 
+ * Base for bean implementation classes of the EncyrptionEJB, 
+ * provides business logic for required contracts
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class EncryptionBeanBase implements EncryptionCommonBusiness
+{
+   // ---------------------------------------------------------------------------||
+   // Class Members -------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(EncryptionBeanBase.class);
+
+   /**
+    * Charset used for encoding/decoding Strings to/from byte representation
+    */
+   private static final String CHARSET = "UTF-8";
+
+   /**
+    * Default Algorithm used by the Digest for one-way hashing
+    */
+   private static final String DEFAULT_ALGORITHM_MESSAGE_DIGEST = "MD5";
+
+   /**
+    * Default Algorithm used by the Cipher Key for symmetric encryption
+    */
+   private static final String DEFAULT_ALGORITHM_CIPHER = "PBEWithMD5AndDES";
+
+   /**
+    * The default passphrase for symmetric encryption/decryption
+    */
+   private static final String DEFAULT_PASSPHRASE = "LocalTestingPassphrase";
+
+   /**
+    * The salt used in symmetric encryption/decryption
+    */
+   private static final byte[] DEFAULT_SALT_CIPHERS =
+   {(byte) 0xB4, (byte) 0xA2, (byte) 0x43, (byte) 0x89, 0x3E, (byte) 0xC5, (byte) 0x78, (byte) 0x53};
+
+   /**
+    * Iteration count used for symmetric encryption/decryption
+    */
+   private static final int DEFAULT_ITERATION_COUNT_CIPHERS = 20;
+
+   // ---------------------------------------------------------------------------||
+   // Instance Members ----------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /*
+    * The following members represent the internal
+    * state of the Service.  Note how these are *not* leaked out
+    * via the end-user API, and are hence part of "internal state"
+    * and not "conversational state".
+    */
+
+   /**
+    * Digest used for one-way hashing
+    */
+   private MessageDigest messageDigest;
+
+   /**
+    * Cipher used for symmetric encryption
+    */
+   private Cipher encryptionCipher;
+
+   /**
+    * Cipher used for symmetric decryption
+    */
+   private Cipher decryptionCipher;
+
+   // ---------------------------------------------------------------------------||
+   // Lifecycle -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Initializes this service before it may handle requests
+    * 
+    * @throws Exception If some unexpected error occurred
+    * @throws IllegalStateException If one of the required ciphers was not available
+    */
+   public void initialize() throws Exception, IllegalStateException
+   {
+      /*
+       * Symmetric Encryption
+       */
+
+      // Obtain parameters used in initializing the ciphers
+      final String cipherAlgorithm = DEFAULT_ALGORITHM_CIPHER;
+      final byte[] ciphersSalt = DEFAULT_SALT_CIPHERS;
+      final int ciphersIterationCount = DEFAULT_ITERATION_COUNT_CIPHERS;
+      final String ciphersPassphrase = this.getCiphersPassphrase();
+
+      // Obtain key and param spec for the ciphers
+      final KeySpec ciphersKeySpec = new PBEKeySpec(ciphersPassphrase.toCharArray(), ciphersSalt, ciphersIterationCount);
+      final SecretKey ciphersKey = SecretKeyFactory.getInstance(cipherAlgorithm).generateSecret(ciphersKeySpec);
+      final AlgorithmParameterSpec paramSpec = new PBEParameterSpec(ciphersSalt, ciphersIterationCount);
+
+      // Create and init the ciphers
+      this.encryptionCipher = Cipher.getInstance(ciphersKey.getAlgorithm());
+      this.decryptionCipher = Cipher.getInstance(ciphersKey.getAlgorithm());
+      encryptionCipher.init(Cipher.ENCRYPT_MODE, ciphersKey, paramSpec);
+      decryptionCipher.init(Cipher.DECRYPT_MODE, ciphersKey, paramSpec);
+
+      // Log
+      log.info("Initialized encryption cipher: " + this.encryptionCipher);
+      log.info("Initialized decryption cipher: " + this.decryptionCipher);
+
+      /*
+       * One-way Hashing
+       */
+
+      // Get the algorithm for the MessageDigest
+      final String messageDigestAlgorithm = this.getMessageDigestAlgorithm();
+
+      // Create the MessageDigest
+      try
+      {
+         this.messageDigest = MessageDigest.getInstance(messageDigestAlgorithm);
+      }
+      catch (NoSuchAlgorithmException e)
+      {
+         throw new RuntimeException("Could not obtain the " + MessageDigest.class.getSimpleName() + " for algorithm: "
+               + messageDigestAlgorithm, e);
+      }
+      log.info("Initialized MessageDigest for one-way hashing: " + this.messageDigest);
+   }
+
+   // ---------------------------------------------------------------------------||
+   // Required Implementations --------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionCommonBusiness#compare(java.lang.String, java.lang.String)
+    */
+   @Override
+   public boolean compare(final String hash, final String input) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (hash == null)
+      {
+         throw new IllegalArgumentException("hash is required.");
+      }
+      if (input == null)
+      {
+         throw new IllegalArgumentException("Input is required.");
+      }
+
+      // Get the hash of the supplied input
+      final String hashOfInput = this.hash(input);
+
+      // Determine whether equal
+      final boolean equal = hash.equals(hashOfInput);
+
+      // Return
+      return equal;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionCommonBusiness#decrypt(java.lang.String)
+    */
+   @Override
+   public String decrypt(final String input) throws IllegalArgumentException, IllegalStateException
+   {
+      // Get the cipher
+      final Cipher cipher = this.decryptionCipher;
+      if (cipher == null)
+      {
+         throw new IllegalStateException("Decyrption cipher not available, has this service been initialized?");
+      }
+
+      // Run the cipher
+      byte[] resultBytes = null;;
+      try
+      {
+         final byte[] inputBytes = this.stringToByteArray(input);
+         resultBytes = cipher.doFinal(Base64.decodeBase64(inputBytes));
+      }
+      catch (final Throwable t)
+      {
+         throw new RuntimeException("Error in decryption", t);
+      }
+      final String result = this.byteArrayToString(resultBytes);
+
+      // Log
+      log.info("Decryption on \"" + input + "\": " + result);
+
+      // Return
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionCommonBusiness#encrypt(java.lang.String)
+    */
+   @Override
+   public String encrypt(final String input) throws IllegalArgumentException
+   {
+      // Get the cipher
+      final Cipher cipher = this.encryptionCipher;
+      if (cipher == null)
+      {
+         throw new IllegalStateException("Encyrption cipher not available, has this service been initialized?");
+      }
+
+      // Get bytes from the String
+      byte[] inputBytes = this.stringToByteArray(input);
+
+      // Run the cipher
+      byte[] resultBytes = null;
+      try
+      {
+         resultBytes = Base64.encodeBase64(cipher.doFinal(inputBytes));
+      }
+      catch (final Throwable t)
+      {
+         throw new RuntimeException("Error in encryption of: " + input, t);
+      }
+
+      // Log
+      log.info("Encryption on \"" + input + "\": " + this.byteArrayToString(resultBytes));
+
+      // Return
+      final String result = this.byteArrayToString(resultBytes);
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch05.encryption.EncryptionCommonBusiness#hash(java.lang.String)
+    */
+   @Override
+   public String hash(final String input) throws IllegalArgumentException
+   {
+      // Precondition check
+      if (input == null)
+      {
+         throw new IllegalArgumentException("Input is required.");
+      }
+
+      // Get bytes from the input
+      byte[] inputBytes = this.stringToByteArray(input);
+
+      // Obtain the MessageDigest
+      final MessageDigest digest = this.getMessageDigest();
+
+      // Update with our input, and obtain the hash, resetting the messageDigest
+      digest.update(inputBytes, 0, inputBytes.length);
+      final byte[] hashBytes = digest.digest();
+      final byte[] encodedBytes = Base64.encodeBase64(hashBytes);
+
+      // Get the input back in some readable format
+      final String hash = this.byteArrayToString(encodedBytes);
+      log.info("One-way hash of \"" + input + "\": " + hash);
+
+      // Return
+      return hash;
+   }
+
+   // ---------------------------------------------------------------------------||
+   // Internal Helper Methods ---------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Obtains the charset used in encoding/decoding Strings 
+    * to/from byte representation
+    * 
+    * @return The charset
+    */
+   protected String getCharset()
+   {
+      return CHARSET;
+   }
+
+   /**
+    * Returns a String representation of the specified byte array
+    * using the charset from {@link EncryptionBeanBase#getCharset()}.  Wraps 
+    * any {@link UnsupportedEncodingException} as a result of using an invalid
+    * charset in a {@link RuntimeException}.
+    * 
+    * @param bytes
+    * @return
+    * @throws RuntimeException If the charset was invalid, or some otehr unknown error occurred 
+    * @throws IllegalArgumentException If the byte array was not specified
+    */
+   protected final String byteArrayToString(final byte[] bytes) throws RuntimeException, IllegalArgumentException
+   {
+      // Precondition check
+      if (bytes == null)
+      {
+         throw new IllegalArgumentException("Byte array is required.");
+      }
+
+      // Represent as a String
+      String result = null;
+      final String charset = this.getCharset();
+      try
+      {
+         result = new String(bytes, charset);
+      }
+      catch (final UnsupportedEncodingException e)
+      {
+         throw new RuntimeException("Specified charset is invalid: " + charset, e);
+      }
+
+      // Return
+      return result;
+   }
+
+   /**
+    * Returns a byte array representation of the specified String
+    * using the charset from {@link EncryptionBeanBase#getCharset()}.  Wraps 
+    * any {@link UnsupportedEncodingException} as a result of using an invalid
+    * charset in a {@link RuntimeException}.
+    * 
+    * @param input
+    * @return
+    * @throws RuntimeException If the charset was invalid, or some otehr unknown error occurred 
+    * @throws IllegalArgumentException If the input was not specified (null)
+    */
+   protected final byte[] stringToByteArray(final String input) throws RuntimeException, IllegalArgumentException
+   {
+      // Precondition check
+      if (input == null)
+      {
+         throw new IllegalArgumentException("Input is required.");
+      }
+
+      // Represent as a String
+      byte[] result = null;
+      final String charset = this.getCharset();
+      try
+      {
+         result = input.getBytes(charset);
+      }
+      catch (final UnsupportedEncodingException e)
+      {
+         throw new RuntimeException("Specified charset is invalid: " + charset, e);
+      }
+
+      // Return
+      return result;
+   }
+
+   /**
+    * Returns the MessageDigest to be used for hashing
+    * 
+    * @return
+    * @throws IllegalStateException If the messageDigest has not yet been initialized
+    */
+   protected final MessageDigest getMessageDigest() throws IllegalStateException
+   {
+      // Get
+      final MessageDigest digest = this.messageDigest;
+
+      // Ensure init'd
+      if (digest == null)
+      {
+         throw new IllegalStateException(MessageDigest.class.getSimpleName() + " has not yet been initialized");
+      }
+
+      // Return
+      return digest;
+   }
+
+   /**
+    * Obtains the passphrase to be used in the key for
+    * the symmetric encryption/decryption ciphers
+    * 
+    * @return
+    */
+   protected String getCiphersPassphrase()
+   {
+      return DEFAULT_PASSPHRASE;
+   }
+
+   /**
+    * Returns the algorithm to be used in
+    * one-way hashing
+    *  
+    * @return
+    */
+   protected String getMessageDigestAlgorithm()
+   {
+      return DEFAULT_ALGORITHM_MESSAGE_DIGEST;
+   }
+
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionCommonBusiness.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionCommonBusiness.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionCommonBusiness.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+/**
+ * EncryptionCommonBusiness
+ * 
+ * Contains the contract for operations common to 
+ * all business interfaces of the EncryptionEJB
+ *
+ * @author <a href="mailto:alr at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface EncryptionCommonBusiness
+{
+   // ---------------------------------------------------------------------------||
+   // Contracts -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Encrypts the specified String, returning the result  
+    * 
+    * @param input
+    * @return
+    * @throws IllegalArgumentException If no input was provided (null)
+    */
+   String encrypt(String input) throws IllegalArgumentException;
+
+   /**
+    * Decrypts the specified String, returning the result.  The general
+    * contract is that the result of decrypting a String encrypted with
+    * {@link EncryptionCommonBusiness#encrypt(String)} will be equal 
+    * by value to the original input (round trip).
+    * 
+    * @param input
+    * @return
+    * @throws IllegalArgumentException If no input was provided (null)
+    */
+   String decrypt(String input) throws IllegalArgumentException;
+
+   /**
+    * Returns a one-way hash of the specified argument.  Useful
+    * for safely storing passwords for comparison.
+    * 
+    * @param input
+    * @return
+    * @throws IllegalArgumentException If no input was provided (null)
+    */
+   String hash(String input) throws IllegalArgumentException;
+
+   /**
+    * Returns whether or not the specified input matches the specified 
+    * hash.  Useful for validating passwords against a 
+    * securely-stored hash. 
+    * 
+    * @param hash
+    * @param input
+    * @return
+    * @throws IllegalArgumentException If either the hash or input is not provided (null)
+    */
+   boolean compare(String hash, String input) throws IllegalArgumentException;
+
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionRemoteBusiness.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionRemoteBusiness.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/main/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionRemoteBusiness.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+/**
+ * EncryptionRemoteBusiness
+ * 
+ * EJB 3.x Remote Business View of the EncryptionEJB
+ *
+ * @author <a href="mailto:alr at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface EncryptionRemoteBusiness extends EncryptionCommonBusiness
+{
+   // ---------------------------------------------------------------------------||
+   // Contracts -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /*
+    * Here we add some support in addition to methods defined by EncryptionCommonBusiness
+    * which will be specific to our EJB.  In real life it's a security risk to 
+    * expose these internals, but they're in place here for testing and to show 
+    * functionality described by the examples
+    */
+
+   /**
+    * Obtains the passphrase to be used in the key for
+    * the symmetric encryption/decryption ciphers
+    * 
+    * @return
+    */
+   String getCiphersPassphrase();
+
+   /**
+    * Obtains the algorithm to be used in performing
+    * one-way hashing
+    * 
+    * @return
+    */
+   String getMessageDigestAlgorithm();
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/main/resources/META-INF/ejb-jar.xml
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/main/resources/META-INF/ejb-jar.xml	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/main/resources/META-INF/ejb-jar.xml	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,52 @@
+<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+                  http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
+  version="3.0">
+
+  <enterprise-beans>
+
+    <!--
+      In this section we'll bolster our EncryptionEJB with some
+      additional metadata to complement the info defined via
+      annotations.
+    -->
+    <session>
+
+      <!--
+        This will match the value of @Stateless.name upon our bean
+        implementation class
+      -->
+      <ejb-name>EncryptionEJB</ejb-name>
+
+      <!-- Override the ciphers passphrase -->
+      <env-entry>
+        <env-entry-name>ciphersPassphrase</env-entry-name>
+        <env-entry-type>java.lang.String</env-entry-type>
+        <env-entry-value>OverriddenPassword</env-entry-value>
+      </env-entry>
+
+      <!-- Override the one-way hash MessageDigest algorithm -->
+      <env-entry>
+        <env-entry-name>messageDigestAlgorithm</env-entry-name>
+        <env-entry-type>java.lang.String</env-entry-type>
+        <env-entry-value>SHA</env-entry-value>
+        <!--
+          TODO This "injection-target" should not be required, we've got @Resource on the
+          member
+          
+          https://jira.jboss.org/jira/browse/EJBTHREE-1813
+          https://jira.jboss.org/jira/browse/EJBBOOK-5
+        -->
+        <injection-target>
+          <injection-target-class>
+            org.jboss.ejb3.examples.ch05.encryption.EncryptionBean</injection-target-class>
+          <injection-target-name>messageDigestAlgorithm</injection-target-name>
+        </injection-target>
+
+      </env-entry>
+
+    </session>
+
+  </enterprise-beans>
+
+</ejb-jar>
\ No newline at end of file

Added: projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionIntegrationTestCase.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionIntegrationTestCase.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionIntegrationTestCase.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,169 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import junit.framework.TestCase;
+
+import org.jboss.logging.Logger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * EncryptionIntegrationTestCase
+ * 
+ * Integration tests for the EncryptionEJB
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class EncryptionIntegrationTestCase extends EncryptionTestCaseSupport
+{
+   // ---------------------------------------------------------------------------||
+   // Class Members -------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(EncryptionIntegrationTestCase.class);
+
+   /**
+    * The JNDI Naming Context
+    */
+   private static Context namingContext;
+
+   /**
+    * The EJB 3.x remote business view of the EncryptionEJB
+    */
+   private static EncryptionRemoteBusiness encryptionRemoteBusiness;
+
+   /**
+    * JNDI Name of the Remote Business Reference
+    */
+   //TODO Use Global JNDI Syntax (not yet supported in JBoss EJB3)
+   private static final String JNDI_NAME_ENCRYPTION_REMOTE_BUSINESS = EncryptionBean.EJB_NAME + "/remote";
+
+   /**
+    * Correlates to the env-entry within ejb-jar.xml, to be used as an override from the default 
+    */
+   private static final String EXPECTED_CIPHERS_PASSPHRASE = "OverriddenPassword";
+
+   /**
+    * Correlates to the env-entry within ejb-jar.xml, to be used as an override from the default 
+    */
+   private static final String EXPECTED_ALGORITHM_MESSAGE_DIGEST = "SHA";
+
+   // ---------------------------------------------------------------------------||
+   // Lifecycle Methods ---------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   @BeforeClass
+   public static void beforeClass() throws Throwable
+   {
+      // Create the naming context, using jndi.properties on the CP
+      namingContext = new InitialContext();
+
+      // Obtain EJB 3.x Business Reference
+      encryptionRemoteBusiness = (EncryptionRemoteBusiness) namingContext.lookup(JNDI_NAME_ENCRYPTION_REMOTE_BUSINESS);
+   }
+
+   // ---------------------------------------------------------------------------||
+   // Tests ---------------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /*
+    * These tests will use the EJB set up in test initialization
+    */
+
+   /**
+    * @see {@link EncryptionTestCaseSupport#assertHashing(EncryptionCommonBusiness)}
+    */
+   @Test
+   public void testHashing() throws Throwable
+   {
+      // Log
+      log.info("testHashing");
+
+      // Test via superclass
+      this.assertHashing(encryptionRemoteBusiness);
+   }
+
+   /**
+    * @see {@link EncryptionTestCaseSupport#assertEncryption(EncryptionCommonBusiness)}
+    */
+   @Test
+   public void testEncryption() throws Throwable
+   {
+      // Log
+      log.info("testEncryption");
+
+      // Test via superclass
+      this.assertEncryption(encryptionRemoteBusiness);
+   }
+
+   /**
+    * Ensures that the hashing algorithm was overridden 
+    * from the environment entry declared in ejb-jar.xml
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testMessageDigestAlgorithmOverride() throws Throwable
+   {
+      // Log
+      log.info("testMessageDigestAlgorithmOverride");
+
+      // Get the algorithm used
+      final String algorithm = encryptionRemoteBusiness.getMessageDigestAlgorithm();
+      log.info("Using MessageDigest algorithm: " + algorithm);
+
+      // Ensure expected
+      TestCase.assertEquals("MessageDigest algorithm should have been overridden from the environment entry",
+            EXPECTED_ALGORITHM_MESSAGE_DIGEST, algorithm);
+   }
+
+   /**
+    * Ensures that the cipher passphrase was overridden 
+    * from the environment entry declared in ejb-jar.xml
+    * 
+    * @throws Throwable
+    */
+   @Test
+   public void testCiphersPassphraseOverride() throws Throwable
+   {
+      // Log
+      log.info("testCiphersPassphraseOverride");
+
+      // Get the algorithm used
+      final String passphrase = encryptionRemoteBusiness.getCiphersPassphrase();
+      log.info("Using Encryption passphrase: " + passphrase);
+
+      // Ensure expected
+      TestCase.assertEquals("Encryption passphrase should have been overridden from the environment entry",
+            EXPECTED_CIPHERS_PASSPHRASE, passphrase);
+   }
+
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionTestCaseSupport.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionTestCaseSupport.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionTestCaseSupport.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,118 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+import junit.framework.TestCase;
+
+import org.jboss.logging.Logger;
+
+/**
+ * EncryptionTestCaseSupport
+ * 
+ * Common base for centralizing test logic used
+ * for the Encryption POJO and EncryptionEJB
+ *
+ * @author <a href="mailto:alr at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class EncryptionTestCaseSupport
+{
+   // ---------------------------------------------------------------------------||
+   // Class Members -------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(EncryptionTestCaseSupport.class);
+
+   /**
+    * A simple String used in testing
+    */
+   private static final String TEST_STRING = "EJB 3.1 Examples Test String";
+
+   // ---------------------------------------------------------------------------||
+   // Test Support --------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Ensures that the hashing functions are working as expected:
+    * 
+    * 1) Passing through the hash returns a result inequal to the input
+    * 2) Comparison upon the hash result and the original input matches 
+    * 
+    * @param service The service to use (either POJO or EJB)
+    * @throws Throwable
+    */
+   protected void assertHashing(final EncryptionCommonBusiness service) throws Throwable
+   {
+      // Log
+      log.info("assertHashing");
+
+      // Declare the input
+      final String input = TEST_STRING;
+
+      // Hash
+      final String hash = service.hash(input);
+      log.info("Hash of \"" + input + "\": " + hash);
+
+      // Test that the has function had some effect
+      TestCase.assertNotSame("The hash function had no effect upon the supplied input", input, hash);
+
+      // Get the comparison result
+      final boolean equal = service.compare(hash, input);
+
+      // Test that the input matches the hash we'd gotten
+      TestCase.assertTrue("The comparison of the input to its hashed result failed", equal);
+   }
+
+   /**
+    * Ensures that the encryption functions are working as expected:
+    * 
+    * 1) Passing through the encryption returns a result inequal to the input
+    * 2) Round-trip through decryption again returns a result equal to the original input 
+    * 
+    * @param service The service to use (either POJO or EJB)
+    * @throws Throwable
+    */
+   protected void assertEncryption(final EncryptionCommonBusiness service) throws Throwable
+   {
+      // Log
+      log.info("assertEncryption");
+
+      // Declare the input
+      final String input = TEST_STRING;
+
+      // Hash
+      final String encrypted = service.encrypt(input);
+      log.info("Encrypted result of \"" + input + "\": " + encrypted);
+
+      // Test that the has function had some effect
+      TestCase.assertNotSame("The encryption function had no effect upon the supplied input", input, encrypted);
+
+      // Get the round-trip result
+      final String roundTrip = service.decrypt(encrypted);
+
+      // Test that the result matches the original input
+      TestCase.assertEquals("The comparison of the input to its encrypted result failed", input, roundTrip);
+   }
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionUnitTestCase.java
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionUnitTestCase.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/test/java/org/jboss/ejb3/examples/ch05/encryption/EncryptionUnitTestCase.java	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,101 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.ejb3.examples.ch05.encryption;
+
+import org.jboss.logging.Logger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * EncryptionUnitTestCase
+ * 
+ * Tests to ensure that the business methods of the EncryptionEJB
+ * are working as expected
+ *
+ * @author <a href="mailto:alr at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class EncryptionUnitTestCase extends EncryptionTestCaseSupport
+{
+   // ---------------------------------------------------------------------------||
+   // Class Members -------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Logger 
+    */
+   private static final Logger log = Logger.getLogger(EncryptionUnitTestCase.class);
+
+   /**
+    * POJO Encryption Service
+    */
+   private static EncryptionBeanBase encryptionService;
+
+   // ---------------------------------------------------------------------------||
+   // Lifecycle -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Initializes the suite, invoked once before any tests are run 
+    */
+   @BeforeClass
+   public static void initialize() throws Throwable
+   {
+      // Create the encryption service
+      encryptionService = new EncryptionBeanBase();
+      encryptionService.initialize(); // We call init manually here
+   }
+
+   // ---------------------------------------------------------------------------||
+   // Tests ---------------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /*
+    * These tests will use the POJO set up in test initialization
+    */
+
+   /**
+    * @see {@link EncryptionTestCaseSupport#assertHashing(EncryptionCommonBusiness)}
+    */
+   @Test
+   public void testHashing() throws Throwable
+   {
+      // Log
+      log.info("testHashing");
+
+      // Test via superclass
+      this.assertHashing(encryptionService);
+   }
+
+   /**
+    * @see {@link EncryptionTestCaseSupport#assertEncryption(EncryptionCommonBusiness)}
+    */
+   @Test
+   public void testEncryption() throws Throwable
+   {
+      // Log
+      log.info("testEncryption");
+
+      // Test via superclass
+      this.assertEncryption(encryptionService);
+   }
+}

Added: projects/ejb-book/trunk/ch05-encryption/src/test/resources/jndi.properties
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/test/resources/jndi.properties	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/test/resources/jndi.properties	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,4 @@
+# JNDI Properties for Remote interaction with JBoss Application Server Naming Service 
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+java.naming.provider.url=jnp://localhost:1099
\ No newline at end of file

Added: projects/ejb-book/trunk/ch05-encryption/src/test/resources/log4j.xml
===================================================================
--- projects/ejb-book/trunk/ch05-encryption/src/test/resources/log4j.xml	                        (rev 0)
+++ projects/ejb-book/trunk/ch05-encryption/src/test/resources/log4j.xml	2009-04-27 23:00:16 UTC (rev 87905)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!--  Log4j Configuration                                                  -->
+<!-- ===================================================================== -->
+
+<!--
+   | For more configuration infromation and examples see the Jakarta Log4j
+   | website: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+  <!-- ============================== -->
+  <!-- Append messages to the console -->
+  <!-- ============================== -->
+
+  <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out"/>
+    <param name="Threshold" value="INFO"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+    </layout>
+  </appender>
+
+
+  <!-- ================ -->
+  <!-- Limit categories -->
+  <!-- ================ -->
+  
+  <category name="org.jboss.ejb3.examples">
+    <priority value="ALL"/>
+  </category>
+  
+  <!-- ======================= -->
+  <!-- Setup the Root category -->
+  <!-- ======================= -->
+
+  <root>
+    <appender-ref ref="CONSOLE"/>
+  </root>
+  
+</log4j:configuration>




More information about the jboss-cvs-commits mailing list