Liran Zelkha has uploaded a new change for review.

Change subject: core: Infra for injecting beans in external JARs
......................................................................

core: Infra for injecting beans in external JARs

This patch introduces a ModuleExtension that can inject beans that are not
part of the EAR file. This is a limitation of JBoss 7, which is fixed in future 
versions.
Once we stop supporting older jboss - this code can be safely removed

Change-Id: I3b3c2c57178b5df4f98b4191ac9a06f9129414d0
Bug-Url: https://bugzilla.redhat.com/1159621
Signed-off-by: lzel...@redhat.com <lzel...@redhat.com>
---
M backend/manager/dependencies/common/pom.xml
A 
backend/manager/dependencies/common/src/main/modules/org/deltaspike/main/module.xml
A 
backend/manager/dependencies/common/src/main/modules/org/reflections/main/module.xml
M backend/manager/modules/bll/pom.xml
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/Injector.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/ModuleConfigurationExtension.java
A 
backend/manager/modules/bll/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/SimpleDependecyInjector.java
M 
backend/manager/modules/dal/src/main/modules/org/ovirt/engine/core/dal/main/module.xml
D 
backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/CustomizedContextLoader.java
A backend/manager/modules/dal/src/test/resources/test-beans.xml
M ear/src/main/resources/META-INF/MANIFEST.MF
M pom.xml
13 files changed, 226 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/39/37439/1

