From 6c692bd5843eb2d5f873b7ae5bbf7aa76b5e8f35 Mon Sep 17 00:00:00 2001
From: Dancovich
Date: Wed, 22 May 2013 15:00:12 -0300
Subject: [PATCH] -Reparado problema onde o módulo de gerenciamento não conseguia injetar classes ManagementController que fossem anotadas com qualifiers. -Ajuste nos testes do demoiselle-jmx -Alteração de mensagens de erro
---
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ManagementBootstrap.java | 11 +++++++++++
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java | 59 +++++++++++++++++++++++++++++++++++++++++++++--------------
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java | 7 ++++---
impl/core/src/main/java/br/gov/frameworkdemoiselle/stereotype/ManagementController.java | 4 +++-
impl/core/src/main/resources/demoiselle-core-bundle.properties | 5 +++--
impl/extension/jmx/src/test/java/management/tests/internal/DynamicMBeanProxyTestCase.java | 20 +++++++++++++++-----
impl/extension/jmx/src/test/java/management/tests/internal/NotificationBroadcasterTestCase.java | 5 +++--
impl/extension/jmx/src/test/java/management/tests/internal/RemoteManagementTestCase.java | 90 ------------------------------------------------------------------------------------------
impl/extension/jmx/src/test/resources/META-INF/beans.xml | 6 +++++-
impl/extension/jmx/src/test/resources/META-INF/persistence.xml | 22 ----------------------
10 files changed, 89 insertions(+), 140 deletions(-)
delete mode 100644 impl/extension/jmx/src/test/java/management/tests/internal/RemoteManagementTestCase.java
delete mode 100644 impl/extension/jmx/src/test/resources/META-INF/persistence.xml
diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ManagementBootstrap.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ManagementBootstrap.java
index f9f81bd..3bcea0a 100644
--- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ManagementBootstrap.java
+++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ManagementBootstrap.java
@@ -1,8 +1,10 @@
package br.gov.frameworkdemoiselle.internal.bootstrap;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import javax.enterprise.event.Observes;
@@ -15,13 +17,16 @@ import javax.enterprise.inject.spi.BeforeShutdown;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import br.gov.frameworkdemoiselle.DemoiselleException;
import br.gov.frameworkdemoiselle.internal.context.ContextManager;
import br.gov.frameworkdemoiselle.internal.context.ManagedContext;
import br.gov.frameworkdemoiselle.internal.management.ManagedType;
import br.gov.frameworkdemoiselle.internal.management.Management;
+import br.gov.frameworkdemoiselle.internal.producer.ResourceBundleProducer;
import br.gov.frameworkdemoiselle.lifecycle.ManagementExtension;
import br.gov.frameworkdemoiselle.stereotype.ManagementController;
import br.gov.frameworkdemoiselle.util.Beans;
+import br.gov.frameworkdemoiselle.util.ResourceBundle;
public class ManagementBootstrap implements Extension {
@@ -43,8 +48,14 @@ public class ManagementBootstrap implements Extension {
@SuppressWarnings("unchecked")
public void registerAvailableManagedTypes(@Observes final AfterDeploymentValidation event,BeanManager beanManager) {
+ ResourceBundle bundle = ResourceBundleProducer.create("demoiselle-core-bundle", Locale.getDefault());
+
Management monitoringManager = Beans.getReference(Management.class);
for (AnnotatedType> type : types) {
+ if (type.getJavaClass().isInterface() || Modifier.isAbstract(type.getJavaClass().getModifiers()) ){
+ throw new DemoiselleException(bundle.getString("management-abstract-class-defined" , type.getJavaClass().getCanonicalName()));
+ }
+
ManagedType managedType = new ManagedType(type.getJavaClass());
monitoringManager.addManagedType(managedType);
}
diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java
index 57b1051..2f38593 100644
--- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java
+++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java
@@ -39,8 +39,11 @@ package br.gov.frameworkdemoiselle.internal.management;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.TreeMap;
+import javax.inject.Qualifier;
+
import br.gov.frameworkdemoiselle.DemoiselleException;
import br.gov.frameworkdemoiselle.annotation.ManagedOperation;
import br.gov.frameworkdemoiselle.annotation.ManagedProperty;
@@ -60,6 +63,8 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
public class ManagedType {
private Class> type;
+
+ private Annotation[] qualifiers;
private TreeMap fields;
@@ -83,6 +88,7 @@ public class ManagedType {
fields = new TreeMap();
operationMethods = new TreeMap();
this.description = type.getAnnotation(ManagementController.class).description();
+ this.qualifiers = getQualifierAnnotations(type);
initialize();
}
@@ -102,6 +108,18 @@ public class ManagedType {
public TreeMap getOperationMethods() {
return operationMethods;
}
+
+ /**
+ * Return a (possibly empty) list of all qualifiers this type have. Qualifiers
+ * are any annotations marked as {@link Qualifier}.
+ *
+ * This method returns the true list of qualifiers. If implementators change this list, it will
+ * affect future calls of this method. This is so that resources can be spared by not creating many instances of this list.
+ *
+ */
+ public Annotation[] getQualifiers(){
+ return this.qualifiers;
+ }
private void initialize() {
// Para cada atributo verifica se ele está anotado com ManagedProperty e extrai as informações dele (método get, set e
@@ -224,6 +242,33 @@ public class ManagedType {
return setterMethod;
}
+
+ /**
+ * Indicates another {@link ManagedType} represents the same {@link Class} as this one. This method also supports a
+ * {@link Class} as a parameter, in this case it will return true
if the passed class is exactly the
+ * same Java class represented by this {@link ManagedType}.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == null) {
+ return false;
+ }
+
+ return ((ManagedType) other).getType().getCanonicalName().equals(this.getType().getCanonicalName());
+ }
+
+ private synchronized Annotation[] getQualifierAnnotations(Class> beanClass){
+ Annotation[] annotations = beanClass.getAnnotations();
+ ArrayList qualifiers = new ArrayList(annotations.length);
+
+ for (int i=0; itrue if the passed class is exactly the
- * same Java class represented by this {@link ManagedType}.
- */
- @Override
- public boolean equals(Object other) {
- if (other == null) {
- return false;
- }
-
- return ((ManagedType) other).getType().getCanonicalName().equals(this.getType().getCanonicalName());
- }
}
diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java
index 4d06295..d3158aa 100644
--- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java
+++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java
@@ -129,7 +129,7 @@ public class Management {
activateContexts(managedType.getType());
try {
- Object delegate = Beans.getReference(managedType.getType());
+ Object delegate = Beans.getReference(managedType.getType() , managedType.getQualifiers());
MethodDetail method = managedType.getOperationMethods().get(actionName);
if (method != null) {
@@ -179,7 +179,7 @@ public class Management {
activateContexts(managedType.getType());
try {
- Object delegate = Beans.getReference(managedType.getType());
+ Object delegate = Beans.getReference(managedType.getType() , managedType.getQualifiers());
return getterMethod.invoke(delegate, (Object[]) null);
} catch (Exception e) {
@@ -227,7 +227,7 @@ public class Management {
// Obtém uma instância da classe gerenciada, lembrando que
// classes
// anotadas com @ManagementController são sempre singletons.
- Object delegate = Beans.getReference(managedType.getType());
+ Object delegate = Beans.getReference(managedType.getType() , managedType.getQualifiers() );
// Se houver um validador anexado à propriedade alterada, executa o validador sobre
// o novo valor.
@@ -343,5 +343,6 @@ public class Management {
return this.validator;
}
+
}
diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/stereotype/ManagementController.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/stereotype/ManagementController.java
index 9f2e7d6..89ff9b8 100644
--- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/stereotype/ManagementController.java
+++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/stereotype/ManagementController.java
@@ -49,12 +49,14 @@ import javax.enterprise.inject.Stereotype;
import javax.enterprise.util.Nonbinding;
/**
- * Identifies a management controller class. What it means is that an external client can manage the application
+ *
Identifies a management controller bean. What it means is that an external client can manage the application
* this class is in by reading or writing it's attributes and calling it's operations.
*
* Only fields annotated with {@link br.gov.frameworkdemoiselle.annotation.ManagedProperty} or
* methods annotated with {@link br.gov.frameworkdemoiselle.annotation.ManagedOperation} will be exposed
* to clients.
+ * Only bean implementations (concrete classes) can be management controllers. It's a runtime error to mark an interface
+ * or abstract class with this annotation.
* This stereotype only defines a class as managed, you need to choose an extension that will expose this managed class
* to external clients using any technology available. One example is the Demoiselle JMX extension, that will expose
* managed classes as MBeans.
diff --git a/impl/core/src/main/resources/demoiselle-core-bundle.properties b/impl/core/src/main/resources/demoiselle-core-bundle.properties
index 6984a5f..0197197 100644
--- a/impl/core/src/main/resources/demoiselle-core-bundle.properties
+++ b/impl/core/src/main/resources/demoiselle-core-bundle.properties
@@ -102,8 +102,9 @@ user-has-role=Usu\u00E1rio {0} possui a(s) role(s)\: {1}
authenticator-not-defined=Nenhum mecanismo de autentica\u00E7\u00E3o foi definido. Para utilizar {0} \u00E9 preciso definir a propriedade frameworkdemoiselle.security.authenticator.class como mecanismo de autentica\u00E7\u00E3o desejado no arquivo demoiselle.properties.
management-notification-attribute-changed=O atributo [{0}] da classe gerenciada [{1}] foi alterado
-management-null-class-defined=A classe gerenciada informada n\u00E3o pode ser nula
-management-no-annotation-found=Classe {0} precisa ser anotada com @Managed
+management-null-class-defined=O controlador de gerenciamento informado n\u00E3o pode ser [null]
+management-abstract-class-defined=O controlador de gerenciamento [{0}] precisa ser uma classe concreta
+management-no-annotation-found=Classe {0} precisa ser anotada com @ManagementController
management-invalid-property-no-getter-setter=Falha ao inicializar classe gerenciada {0}, n\u00E3o foi encontrado um m\u00E9todo get ou m\u00E9todo set para a propriedade {1}
management-invalid-property-as-operation=Falha ao inicializar classe gerenciada {0}, n\u00E3o \u00E9 poss\u00EDvel declarar uma propriedade cujo m\u00E9todo get ou set \u00E9 uma opera\u00E7\u00E3o
management-introspection-error=Erro ao ler atributos da classe gerenciada {0}
diff --git a/impl/extension/jmx/src/test/java/management/tests/internal/DynamicMBeanProxyTestCase.java b/impl/extension/jmx/src/test/java/management/tests/internal/DynamicMBeanProxyTestCase.java
index 2291308..20f5f31 100644
--- a/impl/extension/jmx/src/test/java/management/tests/internal/DynamicMBeanProxyTestCase.java
+++ b/impl/extension/jmx/src/test/java/management/tests/internal/DynamicMBeanProxyTestCase.java
@@ -52,6 +52,7 @@ import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.FileAsset;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,13 +69,16 @@ public class DynamicMBeanProxyTestCase {
mainDeployment
.addPackages(true, "br")
.addAsResource(new FileAsset(new File("src/test/resources/test/beans.xml")), "beans.xml")
- .addAsResource(new FileAsset(new File("src/test/resources/configuration/demoiselle.properties")),
- "demoiselle.properties").addPackages(false, DynamicMBeanProxyTestCase.class.getPackage())
+ .addAsResource(new FileAsset(new File("src/test/resources/configuration/demoiselle.properties")),"demoiselle.properties")
+ .addPackages(false, DynamicMBeanProxyTestCase.class.getPackage())
.addClasses(LocaleProducer.class, ManagedTestClass.class);
-
+
+ mainDeployment.as(ZipExporter.class).exportTo(
+ new File("/home/81986912515/myPackage.jar"), true);
+
return mainDeployment;
}
-
+
/**
* Testa se o bootstrap está corretamente carregando e registrando classes anotadas com {@link Managed} como MBeans.
*/
@@ -89,10 +93,12 @@ public class DynamicMBeanProxyTestCase {
// o NotificationBroadcaster. Qualquer classe gerenciada criada pelo usuário
// será adicionada a ela, então esperamos 2 MBeans aqui.
Assert.assertEquals(2, manager.listRegisteredMBeans().size());
+
}
@Test
public void testAttributeWrite() {
+
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = null;
@@ -107,10 +113,12 @@ public class DynamicMBeanProxyTestCase {
} catch (Exception e) {
Assert.fail(e.getMessage());
}
+
}
@Test
public void testAttributeRead() {
+
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = null;
@@ -129,6 +137,7 @@ public class DynamicMBeanProxyTestCase {
} catch (Exception e) {
Assert.fail();
}
+
}
@Test
@@ -156,6 +165,7 @@ public class DynamicMBeanProxyTestCase {
@Test
public void testTryWriteOverReadOnly() {
+
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = null;
@@ -170,6 +180,6 @@ public class DynamicMBeanProxyTestCase {
} catch (Exception e) {
Assert.fail(e.getMessage());
}
+
}
-
}
diff --git a/impl/extension/jmx/src/test/java/management/tests/internal/NotificationBroadcasterTestCase.java b/impl/extension/jmx/src/test/java/management/tests/internal/NotificationBroadcasterTestCase.java
index 14a9e0b..edc4117 100644
--- a/impl/extension/jmx/src/test/java/management/tests/internal/NotificationBroadcasterTestCase.java
+++ b/impl/extension/jmx/src/test/java/management/tests/internal/NotificationBroadcasterTestCase.java
@@ -88,11 +88,12 @@ public class NotificationBroadcasterTestCase {
public void sendMessageTest(){
JMXConfig config = Beans.getReference(JMXConfig.class);
+ //Este será o lado cliente. Este manager é usado para enviar notificações a partir do código da aplicação
+ NotificationManager notificationManager = Beans.getReference(NotificationManager.class);
+
//Obtém o servidor MBean onde anexaremos um listener para a notificação
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- NotificationManager notificationManager = Beans.getReference(NotificationManager.class);
-
//Aqui obtemos o MBean de notificações já registrado pelo bootstrap
StringBuffer notificationMBeanName = new StringBuffer()
.append( config.getNotificationDomain()!=null ? config.getNotificationDomain() : "br.gov.frameworkdemoiselle.jmx" )
diff --git a/impl/extension/jmx/src/test/java/management/tests/internal/RemoteManagementTestCase.java b/impl/extension/jmx/src/test/java/management/tests/internal/RemoteManagementTestCase.java
deleted file mode 100644
index 3e4321e..0000000
--- a/impl/extension/jmx/src/test/java/management/tests/internal/RemoteManagementTestCase.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package management.tests.internal;
-
-import java.io.File;
-
-import javax.management.Attribute;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-
-import management.LocaleProducer;
-import management.domain.ManagedTestClass;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.container.test.api.RunAsClient;
-import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.asset.FileAsset;
-import org.jboss.shrinkwrap.api.spec.JavaArchive;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- *
- * Tests remote management using JMX.
- *
- *
- * TODO Currently you need to configure Eclipse Run configuration to pass
- * system properties enabling remote management to the Java VM. Arquillian's
- * current version doesn't support this.
- *
- *
- *
- * On a SUN virtual machine these properties need to be set to enable remote management:
- *
- * - com.sun.management.jmxremote.port=9999
- * - com.sun.management.jmxremote.authenticate=false
- * - com.sun.management.jmxremote.ssl=false
- *
- *
- *
- * @author serpro
- *
- */
-@RunWith(Arquillian.class)
-@Ignore
-public class RemoteManagementTestCase {
-
- @Deployment(testable=false)
- public static JavaArchive createDeployment() {
- JavaArchive mainDeployment = ShrinkWrap.create(JavaArchive.class);
- mainDeployment
- .addPackages(true, "br")
- .addAsResource(new FileAsset(new File("src/test/resources/test/beans.xml")), "beans.xml")
- .addAsResource(new FileAsset(new File("src/test/resources/configuration/demoiselle.properties")),
- "demoiselle.properties").addPackages(false, DynamicMBeanProxyTestCase.class.getPackage())
- .addClasses(LocaleProducer.class, ManagedTestClass.class);
-
- return mainDeployment;
- }
-
- @Test
- @RunAsClient
- public void testRemotePropertyReading() {
- try {
- JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
- JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
- MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
-
- ObjectName name = null;
- try {
- name = new ObjectName("br.gov.frameworkdemoiselle.jmx.domain:name=ManagedTest");
- } catch (MalformedObjectNameException e) {
- Assert.fail();
- }
-
- mbsc.setAttribute(name, new Attribute("attribute", "New Value"));
- Object info = mbsc.getAttribute(name, "attribute");
-
- Assert.assertEquals("New Value", info);
- } catch (Exception e) {
- Assert.fail(e.getMessage());
- }
- }
-
-}
diff --git a/impl/extension/jmx/src/test/resources/META-INF/beans.xml b/impl/extension/jmx/src/test/resources/META-INF/beans.xml
index bb028b1..d85497f 100644
--- a/impl/extension/jmx/src/test/resources/META-INF/beans.xml
+++ b/impl/extension/jmx/src/test/resources/META-INF/beans.xml
@@ -1,7 +1,11 @@
-
+
br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor
+ br.gov.frameworkdemoiselle.security.RequiredPermissionInterceptor
+ br.gov.frameworkdemoiselle.security.RequiredRoleInterceptor
+ br.gov.frameworkdemoiselle.exception.ExceptionHandlerInterceptor
+
diff --git a/impl/extension/jmx/src/test/resources/META-INF/persistence.xml b/impl/extension/jmx/src/test/resources/META-INF/persistence.xml
deleted file mode 100644
index 0486d41..0000000
--- a/impl/extension/jmx/src/test/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- br.gov.frameworkdemoiselle.jmx.domain.PersistedTestClass
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
--
libgit2 0.21.2