diff --git a/documentation/reference/pt-BR/gerenciamento.xml b/documentation/reference/pt-BR/gerenciamento.xml new file mode 100644 index 0000000..07d3d09 --- /dev/null +++ b/documentation/reference/pt-BR/gerenciamento.xml @@ -0,0 +1,62 @@ + + + + + Monitoração e Gerenciamento de Recursos + +
+ Por que monitorar e gerenciar aplicações + + Ao implantar um sistema para produção, muitas vezes é necessário monitorar aspectos sobre o funcionamento desse sistema. Quanta memória + ele está utilizando? Qual o pico de MIPS utilizados? Quantas sessões estão autenticadas no momento? + + Além de monitorar um sistema, as vezes é necessário gerencia-lo alterando aspectos de seu comportamento. Se o sistema está implantado em um + servidor alugado, talvez seja necessário ajustar o uso de MIPS para reduzir custos ou talvez deseje-se solicitar que o sistema limpe dados de sessão + de autenticação abandonados por usuários que desligaram suas estações sem efetuar "logoff". + + Para esse fim existem diversas tecnologias que permitem ao desenvolvedor expor aspectos monitoráveis e gerenciáves de seu sistema + para clientes de gerenciamento. Exemplos dessas tecnologias incluem o Simple Network Management Protocol (SNMP) e o + Java Management Extension (JMX). + + O Demoiselle Framework dispõe de uma série de ferramentas para nivelar + o conhecimento do desenvolvedor e facilitar o uso e integraçao de várias tecnologias de gerenciamento e monitoração. Através de seu + uso o desenvolvedor pode se despreocupar com detalhes de implementação de cada tecnologia individual e facilmente integrar tais tecnologias. +
+ +
+ Introdução ao mecanismo + + Para expor aspectos monitoráveis da sua aplicação, o primeiro passo é criar uma interface contendo os atributos monitoráveis e as operações + de gerenciamento que serão expostas para clientes de gerenciamento. Isso é feito através de uma simples classe Java (ou POJO) + anotada com o estereótipo @ManagementController. + + + + Essa anotação é suficiente para o mecanismo de gerenciamento descobrir sua classe e disponibiliza-la para ser monitorada e gerenciada. + + Contudo, a simples anotação acima não informa ao mecanismo quais aspectos da classe serão expostos. Por padrão, um Management Controller + não expõe nenhum aspecto seu. Para selecionais quais aspectos serão expostos usamos as anotações @ManagedProperty e @ManagedOperation. + + + + + + @ManagedProperty + + + + + + Marca um atributo na classe como uma propriedade gerenciada, significando que clientes externos podem ler e/ou escrever valores nesses atributos. + Um + + + +
+ +
+ +
\ No newline at end of file diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ManagedProperty.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ManagedProperty.java index 8236b63..7589345 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ManagedProperty.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ManagedProperty.java @@ -47,7 +47,8 @@ import javax.enterprise.util.Nonbinding; /** *

Indicates that a field must be exposed as a property to management clients.

*

The property will be writable if there's a public setter method - * declared for the field and readable if there's a getter method.

+ * declared for the field and readable if there's a getter method. You can override this behaviour by passing a value + * to the {@link #accessLevel()} property.

*

It's a runtime error to annotate a field with no getter and no setter method.

*

It's also a runtime error to declare a field as a property and one or both of it's getter and setter * methods as an operation using the {@link ManagedOperation} annotation.

@@ -65,5 +66,36 @@ public @interface ManagedProperty { */ @Nonbinding String description() default ""; + + @Nonbinding + ManagedPropertyAccess accessLevel() default ManagedPropertyAccess.DEFAULT; + + /** + *

Access level of a managed property.

+ * + *

These values only affect access via external management clients, the application is still able to inject and use the normal visibility of the property + * by Java standards.

+ * + * @author serpro + * + */ + enum ManagedPropertyAccess{ + + /** + * Restricts a property to be only readable even if a setter method exists. + */ + READ_ONLY + + /** + * Restricts a property to be only writeable even if a getter method exists. + */ + ,WRITE_ONLY + + /** + * Says that the read or write access will + * be determined by the presence of a getter method (getProperty()) or setter method (setProperty(propertyValue)) for a property. + */ + ,DEFAULT; + } } 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 2f38593..3d4c9a4 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 @@ -47,6 +47,7 @@ import javax.inject.Qualifier; import br.gov.frameworkdemoiselle.DemoiselleException; import br.gov.frameworkdemoiselle.annotation.ManagedOperation; import br.gov.frameworkdemoiselle.annotation.ManagedProperty; +import br.gov.frameworkdemoiselle.annotation.ManagedProperty.ManagedPropertyAccess; import br.gov.frameworkdemoiselle.annotation.OperationParameter; import br.gov.frameworkdemoiselle.internal.producer.ResourceBundleProducer; import br.gov.frameworkdemoiselle.stereotype.ManagementController; @@ -195,6 +196,12 @@ public class ManagedType { .append("get") .append(field.getName().substring(0, 1).toUpperCase()) .append(field.getName().substring(1)); + + //Se propriedade está anotada como WRITE-ONLY, ignora essa etapa. + ManagedProperty annotation = field.getAnnotation(ManagedProperty.class); + if (annotation.accessLevel() == ManagedPropertyAccess.WRITE_ONLY){ + return null; + } Method getterMethod; @@ -227,6 +234,13 @@ public class ManagedType { * Returns the public setter method for a given field, or null if no setter method can be found. */ private Method getSetterMethod(Field field) { + + //Se propriedade está anotada como READ-ONLY, ignora essa etapa. + ManagedProperty annotation = field.getAnnotation(ManagedProperty.class); + if (annotation.accessLevel() == ManagedPropertyAccess.READ_ONLY){ + return null; + } + StringBuffer setterMethodName = new StringBuffer() .append("set") .append(field.getName().substring(0, 1).toUpperCase()) 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 d3158aa..c9da28b 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 @@ -189,7 +189,7 @@ public class Management { deactivateContexts(managedType.getType()); } } else { - throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName)); + throw new DemoiselleException(bundle.getString("management-read-value-error", propertyName)); } } else { throw new DemoiselleException(bundle.getString("management-type-not-found")); @@ -282,7 +282,7 @@ public class Management { } } else { - throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName)); + throw new DemoiselleException(bundle.getString("management-write-value-error", propertyName)); } } else { throw new DemoiselleException(bundle.getString("management-type-not-found")); diff --git a/impl/core/src/main/resources/demoiselle-core-bundle.properties b/impl/core/src/main/resources/demoiselle-core-bundle.properties index 0197197..829646c 100644 --- a/impl/core/src/main/resources/demoiselle-core-bundle.properties +++ b/impl/core/src/main/resources/demoiselle-core-bundle.properties @@ -110,6 +110,8 @@ management-invalid-property-as-operation=Falha ao inicializar classe gerenciada management-introspection-error=Erro ao ler atributos da classe gerenciada {0} management-type-not-found=A classe gerenciada informada n\u00E3o existe\: {0} management-invoke-error=Erro ao tentar invocar a opera\u00E7\u00E3o "{0}" da classe gerenciada, a opera\u00E7\u00E3o n\u00E3o foi encontrada +management-write-value-error=N\u00E3o foi poss\u00EDvel definir um valor para a propriedade {0} +management-read-value-error=N\u00E3o foi poss\u00EDvel ler o valor da propriedade {0} management-debug-acessing-property=Acessando propriedade {0} da classe gerenciada {1} management-debug-setting-property=Definindo novo valor para propriedade {0} da classe gerenciada {1} management-debug-invoking-operation=Invocando opera\u00E7\u00E3o {0} da classe gerenciada {1} diff --git a/impl/core/src/test/java/management/ManagementTestCase.java b/impl/core/src/test/java/management/ManagementTestCase.java index 9bc802b..43efd0e 100644 --- a/impl/core/src/test/java/management/ManagementTestCase.java +++ b/impl/core/src/test/java/management/ManagementTestCase.java @@ -169,6 +169,21 @@ public class ManagementTestCase { } @Test + public void testAccessLevelControl(){ + //tentamos escrever em uma propriedade que, apesar de ter método setter, está marcada como read-only. + ManagedClassStore store = Beans.getReference(ManagedClassStore.class); + + try{ + store.setProperty(DummyManagedClass.class, "readOnlyPropertyWithSetMethod","A Value"); + Assert.fail(); + } + catch(DemoiselleException de){ + System.out.println(de.getMessage()); + //success + } + } + + @Test public void testRequestScopedOperation() { ManagedClassStore store = Beans.getReference(ManagedClassStore.class); diff --git a/impl/core/src/test/java/management/testclasses/DummyManagedClass.java b/impl/core/src/test/java/management/testclasses/DummyManagedClass.java index a5d44b5..6e5531f 100644 --- a/impl/core/src/test/java/management/testclasses/DummyManagedClass.java +++ b/impl/core/src/test/java/management/testclasses/DummyManagedClass.java @@ -42,6 +42,7 @@ import javax.validation.constraints.NotNull; import br.gov.frameworkdemoiselle.annotation.ManagedOperation; import br.gov.frameworkdemoiselle.annotation.ManagedProperty; +import br.gov.frameworkdemoiselle.annotation.ManagedProperty.ManagedPropertyAccess; import br.gov.frameworkdemoiselle.stereotype.ManagementController; import br.gov.frameworkdemoiselle.util.Beans; @@ -71,6 +72,12 @@ public class DummyManagedClass { @ManagedProperty private String readOnlyProperty = "Default Value"; + @ManagedProperty(accessLevel=ManagedPropertyAccess.READ_ONLY) + private String readOnlyPropertyWithSetMethod = "Default Value"; + + @ManagedProperty(accessLevel=ManagedPropertyAccess.WRITE_ONLY) + private String writeOnlyPropertyWithGetMethod; + /** * Propriedade para testar detecção de métodos GET e SET quando propriedade tem apenas uma letra. */ @@ -192,11 +199,26 @@ public class DummyManagedClass { return gender; } - public void setGender(String gender) { this.gender = gender; } + public String getReadOnlyPropertyWithSetMethod() { + return readOnlyPropertyWithSetMethod; + } + + public void setReadOnlyPropertyWithSetMethod(String readOnlyPropertyWithSetMethod) { + this.readOnlyPropertyWithSetMethod = readOnlyPropertyWithSetMethod; + } + + public String getWriteOnlyPropertyWithGetMethod() { + return writeOnlyPropertyWithGetMethod; + } + + public void setWriteOnlyPropertyWithGetMethod(String writeOnlyPropertyWithGetMethod) { + this.writeOnlyPropertyWithGetMethod = writeOnlyPropertyWithGetMethod; + } + @ManagedOperation public String requestScopedOperation(){ RequestScopeBeanClient client = Beans.getReference(RequestScopeBeanClient.class); -- libgit2 0.21.2