diff --git a/backend/manager/dependencies/common/pom.xml 
b/backend/manager/dependencies/common/pom.xml
index 87bd5b9..d4920bd 100644
--- a/backend/manager/dependencies/common/pom.xml
+++ b/backend/manager/dependencies/common/pom.xml
@@ -379,6 +379,24 @@
       <version>${jackson.version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.deltaspike.core</groupId>
+      <artifactId>deltaspike-core-api</artifactId>
+      <version>${deltaspike.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.deltaspike.core</groupId>
+      <artifactId>deltaspike-core-impl</artifactId>
+      <version>${deltaspike.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.reflections</groupId>
+      <artifactId>reflections</artifactId>
+      <version>${reflections.version}</version>
+    </dependency>
+
   </dependencies>
 
   <build>
@@ -734,6 +752,24 @@
                 <moduleName>org.codehaus.jackson.jackson-xc</moduleName>
               </module>
 
+              <module>
+                <groupId>org.apache.deltaspike.core</groupId>
+                <artifactId>deltaspike-core-api</artifactId>
+                <moduleName>org.deltaspike</moduleName>
+              </module>
+
+              <module>
+                <groupId>org.apache.deltaspike.core</groupId>
+                <artifactId>deltaspike-core-impl</artifactId>
+                <moduleName>org.deltaspike</moduleName>
+              </module>
+
+              <module>
+                <groupId>org.reflections</groupId>
+                <artifactId>reflections</artifactId>
+                <moduleName>org.reflections</moduleName>
+              </module>
+
             </modules>
           </configuration>
         </plugin>
diff --git 
a/backend/manager/dependencies/common/src/main/modules/org/deltaspike/main/module.xml
 
b/backend/manager/dependencies/common/src/main/modules/org/deltaspike/main/module.xml
new file mode 100644
index 0000000..323bb1e
--- /dev/null
+++ 
b/backend/manager/dependencies/common/src/main/modules/org/deltaspike/main/module.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.deltaspike">
+
+    <resources>
+        <resource-root path="deltaspike-core-api.jar" />
+        <resource-root path="deltaspike-core-impl.jar" />
+    </resources>
+
+    <dependencies>
+        <module name="com.google.guava" />
+        <module name="javax.enterprise.api" />
+        <module name="javax.inject.api" />
+    </dependencies>
+</module>
diff --git 
a/backend/manager/dependencies/common/src/main/modules/org/reflections/main/module.xml
 
b/backend/manager/dependencies/common/src/main/modules/org/reflections/main/module.xml
new file mode 100644
index 0000000..88d66f9
--- /dev/null
+++ 
b/backend/manager/dependencies/common/src/main/modules/org/reflections/main/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.reflections">
+
+    <resources>
+        <resource-root path="reflections.jar" />
+    </resources>
+
+    <dependencies>
+        <module name="com.google.guava" />
+        <module name="org.javassist" />
+        <module name="org.slf4j" />
+    </dependencies>
+</module>
diff --git a/backend/manager/modules/bll/pom.xml 
b/backend/manager/modules/bll/pom.xml
index 6d70c82..240bf1d 100644
--- a/backend/manager/modules/bll/pom.xml
+++ b/backend/manager/modules/bll/pom.xml
@@ -163,6 +163,39 @@
         <artifactId>cdi-api</artifactId>
         <scope>provided</scope>
      </dependency>
+     <dependency>
+         <groupId>org.scala-lang</groupId>
+         <artifactId>scala-library</artifactId>
+         <version>2.10.4</version>
+     </dependency>
+     <dependency>
+         <groupId>org.springframework.boot</groupId>
+         <artifactId>spring-boot-starter-test</artifactId>
+         <version>1.1.4.RELEASE</version>
+         <scope>test</scope>
+     </dependency>
+     <dependency>
+         <groupId>javax.enterprise</groupId>
+         <artifactId>cdi-api</artifactId>
+         <version>1.0-SP4</version>
+     </dependency>
+     <dependency>
+         <groupId>org.apache.deltaspike.core</groupId>
+         <artifactId>deltaspike-core-api</artifactId>
+         <version>${deltaspike.version}</version>
+         <scope>compile</scope>
+     </dependency>
+     <dependency>
+         <groupId>org.apache.deltaspike.core</groupId>
+         <artifactId>deltaspike-core-impl</artifactId>
+         <version>${deltaspike.version}</version>
+         <scope>runtime</scope>
+     </dependency>
+     <dependency>
+         <groupId>org.reflections</groupId>
+         <artifactId>reflections</artifactId>
+         <version>${reflections.version}</version>
+     </dependency>
   </dependencies>
 
   <build>
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/Injector.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/Injector.java
index 1d06274..77fcf73 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/Injector.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/Injector.java
@@ -8,9 +8,6 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.ovirt.engine.core.bll.CommandBase;
-import org.ovirt.engine.core.common.action.VdcActionParametersBase;
-
 /**
  * an application wide interaction point with the CDI container mostly to gap 
all the existing unmanged code
  * or for unmanaged code which wants interaction with managed beans.
@@ -38,7 +35,7 @@
      * @param <T> an unmanaged CDI instance with some members containing 
<code>@Inject</code> annotated
      *           members
      */
-    public static <T extends  CommandBase<? extends VdcActionParametersBase>> 
T injectMembers(T instance) {
+    public static <T> T injectMembers(T instance) {
         AnnotatedType type = 
injector.manager.createAnnotatedType(instance.getClass());
         InjectionTarget injectionTarget = 
injector.manager.createInjectionTarget(type);
         injectionTarget.inject(instance, 
injector.manager.createCreationalContext(null));
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/ModuleConfigurationExtension.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/ModuleConfigurationExtension.java
new file mode 100644
index 0000000..42d6445
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/ModuleConfigurationExtension.java
@@ -0,0 +1,97 @@
+package org.ovirt.engine.core.bll.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.deltaspike.core.util.bean.BeanBuilder;
+import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
+import org.reflections.Reflections;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class ModuleConfigurationExtension implements Extension {
+    private static final Logger log = 
LoggerFactory.getLogger(ModuleConfigurationExtension.class);
+    private final Map<String, AnnotatedType<Object>> beans = new HashMap<>();
+
+    /**
+     * This method is automatically activated by CDI, and loads all classes in 
the org.ovirt package that has NAMED or
+     * SINGLETON annotations.
+     * @param bdd
+     */
+    void readAllConfigurations(final @Observes BeforeBeanDiscovery bdd, 
BeanManager bm) {
+        log.info("Starting to load beans from modules");
+        addBeansFromPackage(bdd, bm, "org.ovirt.engine.core.dal");
+        addBeansFromPackage(bdd, bm, "org.ovirt.engine.core.dao");
+    }
+
+    private void addBeansFromPackage(final BeforeBeanDiscovery bdd, 
BeanManager bm, String packageName) {
+        Reflections reflections = new Reflections(packageName);
+        Set<Class<?>> beanClasses = 
reflections.getTypesAnnotatedWith(Named.class);
+        beanClasses.addAll(reflections.getTypesAnnotatedWith(Singleton.class));
+
+        for (Class<?> bean : beanClasses) {
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            AnnotatedType<Object> annotatedType = new 
AnnotatedTypeBuilder().readFromType(bean).create();
+            Set<Bean<?>> foundBeans = bm.getBeans(annotatedType.getBaseType(), 
new AnnotationLiteral<Any>() {
+            });
+
+            if (foundBeans.size() == 0) {
+                bdd.addAnnotatedType(annotatedType);
+                String name;
+                Named named = bean.getAnnotation(Named.class);
+                if (named == null || Strings.isNullOrEmpty(named.value())) {
+                    name = bean.getSimpleName();
+                } else {
+                    name = named.value();
+                }
+                beans.put(name, annotatedType);
+            }
+        }
+    }
+
+    /**
+     * This method actually initializes the beans we discovered in 
<code>readAllConfigurations</code>. Again - this
+     * method is automatically activated by CDI
+     * @param abd
+     * @param bm
+     * @throws Exception
+     */
+    public void addCdiBeans(final @Observes AfterBeanDiscovery abd, final 
BeanManager bm) throws Exception {
+        log.info("Starting to initialize beans from modules");
+
+        for (Map.Entry<String, AnnotatedType<Object>> bean : beans.entrySet()) 
{
+            Set<Bean<?>> foundBeans = 
bm.getBeans(bean.getValue().getBaseType());
+            if (foundBeans.size() == 0) {
+                final Bean<Object> cdiBean = createBean(bm, bean.getKey(), 
bean.getValue());
+                abd.addBean(cdiBean);
+                log.debug("Added bean " + cdiBean.getName());
+            }
+        }
+    }
+
+    private static Bean<Object> createBean(final BeanManager bm,
+            final String name,
+            final AnnotatedType<Object> annotatedType)
+            throws Exception {
+        final BeanBuilder<Object> beanBuilder = new BeanBuilder<Object>(bm).
+                readFromType(annotatedType).
+                name(name);
+
+        return beanBuilder.create();
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
 
b/backend/manager/modules/bll/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..2184d5b
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.ovirt.engine.core.bll.utils.ModuleConfigurationExtension
\ No newline at end of file
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/SimpleDependecyInjector.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/SimpleDependecyInjector.java
index 03ba93c..85da37a 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/SimpleDependecyInjector.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/SimpleDependecyInjector.java
@@ -63,6 +63,7 @@
      * @param <T>
      * @return
      */
+    @SuppressWarnings("unchecked")
     public <T> T get(Class<T> clazz) {
         return (T) map.get(clazz.getName());
     }
diff --git 
a/backend/manager/modules/dal/src/main/modules/org/ovirt/engine/core/dal/main/module.xml
 
b/backend/manager/modules/dal/src/main/modules/org/ovirt/engine/core/dal/main/module.xml
index 43f6a82..8115488 100644
--- 
a/backend/manager/modules/dal/src/main/modules/org/ovirt/engine/core/dal/main/module.xml
+++ 
b/backend/manager/modules/dal/src/main/modules/org/ovirt/engine/core/dal/main/module.xml
@@ -7,7 +7,9 @@
   </resources>
 
   <dependencies>
+    <module name="javax.annotation.api"/>
     <module name="javax.api"/>
+    <module name="javax.inject.api"/>
     <module name="javax.transaction.api"/>
     <module name="org.apache.commons.collections"/>
     <module name="org.apache.commons.lang"/>
diff --git 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/CustomizedContextLoader.java
 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/CustomizedContextLoader.java
deleted file mode 100644
index 3a1a830..0000000
--- 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/CustomizedContextLoader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.ovirt.engine.core.dao;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.GenericApplicationContext;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-import org.springframework.test.context.MergedContextConfiguration;
-import org.springframework.test.context.support.AbstractContextLoader;
-
-/**
- * This class is used to provide load the application context for the spring 
framework in a custom way. The
- * customization is for providing the transaction manager that is using the 
data source from the BaseDAOTestCase.
- *
- */
-public class CustomizedContextLoader extends AbstractContextLoader {
-
-    @Override
-    protected String getResourceSuffix() {
-        return "dummy";
-    }
-
-    @Override
-    public ApplicationContext loadContext(String ... locations) throws 
Exception {
-        return doLoadContext();
-    }
-
-    @Override
-    public ApplicationContext loadContext(MergedContextConfiguration 
mergedConfig) throws Exception {
-        return doLoadContext();
-    }
-
-    private ApplicationContext doLoadContext() throws Exception {
-        // initialize spring application context to enable transaction support 
within
-        // the Spring TestContext Framework
-        GenericApplicationContext ctx = new GenericApplicationContext() {
-            @SuppressWarnings("unchecked")
-            @Override
-            public Object getBean(String name, Class requiredType) throws 
BeansException {
-                if ("transactionManager".equals(name)) {
-                    DataSource dataSource = BaseDAOTestCase.getDataSource();
-                    if (dataSource != null) {
-                        DataSourceTransactionManager transactionManager = new 
DataSourceTransactionManager(dataSource);
-                        transactionManager.afterPropertiesSet();
-                        return transactionManager;
-                    }
-                    else {
-                        System.err.println("loading context for transaction 
management but data source is not initializaed yet. "
-                                +
-                                "Please make sure datasource is initializaed 
in BaseDAOTestCase before loading the test context.");
-                        throw new IllegalStateException("datasource is not 
initializaed");
-                    }
-                }
-                return super.getBean(name, requiredType);
-            }
-        };
-        return ctx;
-    }
-}
diff --git a/backend/manager/modules/dal/src/test/resources/test-beans.xml 
b/backend/manager/modules/dal/src/test/resources/test-beans.xml
new file mode 100644
index 0000000..f490b71
--- /dev/null
+++ b/backend/manager/modules/dal/src/test/resources/test-beans.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:p="http://www.springframework.org/schema/p";
+    xmlns:context="http://www.springframework.org/schema/context";
+
+    xsi:schemaLocation="
+    http://www.springframework.org/schema/beans
+    http://www.springframework.org/schema/beans/spring-beans.xsd
+    http://www.springframework.org/schema/context
+    http://www.springframework.org/schema/context/spring-context.xsd";>
+
+    <context:component-scan base-package="org.ovirt.engine" />
+    <context:annotation-config />
+
+    <bean name="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+        <constructor-arg ref="DataSource"/>
+    </bean>
+    <bean id="DataSource" class="org.ovirt.engine.core.dao.BaseDAOTestCase"  
factory-method="getDataSource" />
+</beans>
\ No newline at end of file
diff --git a/ear/src/main/resources/META-INF/MANIFEST.MF 
b/ear/src/main/resources/META-INF/MANIFEST.MF
index 3f34aed..16c4496 100644
--- a/ear/src/main/resources/META-INF/MANIFEST.MF
+++ b/ear/src/main/resources/META-INF/MANIFEST.MF
@@ -1,5 +1,6 @@
 Manifest-Version: 1.0
 Dependencies: asm.asm,
+ com.google.guava,
  javax.validation.api,
  org.apache.commons.beanutils,
  org.apache.commons.codec,
@@ -10,12 +11,13 @@
  org.apache.xmlrpc,
  org.codehaus.jackson.jackson-core-asl,
  org.codehaus.jackson.jackson-mapper-asl,
+ org.deltaspike,
  org.dom4j,
  org.hibernate.validator,
  org.infinispan,
  org.ovirt.engine.core.common,
  org.ovirt.engine.core.compat,
- org.ovirt.engine.core.dal,
+ org.ovirt.engine.core.dal meta-inf,
  org.ovirt.engine.core.searchbackend,
  org.ovirt.engine.core.utils,
  org.ovirt.engine.core.uutils,
@@ -27,6 +29,7 @@
  org.ovirt.engine.api.ovirt-engine-extensions-api,
  org.ovirt.vdsm-jsonrpc-java,
  org.quartz,
+ org.reflections,
  org.slf4j,
  org.springframework,
  com.woorea.openstack.sdk services,
diff --git a/pom.xml b/pom.xml
index 8350ea5..aa593fb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,6 +110,9 @@
     
<gwt-maven-plugin.workingRefresh.version>2.4.0</gwt-maven-plugin.workingRefresh.version>
     <cdi.api.version>1.0-SP4</cdi.api.version>
     <javacc.version>2.6</javacc.version>
+    <antlr.version>4.2.2</antlr.version>
+    <deltaspike.version>1.1.0</deltaspike.version>
+    <reflections.version>0.9.9-RC1</reflections.version>
   </properties>
   <dependencyManagement>
     <dependencies>


-- 
To view, visit http://gerrit.ovirt.org/37439
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3b3c2c57178b5df4f98b4191ac9a06f9129414d0
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Liran Zelkha <lzel...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to