http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/efed31f4/src/main/jbake/content/examples/dynamic-dao-implementation.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/dynamic-dao-implementation.adoc b/src/main/jbake/content/examples/dynamic-dao-implementation.adoc deleted file mode 100755 index 40b7a96..0000000 --- a/src/main/jbake/content/examples/dynamic-dao-implementation.adoc +++ /dev/null @@ -1,384 +0,0 @@ -= Dynamic DAO Implementation -:jbake-date: 2016-09-06 -:jbake-type: page -:jbake-tomeepdf: -:jbake-status: published - -Example dynamic-dao-implementation can be browsed at https://github.com/apache/tomee/tree/master/examples/dynamic-dao-implementation - - -Many aspects of Data Access Objects (DAOs) are very repetitive and boiler plate. As a fun and experimental feature, TomEE supports dynamically implementing an interface -that is seen to have standard DAO-style methods. - -The interface has to be annotated with @PersistenceContext to define which EntityManager to use. - -Methods should respect these conventions: - - * void save(Foo foo): persist foo - * Foo update(Foo foo): merge foo - * void delete(Foo foo): remove foo, if foo is detached it tries to attach it - * Collection<Foo>|Foo namedQuery(String name[, Map<String, ?> params, int first, int max]): run the named query called name, params contains bindings, first and max are used for magination. Last three parameters are optionnals - * Collection<Foo>|Foo nativeQuery(String name[, Map<String, ?> params, int first, int max]): run the native query called name, params contains bindings, first and max are used for magination. Last three parameters are optionnals - * Collection<Foo>|Foo query(String value [, Map<String, ?> params, int first, int max]): run the query put as first parameter, params contains bindings, first and max are used for magination. Last three parameters are optionnals - * Collection<Foo> findAll([int first, int max]): find all Foo, parameters are used for pagination - * Collection<Foo> findByBar1AndBar2AndBar3(<bar 1 type> bar1, <bar 2 type> bar2, <bar3 type> bar3 [, int first, int max]): find all Foo with specified field values for bar1, bar2, bar3. - -Dynamic finder can have as much as you want field constraints. For String like is used and for other type equals is used. - -= Example - -== User - - -[source,java] ----- -package org.superbiz.dynamic; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; - -@Entity -@NamedQueries({ - @NamedQuery(name = "dynamic-ejb-impl-test.query", query = "SELECT u FROM User AS u WHERE u.name LIKE :name"), - @NamedQuery(name = "dynamic-ejb-impl-test.all", query = "SELECT u FROM User AS u") -}) -public class User { - @Id - @GeneratedValue - private long id; - private String name; - private int age; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } -} ----- - - -== UserDao - - -[source,java] ----- -package org.superbiz.dynamic; - - -import javax.ejb.Stateless; -import javax.persistence.PersistenceContext; -import java.util.Collection; -import java.util.Map; - -@Stateless -@PersistenceContext(name = "dynamic") -public interface UserDao { - User findById(long id); - - Collection<User> findByName(String name); - - Collection<User> findByNameAndAge(String name, int age); - - Collection<User> findAll(); - - Collection<User> findAll(int first, int max); - - Collection<User> namedQuery(String name, Map<String, ?> params, int first, int max); - - Collection<User> namedQuery(String name, int first, int max, Map<String, ?> params); - - Collection<User> namedQuery(String name, Map<String, ?> params); - - Collection<User> namedQuery(String name); - - Collection<User> query(String value, Map<String, ?> params); - - void save(User u); - - void delete(User u); - - User update(User u); -} ----- - - -== persistence.xml - - -[source,xml] ----- -<persistence version="2.0" - xmlns="http://java.sun.com/xml/ns/persistence" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation=" - http://java.sun.com/xml/ns/persistence - http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> - <persistence-unit name="dynamic" transaction-type="JTA"> - <jta-data-source>jdbc/dynamicDB</jta-data-source> - <class>org.superbiz.dynamic.User</class> - <properties> - <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> - </properties> - </persistence-unit> -</persistence> ----- - - - -== DynamicUserDaoTest - - -[source,java] ----- -package org.superbiz.dynamic; - -import junit.framework.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import javax.ejb.EJBException; -import javax.ejb.Stateless; -import javax.ejb.embeddable.EJBContainer; -import javax.naming.Context; -import javax.persistence.EntityManager; -import javax.persistence.NoResultException; -import javax.persistence.PersistenceContext; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertTrue; - -public class DynamicUserDaoTest { - private static UserDao dao; - private static Util util; - - @BeforeClass - public static void init() throws Exception { - final Properties p = new Properties(); - p.put("jdbc/dynamicDB", "new://Resource?type=DataSource"); - p.put("jdbc/dynamicDB.JdbcDriver", "org.hsqldb.jdbcDriver"); - p.put("jdbc/dynamicDB.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); - p.put("jdbc/dynamicDB.UserName", "sa"); - p.put("jdbc/dynamicDB.Password", ""); - - final Context context = EJBContainer.createEJBContainer(p).getContext(); - dao = (UserDao) context.lookup("java:global/dynamic-dao-implementation/UserDao"); - util = (Util) context.lookup("java:global/dynamic-dao-implementation/Util"); - - util.init(); // init database - } - - @Test - public void simple() { - User user = dao.findById(1); - assertNotNull(user); - assertEquals(1, user.getId()); - } - - @Test - public void findAll() { - Collection<User> users = dao.findAll(); - assertEquals(10, users.size()); - } - - @Test - public void pagination() { - Collection<User> users = dao.findAll(0, 5); - assertEquals(5, users.size()); - - users = dao.findAll(6, 1); - assertEquals(1, users.size()); - assertEquals(7, users.iterator().next().getId()); - } - - @Test - public void persist() { - User u = new User(); - dao.save(u); - assertNotNull(u.getId()); - util.remove(u); - } - - @Test - public void remove() { - User u = new User(); - dao.save(u); - assertNotNull(u.getId()); - dao.delete(u); - try { - dao.findById(u.getId()); - Assert.fail(); - } catch (EJBException ee) { - assertTrue(ee.getCause() instanceof NoResultException); - } - } - - @Test - public void merge() { - User u = new User(); - u.setAge(1); - dao.save(u); - assertEquals(1, u.getAge()); - assertNotNull(u.getId()); - - u.setAge(2); - dao.update(u); - assertEquals(2, u.getAge()); - - dao.delete(u); - } - - @Test - public void oneCriteria() { - Collection<User> users = dao.findByName("foo"); - assertEquals(4, users.size()); - for (User user : users) { - assertEquals("foo", user.getName()); - } - } - - @Test - public void twoCriteria() { - Collection<User> users = dao.findByNameAndAge("bar-1", 1); - assertEquals(1, users.size()); - - User user = users.iterator().next(); - assertEquals("bar-1", user.getName()); - assertEquals(1, user.getAge()); - } - - @Test - public void query() { - Map<String, Object> params = new HashMap<String, Object>(); - params.put("name", "foo"); - - Collection<User> users = dao.namedQuery("dynamic-ejb-impl-test.query", params, 0, 100); - assertEquals(4, users.size()); - - users = dao.namedQuery("dynamic-ejb-impl-test.query", params); - assertEquals(4, users.size()); - - users = dao.namedQuery("dynamic-ejb-impl-test.query", params, 0, 2); - assertEquals(2, users.size()); - - users = dao.namedQuery("dynamic-ejb-impl-test.query", 0, 2, params); - assertEquals(2, users.size()); - - users = dao.namedQuery("dynamic-ejb-impl-test.all"); - assertEquals(10, users.size()); - - params.remove("name"); - params.put("age", 1); - users = dao.query("SELECT u FROM User AS u WHERE u.age = :age", params); - assertEquals(3, users.size()); - } - - @Stateless - public static class Util { - @PersistenceContext - private EntityManager em; - - public void remove(User o) { - em.remove(em.find(User.class, o.getId())); - } - - public void init() { - for (int i = 0; i < 10; i++) { - User u = new User(); - u.setAge(i % 4); - if (i % 3 == 0) { - u.setName("foo"); - } else { - u.setName("bar-" + i); - } - em.persist(u); - } - } - } -} ----- - - -= Running - - - -[source] ----- -------------------------------------------------------- - T E S T S -------------------------------------------------------- -Running org.superbiz.dynamic.DynamicUserDaoTest -Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 -http://tomee.apache.org/ -INFO - openejb.home = /Users/dblevins/examples/dynamic-dao-implementation -INFO - openejb.base = /Users/dblevins/examples/dynamic-dao-implementation -INFO - Using 'javax.ejb.embeddable.EJBContainer=true' -INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) -INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) -INFO - Configuring Service(id=jdbc/dynamicDB, type=Resource, provider-id=Default JDBC Database) -INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-dao-implementation/target/classes -INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-dao-implementation/target/test-classes -INFO - Beginning load: /Users/dblevins/examples/dynamic-dao-implementation/target/classes -INFO - Beginning load: /Users/dblevins/examples/dynamic-dao-implementation/target/test-classes -INFO - Configuring enterprise application: /Users/dblevins/examples/dynamic-dao-implementation -INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) -INFO - Auto-creating a container for bean UserDao: Container(type=STATELESS, id=Default Stateless Container) -INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) -INFO - Auto-creating a container for bean org.superbiz.dynamic.DynamicUserDaoTest: Container(type=MANAGED, id=Default Managed Container) -INFO - Configuring PersistenceUnit(name=dynamic) -INFO - Auto-creating a Resource with id 'jdbc/dynamicDBNonJta' of type 'DataSource for 'dynamic'. -INFO - Configuring Service(id=jdbc/dynamicDBNonJta, type=Resource, provider-id=jdbc/dynamicDB) -INFO - Adjusting PersistenceUnit dynamic <non-jta-data-source> to Resource ID 'jdbc/dynamicDBNonJta' from 'null' -INFO - Enterprise application "/Users/dblevins/examples/dynamic-dao-implementation" loaded. -INFO - Assembling app: /Users/dblevins/examples/dynamic-dao-implementation -INFO - PersistenceUnit(name=dynamic, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 417ms -INFO - Jndi(name="java:global/dynamic-dao-implementation/UserDao!org.superbiz.dynamic.UserDao") -INFO - Jndi(name="java:global/dynamic-dao-implementation/UserDao") -INFO - Jndi(name="java:global/dynamic-dao-implementation/Util!org.superbiz.dynamic.DynamicUserDaoTest$Util") -INFO - Jndi(name="java:global/dynamic-dao-implementation/Util") -INFO - Jndi(name="java:global/EjbModule346613126/org.superbiz.dynamic.DynamicUserDaoTest!org.superbiz.dynamic.DynamicUserDaoTest") -INFO - Jndi(name="java:global/EjbModule346613126/org.superbiz.dynamic.DynamicUserDaoTest") -INFO - Created Ejb(deployment-id=UserDao, ejb-name=UserDao, container=Default Stateless Container) -INFO - Created Ejb(deployment-id=Util, ejb-name=Util, container=Default Stateless Container) -INFO - Created Ejb(deployment-id=org.superbiz.dynamic.DynamicUserDaoTest, ejb-name=org.superbiz.dynamic.DynamicUserDaoTest, container=Default Managed Container) -INFO - Started Ejb(deployment-id=UserDao, ejb-name=UserDao, container=Default Stateless Container) -INFO - Started Ejb(deployment-id=Util, ejb-name=Util, container=Default Stateless Container) -INFO - Started Ejb(deployment-id=org.superbiz.dynamic.DynamicUserDaoTest, ejb-name=org.superbiz.dynamic.DynamicUserDaoTest, container=Default Managed Container) -INFO - Deployed Application(path=/Users/dblevins/examples/dynamic-dao-implementation) -WARN - Meta class "org.superbiz.dynamic.User_" for entity class org.superbiz.dynamic.User can not be registered with following exception "java.security.PrivilegedActionException: java.lang.ClassNotFoundException: org.superbiz.dynamic.User_" -WARN - Query "SELECT u FROM User AS u WHERE u.name LIKE :name" is removed from cache excluded permanently. Query "SELECT u FROM User AS u WHERE u.name LIKE :name" is not cached because it uses pagination.. -Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.471 sec - -Results : - -Tests run: 9, Failures: 0, Errors: 0, Skipped: 0 ----- - -
http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/efed31f4/src/main/jbake/content/examples/dynamic-datasource-routing.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/dynamic-datasource-routing.adoc b/src/main/jbake/content/examples/dynamic-datasource-routing.adoc deleted file mode 100755 index 8b7a76e..0000000 --- a/src/main/jbake/content/examples/dynamic-datasource-routing.adoc +++ /dev/null @@ -1,473 +0,0 @@ -= Dynamic Datasource Routing -:jbake-date: 2016-09-06 -:jbake-type: page -:jbake-tomeepdf: -:jbake-status: published - -Example dynamic-datasource-routing can be browsed at https://github.com/apache/tomee/tree/master/examples/dynamic-datasource-routing - - -The TomEE dynamic datasource api aims to allow to use multiple data sources as one from an application point of view. - -It can be useful for technical reasons (load balancing for example) or more generally -functionnal reasons (filtering, aggregation, enriching...). However please note you can choose -only one datasource by transaction. It means the goal of this feature is not to switch more than -once of datasource in a transaction. The following code will not work: - - -[source,java] ----- -@Stateless -public class MyEJB { - @Resource private MyRouter router; - @PersistenceContext private EntityManager em; - - public void workWithDataSources() { - router.setDataSource("ds1"); - em.persist(new MyEntity()); - - router.setDataSource("ds2"); // same transaction -> this invocation doesn't work - em.persist(new MyEntity()); - } -} ----- - - -In this example the implementation simply use a datasource from its name and needs to be set before using any JPA -operation in the transaction (to keep the logic simple in the example). - -= The implementation of the Router - -Our router has two configuration parameters: -* a list of jndi names representing datasources to use -* a default datasource to use - -== Router implementation - -The interface Router (`org.apache.openejb.resource.jdbc.Router`) has only one method to implement, `public DataSource getDataSource()` - -Our `DeterminedRouter` implementation uses a ThreadLocal to manage the currently used datasource. Keep in mind JPA used more than once the getDatasource() method -for one operation. To change the datasource in one transaction is dangerous and should be avoid. - - -[source,java] ----- -package org.superbiz.dynamicdatasourcerouting; - -import org.apache.openejb.resource.jdbc.AbstractRouter; - -import javax.naming.NamingException; -import javax.sql.DataSource; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class DeterminedRouter extends AbstractRouter { - private String dataSourceNames; - private String defaultDataSourceName; - private Map<String, DataSource> dataSources = null; - private ThreadLocal<DataSource> currentDataSource = new ThreadLocal<DataSource>(); - - /** - * @param datasourceList datasource resource name, separator is a space - */ - public void setDataSourceNames(String datasourceList) { - dataSourceNames = datasourceList; - } - - /** - * lookup datasource in openejb resources - */ - private void init() { - dataSources = new ConcurrentHashMap<String, DataSource>(); - for (String ds : dataSourceNames.split(" ")) { - try { - Object o = getOpenEJBResource(ds); - if (o instanceof DataSource) { - dataSources.put(ds, DataSource.class.cast(o)); - } - } catch (NamingException e) { - // ignored - } - } - } - - /** - * @return the user selected data source if it is set - * or the default one - * @throws IllegalArgumentException if the data source is not found - */ - @Override - public DataSource getDataSource() { - // lazy init of routed datasources - if (dataSources == null) { - init(); - } - - // if no datasource is selected use the default one - if (currentDataSource.get() == null) { - if (dataSources.containsKey(defaultDataSourceName)) { - return dataSources.get(defaultDataSourceName); - - } else { - throw new IllegalArgumentException("you have to specify at least one datasource"); - } - } - - // the developper set the datasource to use - return currentDataSource.get(); - } - - /** - * - * @param datasourceName data source name - */ - public void setDataSource(String datasourceName) { - if (dataSources == null) { - init(); - } - if (!dataSources.containsKey(datasourceName)) { - throw new IllegalArgumentException("data source called " + datasourceName + " can't be found."); - } - DataSource ds = dataSources.get(datasourceName); - currentDataSource.set(ds); - } - - /** - * reset the data source - */ - public void clear() { - currentDataSource.remove(); - } - - public void setDefaultDataSourceName(String name) { - this.defaultDataSourceName = name; - } -} ----- - - -== Declaring the implementation - -To be able to use your router as a resource you need to provide a service configuration. It is done in a file -you can find in META-INF/org.router/ and called service-jar.xml -(for your implementation you can of course change the package name). - -It contains the following code: - - -[source,xml] ----- -<ServiceJar> - <ServiceProvider id="DeterminedRouter" <!-- the name you want to use --> - service="Resource" - type="org.apache.openejb.resource.jdbc.Router" - class-name="org.superbiz.dynamicdatasourcerouting.DeterminedRouter"> <!-- implementation class --> - - # the parameters - - DataSourceNames - DefaultDataSourceName - </ServiceProvider> -</ServiceJar> ----- - - - -= Using the Router - -Here we have a `RoutedPersister` stateless bean which uses our `DeterminedRouter` - - -[source,java] ----- -package org.superbiz.dynamicdatasourcerouting; - -import javax.annotation.Resource; -import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -@Stateless -public class RoutedPersister { - @PersistenceContext(unitName = "router") - private EntityManager em; - - @Resource(name = "My Router", type = DeterminedRouter.class) - private DeterminedRouter router; - - public void persist(int id, String name, String ds) { - router.setDataSource(ds); - em.persist(new Person(id, name)); - } -} ----- - - -= The test - -In test mode and using property style configuration the foolowing configuration is used: - - -[source,java] ----- -public class DynamicDataSourceTest { - @Test - public void route() throws Exception { - String[] databases = new String[]{"database1", "database2", "database3"}; - - Properties properties = new Properties(); - properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName()); - - // resources - // datasources - for (int i = 1; i <= databases.length; i++) { - String dbName = databases[i - 1]; - properties.setProperty(dbName, "new://Resource?type=DataSource"); - dbName += "."; - properties.setProperty(dbName + "JdbcDriver", "org.hsqldb.jdbcDriver"); - properties.setProperty(dbName + "JdbcUrl", "jdbc:hsqldb:mem:db" + i); - properties.setProperty(dbName + "UserName", "sa"); - properties.setProperty(dbName + "Password", ""); - properties.setProperty(dbName + "JtaManaged", "true"); - } - - // router - properties.setProperty("My Router", "new://Resource?provider=org.router:DeterminedRouter&type=" + DeterminedRouter.class.getName()); - properties.setProperty("My Router.DatasourceNames", "database1 database2 database3"); - properties.setProperty("My Router.DefaultDataSourceName", "database1"); - - // routed datasource - properties.setProperty("Routed Datasource", "new://Resource?provider=RoutedDataSource&type=" + Router.class.getName()); - properties.setProperty("Routed Datasource.Router", "My Router"); - - Context ctx = EJBContainer.createEJBContainer(properties).getContext(); - RoutedPersister ejb = (RoutedPersister) ctx.lookup("java:global/dynamic-datasource-routing/RoutedPersister"); - for (int i = 0; i < 18; i++) { - // persisting a person on database db -> kind of manual round robin - String name = "record " + i; - String db = databases[i % 3]; - ejb.persist(i, name, db); - } - - // assert database records number using jdbc - for (int i = 1; i <= databases.length; i++) { - Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:db" + i, "sa", ""); - Statement st = connection.createStatement(); - ResultSet rs = st.executeQuery("select count(*) from PERSON"); - rs.next(); - assertEquals(6, rs.getInt(1)); - st.close(); - connection.close(); - } - - ctx.close(); - } -} ----- - - -= Configuration via openejb.xml - -The testcase above uses properties for configuration. The identical way to do it via the `conf/openejb.xml` is as follows: - - -[source,xml] ----- -<!-- Router and datasource --> -<Resource id="My Router" type="org.apache.openejb.router.test.DynamicDataSourceTest$DeterminedRouter" provider="org.routertest:DeterminedRouter"> - DatasourceNames = database1 database2 database3 - DefaultDataSourceName = database1 -</Resource> ----- - - -[source,xml] ----- -<Resource id="Routed Datasource" type="org.apache.openejb.resource.jdbc.Router" provider="RoutedDataSource"> - Router = My Router -</Resource> ----- - - - -[source,xml] ----- -<!-- real datasources --> -<Resource id="database1" type="DataSource"> - JdbcDriver = org.hsqldb.jdbcDriver - JdbcUrl = jdbc:hsqldb:mem:db1 - UserName = sa - Password - JtaManaged = true -</Resource> ----- - - -[source,xml] ----- -<Resource id="database2" type="DataSource"> - JdbcDriver = org.hsqldb.jdbcDriver - JdbcUrl = jdbc:hsqldb:mem:db2 - UserName = sa - Password - JtaManaged = true -</Resource> ----- - - -[source,xml] ----- -<Resource id="database3" type="DataSource"> - JdbcDriver = org.hsqldb.jdbcDriver - JdbcUrl = jdbc:hsqldb:mem:db3 - UserName = sa - Password - JtaManaged = true -</Resource> ----- - - - - - -== Some hack for OpenJPA - -Using more than one datasource behind one EntityManager means the databases are already created. If it is not the case, -the JPA provider has to create the datasource at boot time. - -Hibernate do it so if you declare your databases it will work. However with OpenJPA -(the default JPA provider for OpenEJB), the creation is lazy and it happens only once so when you'll switch of database -it will no more work. - -Of course OpenEJB provides @Singleton and @Startup features of Java EE 6 and we can do a bean just making a simple find, -even on none existing entities, just to force the database creation: - - -[source,java] ----- -@Startup -@Singleton -public class BoostrapUtility { - // inject all real databases - - @PersistenceContext(unitName = "db1") - private EntityManager em1; - - @PersistenceContext(unitName = "db2") - private EntityManager em2; - - @PersistenceContext(unitName = "db3") - private EntityManager em3; - - // force database creation - - @PostConstruct - @TransactionAttribute(TransactionAttributeType.SUPPORTS) - public void initDatabase() { - em1.find(Person.class, 0); - em2.find(Person.class, 0); - em3.find(Person.class, 0); - } -} ----- - - -== Using the routed datasource - -Now you configured the way you want to route your JPA operation, you registered the resources and you initialized -your databases you can use it and see how it is simple: - - -[source,java] ----- -@Stateless -public class RoutedPersister { - // injection of the "proxied" datasource - @PersistenceContext(unitName = "router") - private EntityManager em; - - // injection of the router you need it to configured the database - @Resource(name = "My Router", type = DeterminedRouter.class) - private DeterminedRouter router; - - public void persist(int id, String name, String ds) { - router.setDataSource(ds); // configuring the database for the current transaction - em.persist(new Person(id, name)); // will use ds database automatically - } -} ----- - - -= Running - - - -[source] ----- -------------------------------------------------------- - T E S T S -------------------------------------------------------- -Running org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest -Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 -http://tomee.apache.org/ -INFO - openejb.home = /Users/dblevins/examples/dynamic-datasource-routing -INFO - openejb.base = /Users/dblevins/examples/dynamic-datasource-routing -INFO - Using 'javax.ejb.embeddable.EJBContainer=true' -INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) -INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) -INFO - Configuring Service(id=My Router, type=Resource, provider-id=DeterminedRouter) -INFO - Configuring Service(id=database3, type=Resource, provider-id=Default JDBC Database) -INFO - Configuring Service(id=database2, type=Resource, provider-id=Default JDBC Database) -INFO - Configuring Service(id=Routed Datasource, type=Resource, provider-id=RoutedDataSource) -INFO - Configuring Service(id=database1, type=Resource, provider-id=Default JDBC Database) -INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-datasource-routing/target/classes -INFO - Beginning load: /Users/dblevins/examples/dynamic-datasource-routing/target/classes -INFO - Configuring enterprise application: /Users/dblevins/examples/dynamic-datasource-routing -WARN - Method 'lookup' is not available for 'javax.annotation.Resource'. Probably using an older Runtime. -INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) -INFO - Auto-creating a container for bean BoostrapUtility: Container(type=SINGLETON, id=Default Singleton Container) -INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) -INFO - Auto-creating a container for bean RoutedPersister: Container(type=STATELESS, id=Default Stateless Container) -INFO - Auto-linking resource-ref 'java:comp/env/My Router' in bean RoutedPersister to Resource(id=My Router) -INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) -INFO - Auto-creating a container for bean org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest: Container(type=MANAGED, id=Default Managed Container) -INFO - Configuring PersistenceUnit(name=router) -INFO - Configuring PersistenceUnit(name=db1) -INFO - Auto-creating a Resource with id 'database1NonJta' of type 'DataSource for 'db1'. -INFO - Configuring Service(id=database1NonJta, type=Resource, provider-id=database1) -INFO - Adjusting PersistenceUnit db1 <non-jta-data-source> to Resource ID 'database1NonJta' from 'null' -INFO - Configuring PersistenceUnit(name=db2) -INFO - Auto-creating a Resource with id 'database2NonJta' of type 'DataSource for 'db2'. -INFO - Configuring Service(id=database2NonJta, type=Resource, provider-id=database2) -INFO - Adjusting PersistenceUnit db2 <non-jta-data-source> to Resource ID 'database2NonJta' from 'null' -INFO - Configuring PersistenceUnit(name=db3) -INFO - Auto-creating a Resource with id 'database3NonJta' of type 'DataSource for 'db3'. -INFO - Configuring Service(id=database3NonJta, type=Resource, provider-id=database3) -INFO - Adjusting PersistenceUnit db3 <non-jta-data-source> to Resource ID 'database3NonJta' from 'null' -INFO - Enterprise application "/Users/dblevins/examples/dynamic-datasource-routing" loaded. -INFO - Assembling app: /Users/dblevins/examples/dynamic-datasource-routing -INFO - PersistenceUnit(name=router, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 504ms -INFO - PersistenceUnit(name=db1, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 11ms -INFO - PersistenceUnit(name=db2, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 7ms -INFO - PersistenceUnit(name=db3, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 6ms -INFO - Jndi(name="java:global/dynamic-datasource-routing/BoostrapUtility!org.superbiz.dynamicdatasourcerouting.BoostrapUtility") -INFO - Jndi(name="java:global/dynamic-datasource-routing/BoostrapUtility") -INFO - Jndi(name="java:global/dynamic-datasource-routing/RoutedPersister!org.superbiz.dynamicdatasourcerouting.RoutedPersister") -INFO - Jndi(name="java:global/dynamic-datasource-routing/RoutedPersister") -INFO - Jndi(name="java:global/EjbModule1519652738/org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest!org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest") -INFO - Jndi(name="java:global/EjbModule1519652738/org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest") -INFO - Created Ejb(deployment-id=RoutedPersister, ejb-name=RoutedPersister, container=Default Stateless Container) -INFO - Created Ejb(deployment-id=org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest, ejb-name=org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest, container=Default Managed Container) -INFO - Created Ejb(deployment-id=BoostrapUtility, ejb-name=BoostrapUtility, container=Default Singleton Container) -INFO - Started Ejb(deployment-id=RoutedPersister, ejb-name=RoutedPersister, container=Default Stateless Container) -INFO - Started Ejb(deployment-id=org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest, ejb-name=org.superbiz.dynamicdatasourcerouting.DynamicDataSourceTest, container=Default Managed Container) -INFO - Started Ejb(deployment-id=BoostrapUtility, ejb-name=BoostrapUtility, container=Default Singleton Container) -INFO - Deployed Application(path=/Users/dblevins/examples/dynamic-datasource-routing) -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.504 sec - -Results : - -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ----- - - http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/efed31f4/src/main/jbake/content/examples/dynamic-implementation.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/dynamic-implementation.adoc b/src/main/jbake/content/examples/dynamic-implementation.adoc deleted file mode 100755 index 0ffff9c..0000000 --- a/src/main/jbake/content/examples/dynamic-implementation.adoc +++ /dev/null @@ -1,155 +0,0 @@ -= Dynamic Implementation -:jbake-date: 2016-09-06 -:jbake-type: page -:jbake-tomeepdf: -:jbake-status: published - -Example dynamic-implementation can be browsed at https://github.com/apache/tomee/tree/master/examples/dynamic-implementation - - -*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* - -== SocialBean - - -[source,java] ----- -package org.superbiz.dynamic; - -import org.apache.openejb.api.Proxy; - -import javax.ejb.Singleton; -import javax.interceptor.Interceptors; - -@Singleton -@Proxy(SocialHandler.class) -@Interceptors(SocialInterceptor.class) -public interface SocialBean { - public String facebookStatus(); - - public String twitterStatus(); - - public String status(); -} ----- - - -== SocialHandler - - -[source,java] ----- -package org.superbiz.dynamic; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -public class SocialHandler implements InvocationHandler { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String mtd = method.getName(); - if (mtd.toLowerCase().contains("facebook")) { - return "You think you have a life!"; - } else if (mtd.toLowerCase().contains("twitter")) { - return "Wow, you eat pop corn!"; - } - return "Hey, you have no virtual friend!"; - } -} ----- - - -== SocialInterceptor - - -[source,java] ----- -packagenull -} ----- - - -== SocialTest - - -[source,java] ----- -package org.superbiz.dynamic; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import javax.ejb.embeddable.EJBContainer; - -import static junit.framework.Assert.assertTrue; - -public class SocialTest { - private static SocialBean social; - private static EJBContainer container; - - @BeforeClass - public static void init() throws Exception { - container = EJBContainer.createEJBContainer(); - social = (SocialBean) container.getContext().lookup("java:global/dynamic-implementation/SocialBean"); - } - - @AfterClass - public static void close() { - container.close(); - } - - @Test - public void simple() { - assertTrue(social.facebookStatus().contains("think")); - assertTrue(social.twitterStatus().contains("eat")); - assertTrue(social.status().contains("virtual")); - } -} ----- - - -= Running - - - -[source] ----- -------------------------------------------------------- - T E S T S -------------------------------------------------------- -Running org.superbiz.dynamic.SocialTest -Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06 -http://tomee.apache.org/ -INFO - openejb.home = /Users/dblevins/examples/dynamic-implementation -INFO - openejb.base = /Users/dblevins/examples/dynamic-implementation -INFO - Using 'javax.ejb.embeddable.EJBContainer=true' -INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) -INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) -INFO - Found EjbModule in classpath: /Users/dblevins/examples/dynamic-implementation/target/classes -INFO - Beginning load: /Users/dblevins/examples/dynamic-implementation/target/classes -INFO - Configuring enterprise application: /Users/dblevins/examples/dynamic-implementation -INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container) -INFO - Auto-creating a container for bean SocialBean: Container(type=SINGLETON, id=Default Singleton Container) -INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) -INFO - Auto-creating a container for bean org.superbiz.dynamic.SocialTest: Container(type=MANAGED, id=Default Managed Container) -INFO - Enterprise application "/Users/dblevins/examples/dynamic-implementation" loaded. -INFO - Assembling app: /Users/dblevins/examples/dynamic-implementation -INFO - Jndi(name="java:global/dynamic-implementation/SocialBean!org.superbiz.dynamic.SocialBean") -INFO - Jndi(name="java:global/dynamic-implementation/SocialBean") -INFO - Jndi(name="java:global/EjbModule236706648/org.superbiz.dynamic.SocialTest!org.superbiz.dynamic.SocialTest") -INFO - Jndi(name="java:global/EjbModule236706648/org.superbiz.dynamic.SocialTest") -INFO - Created Ejb(deployment-id=org.superbiz.dynamic.SocialTest, ejb-name=org.superbiz.dynamic.SocialTest, container=Default Managed Container) -INFO - Created Ejb(deployment-id=SocialBean, ejb-name=SocialBean, container=Default Singleton Container) -INFO - Started Ejb(deployment-id=org.superbiz.dynamic.SocialTest, ejb-name=org.superbiz.dynamic.SocialTest, container=Default Managed Container) -INFO - Started Ejb(deployment-id=SocialBean, ejb-name=SocialBean, container=Default Singleton Container) -INFO - Deployed Application(path=/Users/dblevins/examples/dynamic-implementation) -INFO - Undeploying app: /Users/dblevins/examples/dynamic-implementation -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.107 sec - -Results : - -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ----- - - http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/efed31f4/src/main/jbake/content/examples/dynamic-proxy-to-access-mbean.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/dynamic-proxy-to-access-mbean.adoc b/src/main/jbake/content/examples/dynamic-proxy-to-access-mbean.adoc deleted file mode 100755 index ae03587..0000000 --- a/src/main/jbake/content/examples/dynamic-proxy-to-access-mbean.adoc +++ /dev/null @@ -1,460 +0,0 @@ -= dynamic-proxy-to-access-mbean -:jbake-date: 2016-09-06 -:jbake-type: page -:jbake-tomeepdf: -:jbake-status: published - -Example dynamic-proxy-to-access-mbean can be browsed at https://github.com/apache/tomee/tree/master/examples/dynamic-proxy-to-access-mbean - - -*Help us document this example! Click the blue pencil icon in the upper right to edit this page.* - -== Example - -Acessing MBean is something simple through the JMX API but it is often technical and not very interesting. - -This example simplify this work simply doing it generically in a proxy. - -So from an user side you simple declare an interface to access your MBeans. - -Note: the example implementation uses a local MBeanServer but enhancing the example API -it is easy to imagine a remote connection with user/password if needed. - -== ObjectName API (annotation) - -Simply an annotation to get the object - - -[source,java] ----- -package org.superbiz.dynamic.mbean; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -@Target({TYPE, METHOD}) -@Retention(RUNTIME) -public @interface ObjectName { - String value(); - - // for remote usage only - String url() default ""; - String user() default ""; - String password() default ""; -} ----- - - -== DynamicMBeanHandler (thr proxy implementation) - - -[source,java] ----- -package org.superbiz.dynamic.mbean; - -import javax.annotation.PreDestroy; -import javax.management.Attribute; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanServer; -import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Need a @PreDestroy method to disconnect the remote host when used in remote mode. - */ -public class DynamicMBeanHandler implements InvocationHandler { - private final Map<Method, ConnectionInfo> infos = new ConcurrentHashMap<Method, ConnectionInfo>(); - - @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - final String methodName = method.getName(); - if (method.getDeclaringClass().equals(Object.class) && "toString".equals(methodName)) { - return getClass().getSimpleName() + " Proxy"; - } - if (method.getAnnotation(PreDestroy.class) != null) { - return destroy(); - } - - final ConnectionInfo info = getConnectionInfo(method); - final MBeanInfo infos = info.getMBeanInfo(); - if (methodName.startsWith("set") && methodName.length() > 3 && args != null && args.length == 1 - && (Void.TYPE.equals(method.getReturnType()) || Void.class.equals(method.getReturnType()))) { - final String attributeName = attributeName(infos, methodName, method.getParameterTypes()[0]); - info.setAttribute(new Attribute(attributeName, args[0])); - return null; - } else if (methodName.startsWith("get") && (args == null || args.length == 0) && methodName.length() > 3) { - final String attributeName = attributeName(infos, methodName, method.getReturnType()); - return info.getAttribute(attributeName); - } - // operation - return info.invoke(methodName, args, getSignature(method)); - } - - public Object destroy() { - for (ConnectionInfo info : infos.values()) { - info.clean(); - } - infos.clear(); - return null; - } - - private String[] getSignature(Method method) { - String[] args = new String[method.getParameterTypes().length]; - for (int i = 0; i < method.getParameterTypes().length; i++) { - args[i] = method.getParameterTypes()[i].getName(); - } - return args; // note: null should often work... - } - - private String attributeName(MBeanInfo infos, String methodName, Class<?> type) { - String found = null; - String foundBackUp = null; // without checking the type - final String attributeName = methodName.substring(3, methodName.length()); - final String lowerName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4, methodName.length()); - - for (MBeanAttributeInfo attribute : infos.getAttributes()) { - final String name = attribute.getName(); - if (attributeName.equals(name)) { - foundBackUp = attributeName; - if (attribute.getType().equals(type.getName())) { - found = name; - } - } else if (found == null && ((lowerName.equals(name) && !attributeName.equals(name)) - || lowerName.equalsIgnoreCase(name))) { - foundBackUp = name; - if (attribute.getType().equals(type.getName())) { - found = name; - } - } - } - - if (found == null && foundBackUp == null) { - throw new UnsupportedOperationException("cannot find attribute " + attributeName); - } - - if (found != null) { - return found; - } - return foundBackUp; - } - - private synchronized ConnectionInfo getConnectionInfo(Method method) throws Exception { - if (!infos.containsKey(method)) { - synchronized (infos) { - if (!infos.containsKey(method)) { // double check for synchro - org.superbiz.dynamic.mbean.ObjectName on = method.getAnnotation(org.superbiz.dynamic.mbean.ObjectName.class); - if (on == null) { - Class<?> current = method.getDeclaringClass(); - do { - on = method.getDeclaringClass().getAnnotation(org.superbiz.dynamic.mbean.ObjectName.class); - current = current.getSuperclass(); - } while (on == null && current != null); - if (on == null) { - throw new UnsupportedOperationException("class or method should define the objectName to use for invocation: " + method.toGenericString()); - } - } - final ConnectionInfo info; - if (on.url().isEmpty()) { - info = new LocalConnectionInfo(); - ((LocalConnectionInfo) info).server = ManagementFactory.getPlatformMBeanServer(); // could use an id... - } else { - info = new RemoteConnectionInfo(); - final Map<String, String[]> environment = new HashMap<String, String[]>(); - if (!on.user().isEmpty()) { - environment.put(JMXConnector.CREDENTIALS, new String[]{ on.user(), on.password() }); - } - // ((RemoteConnectionInfo) info).connector = JMXConnectorFactory.newJMXConnector(new JMXServiceURL(on.url()), environment); - ((RemoteConnectionInfo) info).connector = JMXConnectorFactory.connect(new JMXServiceURL(on.url()), environment); - - } - info.objectName = new ObjectName(on.value()); - - infos.put(method, info); - } - } - } - return infos.get(method); - } - - private abstract static class ConnectionInfo { - protected ObjectName objectName; - - public abstract void setAttribute(Attribute attribute) throws Exception; - public abstract Object getAttribute(String attribute) throws Exception; - public abstract Object invoke(String operationName, Object params[], String signature[]) throws Exception; - public abstract MBeanInfo getMBeanInfo() throws Exception; - public abstract void clean(); - } - - private static class LocalConnectionInfo extends ConnectionInfo { - private MBeanServer server; - - @Override public void setAttribute(Attribute attribute) throws Exception { - server.setAttribute(objectName, attribute); - } - - @Override public Object getAttribute(String attribute) throws Exception { - return server.getAttribute(objectName, attribute); - } - - @Override - public Object invoke(String operationName, Object[] params, String[] signature) throws Exception { - return server.invoke(objectName, operationName, params, signature); - } - - @Override public MBeanInfo getMBeanInfo() throws Exception { - return server.getMBeanInfo(objectName); - } - - @Override public void clean() { - // no-op - } - } - - private static class RemoteConnectionInfo extends ConnectionInfo { - private JMXConnector connector; - private MBeanServerConnection connection; - - private void before() throws IOException { - connection = connector.getMBeanServerConnection(); - } - - private void after() throws IOException { - // no-op - } - - @Override public void setAttribute(Attribute attribute) throws Exception { - before(); - connection.setAttribute(objectName, attribute); - after(); - } - - @Override public Object getAttribute(String attribute) throws Exception { - before(); - try { - return connection.getAttribute(objectName, attribute); - } finally { - after(); - } - } - - @Override - public Object invoke(String operationName, Object[] params, String[] signature) throws Exception { - before(); - try { - return connection.invoke(objectName, operationName, params, signature); - } finally { - after(); - } - } - - @Override public MBeanInfo getMBeanInfo() throws Exception { - before(); - try { - return connection.getMBeanInfo(objectName); - } finally { - after(); - } - } - - @Override public void clean() { - try { - connector.close(); - } catch (IOException e) { - // no-op - } - } - } -} ----- - - -== Dynamic Proxies - -=== DynamicMBeanClient (the dynamic JMX client) - - package org.superbiz.dynamic.mbean; - - import org.apache.openejb.api.Proxy; - import org.superbiz.dynamic.mbean.DynamicMBeanHandler; - import org.superbiz.dynamic.mbean.ObjectName; - - import javax.ejb.Singleton; - - /** - * @author rmannibucau - */ - @Singleton - @Proxy(DynamicMBeanHandler.class) - @ObjectName(DynamicMBeanClient.OBJECT_NAME) - public interface DynamicMBeanClient { - static final String OBJECT_NAME = "test:group=DynamicMBeanClientTest"; - - int getCounter(); - void setCounter(int i); - int length(String aString); - } - -=== DynamicMBeanClient (the dynamic JMX client) - -[source,java] ----- -package org.superbiz.dynamic.mbean; - -import org.apache.openejb.api.Proxy; - -import javax.annotation.PreDestroy; -import javax.ejb.Singleton; - - -@Singleton -@Proxy(DynamicMBeanHandler.class) -@ObjectName(value = DynamicRemoteMBeanClient.OBJECT_NAME, url = "service:jmx:rmi:///jndi/rmi://localhost:8243/jmxrmi") -public interface DynamicRemoteMBeanClient { - static final String OBJECT_NAME = "test:group=DynamicMBeanClientTest"; - - int getCounter(); - void setCounter(int i); - int length(String aString); - - @PreDestroy void clean(); -} ----- - - -== The MBean used for the test - -=== SimpleMBean - - package org.superbiz.dynamic.mbean.simple; - - public interface SimpleMBean { - int length(String s); - - int getCounter(); - void setCounter(int c); - } - -== Simple - - package org.superbiz.dynamic.mbean.simple; - - public class Simple implements SimpleMBean { - private int counter = 0; - - @Override public int length(String s) { - if (s == null) { - return 0; - } - return s.length(); - } - - @Override public int getCounter() { - return counter; - } - - @Override public void setCounter(int c) { - counter = c; - } - } - -== DynamicMBeanClientTest (The test) - - -[source,java] ----- -package org.superbiz.dynamic.mbean; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.superbiz.dynamic.mbean.simple.Simple; - -import javax.ejb.EJB; -import javax.ejb.embeddable.EJBContainer; -import javax.management.Attribute; -import javax.management.ObjectName; -import java.lang.management.ManagementFactory; - -import static junit.framework.Assert.assertEquals; - -public class DynamicMBeanClientTest { - private static ObjectName objectName; - private static EJBContainer container; - - @EJB private DynamicMBeanClient localClient; - @EJB private DynamicRemoteMBeanClient remoteClient; - - @BeforeClass public static void start() { - container = EJBContainer.createEJBContainer(); - } - - @Before public void injectAndRegisterMBean() throws Exception { - container.getContext().bind("inject", this); - objectName = new ObjectName(DynamicMBeanClient.OBJECT_NAME); - ManagementFactory.getPlatformMBeanServer().registerMBean(new Simple(), objectName); - } - - @After public void unregisterMBean() throws Exception { - if (objectName != null) { - ManagementFactory.getPlatformMBeanServer().unregisterMBean(objectName); - } - } - - @Test public void localGet() throws Exception { - assertEquals(0, localClient.getCounter()); - ManagementFactory.getPlatformMBeanServer().setAttribute(objectName, new Attribute("Counter", 5)); - assertEquals(5, localClient.getCounter()); - } - - @Test public void localSet() throws Exception { - assertEquals(0, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, "Counter")).intValue()); - localClient.setCounter(8); - assertEquals(8, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, "Counter")).intValue()); - } - - @Test public void localOperation() { - assertEquals(7, localClient.length("openejb")); - } - - @Test public void remoteGet() throws Exception { - assertEquals(0, remoteClient.getCounter()); - ManagementFactory.getPlatformMBeanServer().setAttribute(objectName, new Attribute("Counter", 5)); - assertEquals(5, remoteClient.getCounter()); - } - - @Test public void remoteSet() throws Exception { - assertEquals(0, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, "Counter")).intValue()); - remoteClient.setCounter(8); - assertEquals(8, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, "Counter")).intValue()); - } - - @Test public void remoteOperation() { - assertEquals(7, remoteClient.length("openejb")); - } - - @AfterClass public static void close() { - if (container != null) { - container.close(); - } - } -} ----- - - http://git-wip-us.apache.org/repos/asf/tomee-site-generator/blob/efed31f4/src/main/jbake/content/examples/ear-testing.adoc ---------------------------------------------------------------------- diff --git a/src/main/jbake/content/examples/ear-testing.adoc b/src/main/jbake/content/examples/ear-testing.adoc deleted file mode 100755 index eac0b6d..0000000 --- a/src/main/jbake/content/examples/ear-testing.adoc +++ /dev/null @@ -1,244 +0,0 @@ -= EAR Testing -:jbake-date: 2016-09-06 -:jbake-type: page -:jbake-tomeepdf: -:jbake-status: published - -Example ear-testing can be browsed at https://github.com/apache/tomee/tree/master/examples/ear-testing - - -The goal of this example is to demonstrate how maven projects might be organized in a more real world style and how testing with OpenEJB can fit into that structure. - -This example takes the basic moviefun code we us in many of examples and splits it into two modules: - - - `business-logic` - - `business-model` - -As the names imply, we keep our `@Entity` beans in the `business-model` module and our session beans in the `business-logic` model. The tests located and run from the business logic module. - - ear-testing - ear-testing/business-logic - ear-testing/business-logic/pom.xml - ear-testing/business-logic/src/main/java/org/superbiz/logic/Movies.java - ear-testing/business-logic/src/main/java/org/superbiz/logic/MoviesImpl.java - ear-testing/business-logic/src/main/resources - ear-testing/business-logic/src/main/resources/META-INF - ear-testing/business-logic/src/main/resources/META-INF/ejb-jar.xml - ear-testing/business-logic/src/test/java/org/superbiz/logic/MoviesTest.java - ear-testing/business-model - ear-testing/business-model/pom.xml - ear-testing/business-model/src/main/java/org/superbiz/model/Movie.java - ear-testing/business-model/src/main/resources/META-INF/persistence.xml - ear-testing/pom.xml - -= Project configuration - -The parent pom, trimmed to the minimum, looks like so: - - -[source,xml] ----- -<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"> - - <modelVersion>4.0.0</modelVersion> - <groupId>org.superbiz</groupId> - <artifactId>myear</artifactId> - <version>1.1.0-SNAPSHOT</version> - - <packaging>pom</packaging> - - <modules> - <module>business-model</module> - <module>business-logic</module> - </modules> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>javaee-api</artifactId> - <version>6.0-2</version> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.8.1</version> - </dependency> - </dependencies> - </dependencyManagement> -</project> ----- - - -The `business-model/pom.xml` as follows: - - -[source,xml] ----- -<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> - <groupId>org.superbiz</groupId> - <artifactId>myear</artifactId> - <version>1.1.0-SNAPSHOT</version> - </parent> - - <modelVersion>4.0.0</modelVersion> - - <artifactId>business-model</artifactId> - <packaging>jar</packaging> - - <dependencies> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>javaee-api</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - - </dependencies> - -</project> ----- - - -And finally, the `business-logic/pom.xml` which is setup to support embedded testing with OpenEJB: - - -[source,xml] ----- -<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> - <groupId>org.superbiz</groupId> - <artifactId>myear</artifactId> - <version>1.1.0-SNAPSHOT</version> - </parent> - - <modelVersion>4.0.0</modelVersion> - - <artifactId>business-logic</artifactId> - <packaging>jar</packaging> - - <dependencies> - <dependency> - <groupId>org.superbiz</groupId> - <artifactId>business-model</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>javaee-api</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <!-- - The <scope>test</scope> guarantees that non of your runtime - code is dependent on any OpenEJB classes. - --> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>openejb-core</artifactId> - <version>7.0.0-SNAPSHOT</version> - <scope>test</scope> - </dependency> - </dependencies> -</project> ----- - - -= TestCode - -The test code is the same as always: - - -[source,java] ----- -public class MoviesTest extends TestCase { - - public void test() throws Exception { - Properties p = new Properties(); - p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory"); - - p.put("openejb.deployments.classpath.ear", "true"); - - p.put("movieDatabase", "new://Resource?type=DataSource"); - p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver"); - p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); - - p.put("movieDatabaseUnmanaged", "new://Resource?type=DataSource"); - p.put("movieDatabaseUnmanaged.JdbcDriver", "org.hsqldb.jdbcDriver"); - p.put("movieDatabaseUnmanaged.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); - p.put("movieDatabaseUnmanaged.JtaManaged", "false"); - - Context context = new InitialContext(p); - - Movies movies = (Movies) context.lookup("MoviesLocal"); - - movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992)); - movies.addMovie(new Movie("Joel Coen", "Fargo", 1996)); - movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998)); - - List<Movie> list = movies.getMovies(); - assertEquals("List.size()", 3, list.size()); - - for (Movie movie : list) { - movies.deleteMovie(movie); - } - - assertEquals("Movies.getMovies()", 0, movies.getMovies().size()); - } -} ----- - - - -= Running - - - -[source] ----- -------------------------------------------------------- - T E S T S -------------------------------------------------------- -Running org.superbiz.logic.MoviesTest -Apache OpenEJB 7.0.0-SNAPSHOT build: 20111002-04:06 -http://tomee.apache.org/ -INFO - openejb.home = /Users/dblevins/examples/ear-testing/business-logic -INFO - openejb.base = /Users/dblevins/examples/ear-testing/business-logic -INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) -INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) -INFO - Configuring Service(id=movieDatabaseUnmanaged, type=Resource, provider-id=Default JDBC Database) -INFO - Configuring Service(id=movieDatabase, type=Resource, provider-id=Default JDBC Database) -INFO - Found PersistenceModule in classpath: /Users/dblevins/examples/ear-testing/business-model/target/business-model-1.0.jar -INFO - Found EjbModule in classpath: /Users/dblevins/examples/ear-testing/business-logic/target/classes -INFO - Using 'openejb.deployments.classpath.ear=true' -INFO - Beginning load: /Users/dblevins/examples/ear-testing/business-model/target/business-model-1.0.jar -INFO - Beginning load: /Users/dblevins/examples/ear-testing/business-logic/target/classes -INFO - Configuring enterprise application: /Users/dblevins/examples/ear-testing/business-logic/classpath.ear -INFO - Configuring Service(id=Default Stateful Container, type=Container, provider-id=Default Stateful Container) -INFO - Auto-creating a container for bean Movies: Container(type=STATEFUL, id=Default Stateful Container) -INFO - Configuring PersistenceUnit(name=movie-unit) -INFO - Enterprise application "/Users/dblevins/examples/ear-testing/business-logic/classpath.ear" loaded. -INFO - Assembling app: /Users/dblevins/examples/ear-testing/business-logic/classpath.ear -INFO - PersistenceUnit(name=movie-unit, provider=org.apache.openjpa.persistence.PersistenceProviderImpl) - provider time 415ms -INFO - Jndi(name=MoviesLocal) --> Ejb(deployment-id=Movies) -INFO - Jndi(name=global/classpath.ear/business-logic/Movies!org.superbiz.logic.Movies) --> Ejb(deployment-id=Movies) -INFO - Jndi(name=global/classpath.ear/business-logic/Movies) --> Ejb(deployment-id=Movies) -INFO - Created Ejb(deployment-id=Movies, ejb-name=Movies, container=Default Stateful Container) -INFO - Started Ejb(deployment-id=Movies, ejb-name=Movies, container=Default Stateful Container) -INFO - Deployed Application(path=/Users/dblevins/examples/ear-testing/business-logic/classpath.ear) -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.393 sec - -Results : - -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ----- -
