Commit dbc9dcc2ced859a6efd7474125db081759718a37

Authored by Dancovich
1 parent 0d9f1260
Exists in master

-Alterada mensagem de erro ao ler propriedade inexistente em classe

gerenciada
-Adicionado recurso para marcar propriedade com apenas leitura ou
escrita ignorando presença ou ausência de métodos set e get
-Iniciada escrita de documentação
documentation/reference/pt-BR/gerenciamento.xml 0 → 100644
... ... @@ -0,0 +1,62 @@
  1 +<?xml version='1.0' encoding="utf-8"?>
  2 +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3 + "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
  4 +<chapter id="mensagem">
  5 +
  6 + <title>Monitoração e Gerenciamento de Recursos</title>
  7 +
  8 + <section>
  9 + <title>Por que monitorar e gerenciar aplicações</title>
  10 +
  11 + <para>Ao implantar um sistema para produção, muitas vezes é necessário monitorar aspectos sobre o funcionamento desse sistema. Quanta memória
  12 + ele está utilizando? Qual o pico de MIPS utilizados? Quantas sessões estão autenticadas no momento?</para>
  13 +
  14 + <para>Além de monitorar um sistema, as vezes é necessário gerencia-lo alterando aspectos de seu comportamento. Se o sistema está implantado em um
  15 + 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
  16 + de autenticação abandonados por usuários que desligaram suas estações sem efetuar "logoff".</para>
  17 +
  18 + <para>Para esse fim existem diversas tecnologias que permitem ao desenvolvedor expor aspectos monitoráveis e gerenciáves de seu sistema
  19 + para clientes de gerenciamento. Exemplos dessas tecnologias incluem o <emphasis>Simple Network Management Protocol</emphasis> (SNMP) e o
  20 + <emphasis>Java Management Extension</emphasis> (JMX).</para>
  21 +
  22 + <para>O <emphasis>Demoiselle Framework</emphasis> dispõe de uma série de ferramentas para nivelar
  23 + o conhecimento do desenvolvedor e facilitar o uso e integraçao de várias tecnologias de gerenciamento e monitoração. Através de seu
  24 + uso o desenvolvedor pode se despreocupar com detalhes de implementação de cada tecnologia individual e facilmente integrar tais tecnologias.</para>
  25 + </section>
  26 +
  27 + <section>
  28 + <title>Introdução ao mecanismo</title>
  29 +
  30 + <para>Para expor aspectos monitoráveis da sua aplicação, o primeiro passo é criar uma interface contendo os atributos monitoráveis e as operações
  31 + de gerenciamento que serão expostas para clientes de gerenciamento. Isso é feito através de uma simples classe Java (<emphasis>ou POJO</emphasis>)
  32 + anotada com o estereótipo <code>@ManagementController</code>.</para>
  33 +
  34 + <programlisting role="JAVA"><![CDATA[
  35 + @ManagementController
  36 + public class GerenciadorUsuarios]]></programlisting>
  37 +
  38 + <para>Essa anotação é suficiente para o mecanismo de gerenciamento descobrir sua classe e disponibiliza-la para ser monitorada e gerenciada.</para>
  39 +
  40 + <para>Contudo, a simples anotação acima não informa ao mecanismo quais aspectos da classe serão expostos. Por padrão, um <emphasis>Management Controller</emphasis>
  41 + não expõe nenhum aspecto seu. Para selecionais quais aspectos serão expostos usamos as anotações <code>@ManagedProperty</code> e <code>@ManagedOperation</code>.</para>
  42 +
  43 + <table>
  44 + <tbody>
  45 + <row>
  46 + <entry>
  47 + <emphasis role="BOLD">@ManagedProperty</emphasis>
  48 + </entry>
  49 + </row>
  50 +
  51 + <row>
  52 + <entry>
  53 + <para>Marca um atributo na classe como uma propriedade gerenciada, significando que clientes externos podem ler e/ou escrever valores nesses atributos.</para>
  54 + <para>Um</para>
  55 + </entry>
  56 + </row>
  57 + </tbody>
  58 + </table>
  59 +
  60 + </section>
  61 +
  62 +</chapter>
0 63 \ No newline at end of file
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ManagedProperty.java
... ... @@ -47,7 +47,8 @@ import javax.enterprise.util.Nonbinding;
47 47 /**
48 48 * <p>Indicates that a field must be exposed as a property to management clients.</p>
49 49 * <p>The property will be writable if there's a public setter method
50   - * declared for the field and readable if there's a getter method.</p>
  50 + * declared for the field and readable if there's a getter method. You can override this behaviour by passing a value
  51 + * to the {@link #accessLevel()} property.</p>
51 52 * <p>It's a runtime error to annotate a field with no getter and no setter method.</p>
52 53 * <p>It's also a runtime error to declare a field as a property and one or both of it's getter and setter
53 54 * methods as an operation using the {@link ManagedOperation} annotation.</p>
... ... @@ -65,5 +66,36 @@ public @interface ManagedProperty {
65 66 */
66 67 @Nonbinding
67 68 String description() default "";
  69 +
  70 + @Nonbinding
  71 + ManagedPropertyAccess accessLevel() default ManagedPropertyAccess.DEFAULT;
  72 +
  73 + /**
  74 + * <p>Access level of a managed property.</p>
  75 + *
  76 + * <p>These values only affect access via external management clients, the application is still able to inject and use the normal visibility of the property
  77 + * by Java standards.</p>
  78 + *
  79 + * @author serpro
  80 + *
  81 + */
  82 + enum ManagedPropertyAccess{
  83 +
  84 + /**
  85 + * Restricts a property to be only readable even if a setter method exists.
  86 + */
  87 + READ_ONLY
  88 +
  89 + /**
  90 + * Restricts a property to be only writeable even if a getter method exists.
  91 + */
  92 + ,WRITE_ONLY
  93 +
  94 + /**
  95 + * Says that the read or write access will
  96 + * be determined by the presence of a getter method <code>(getProperty())</code> or setter method <code>(setProperty(propertyValue))</code> for a property.
  97 + */
  98 + ,DEFAULT;
  99 + }
68 100  
69 101 }
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/ManagedType.java
... ... @@ -47,6 +47,7 @@ import javax.inject.Qualifier;
47 47 import br.gov.frameworkdemoiselle.DemoiselleException;
48 48 import br.gov.frameworkdemoiselle.annotation.ManagedOperation;
49 49 import br.gov.frameworkdemoiselle.annotation.ManagedProperty;
  50 +import br.gov.frameworkdemoiselle.annotation.ManagedProperty.ManagedPropertyAccess;
50 51 import br.gov.frameworkdemoiselle.annotation.OperationParameter;
51 52 import br.gov.frameworkdemoiselle.internal.producer.ResourceBundleProducer;
52 53 import br.gov.frameworkdemoiselle.stereotype.ManagementController;
... ... @@ -195,6 +196,12 @@ public class ManagedType {
195 196 .append("get")
196 197 .append(field.getName().substring(0, 1).toUpperCase())
197 198 .append(field.getName().substring(1));
  199 +
  200 + //Se propriedade está anotada como WRITE-ONLY, ignora essa etapa.
  201 + ManagedProperty annotation = field.getAnnotation(ManagedProperty.class);
  202 + if (annotation.accessLevel() == ManagedPropertyAccess.WRITE_ONLY){
  203 + return null;
  204 + }
198 205  
199 206 Method getterMethod;
200 207  
... ... @@ -227,6 +234,13 @@ public class ManagedType {
227 234 * Returns the public setter method for a given field, or <code>null</code> if no setter method can be found.
228 235 */
229 236 private Method getSetterMethod(Field field) {
  237 +
  238 + //Se propriedade está anotada como READ-ONLY, ignora essa etapa.
  239 + ManagedProperty annotation = field.getAnnotation(ManagedProperty.class);
  240 + if (annotation.accessLevel() == ManagedPropertyAccess.READ_ONLY){
  241 + return null;
  242 + }
  243 +
230 244 StringBuffer setterMethodName = new StringBuffer()
231 245 .append("set")
232 246 .append(field.getName().substring(0, 1).toUpperCase())
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java
... ... @@ -189,7 +189,7 @@ public class Management {
189 189 deactivateContexts(managedType.getType());
190 190 }
191 191 } else {
192   - throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName));
  192 + throw new DemoiselleException(bundle.getString("management-read-value-error", propertyName));
193 193 }
194 194 } else {
195 195 throw new DemoiselleException(bundle.getString("management-type-not-found"));
... ... @@ -282,7 +282,7 @@ public class Management {
282 282 }
283 283  
284 284 } else {
285   - throw new DemoiselleException(bundle.getString("management-invoke-error", propertyName));
  285 + throw new DemoiselleException(bundle.getString("management-write-value-error", propertyName));
286 286 }
287 287 } else {
288 288 throw new DemoiselleException(bundle.getString("management-type-not-found"));
... ...
impl/core/src/main/resources/demoiselle-core-bundle.properties
... ... @@ -110,6 +110,8 @@ management-invalid-property-as-operation=Falha ao inicializar classe gerenciada
110 110 management-introspection-error=Erro ao ler atributos da classe gerenciada {0}
111 111 management-type-not-found=A classe gerenciada informada n\u00E3o existe\: {0}
112 112 management-invoke-error=Erro ao tentar invocar a opera\u00E7\u00E3o "{0}" da classe gerenciada, a opera\u00E7\u00E3o n\u00E3o foi encontrada
  113 +management-write-value-error=N\u00E3o foi poss\u00EDvel definir um valor para a propriedade {0}
  114 +management-read-value-error=N\u00E3o foi poss\u00EDvel ler o valor da propriedade {0}
113 115 management-debug-acessing-property=Acessando propriedade {0} da classe gerenciada {1}
114 116 management-debug-setting-property=Definindo novo valor para propriedade {0} da classe gerenciada {1}
115 117 management-debug-invoking-operation=Invocando opera\u00E7\u00E3o {0} da classe gerenciada {1}
... ...
impl/core/src/test/java/management/ManagementTestCase.java
... ... @@ -169,6 +169,21 @@ public class ManagementTestCase {
169 169 }
170 170  
171 171 @Test
  172 + public void testAccessLevelControl(){
  173 + //tentamos escrever em uma propriedade que, apesar de ter método setter, está marcada como read-only.
  174 + ManagedClassStore store = Beans.getReference(ManagedClassStore.class);
  175 +
  176 + try{
  177 + store.setProperty(DummyManagedClass.class, "readOnlyPropertyWithSetMethod","A Value");
  178 + Assert.fail();
  179 + }
  180 + catch(DemoiselleException de){
  181 + System.out.println(de.getMessage());
  182 + //success
  183 + }
  184 + }
  185 +
  186 + @Test
172 187 public void testRequestScopedOperation() {
173 188 ManagedClassStore store = Beans.getReference(ManagedClassStore.class);
174 189  
... ...
impl/core/src/test/java/management/testclasses/DummyManagedClass.java
... ... @@ -42,6 +42,7 @@ import javax.validation.constraints.NotNull;
42 42  
43 43 import br.gov.frameworkdemoiselle.annotation.ManagedOperation;
44 44 import br.gov.frameworkdemoiselle.annotation.ManagedProperty;
  45 +import br.gov.frameworkdemoiselle.annotation.ManagedProperty.ManagedPropertyAccess;
45 46 import br.gov.frameworkdemoiselle.stereotype.ManagementController;
46 47 import br.gov.frameworkdemoiselle.util.Beans;
47 48  
... ... @@ -71,6 +72,12 @@ public class DummyManagedClass {
71 72 @ManagedProperty
72 73 private String readOnlyProperty = "Default Value";
73 74  
  75 + @ManagedProperty(accessLevel=ManagedPropertyAccess.READ_ONLY)
  76 + private String readOnlyPropertyWithSetMethod = "Default Value";
  77 +
  78 + @ManagedProperty(accessLevel=ManagedPropertyAccess.WRITE_ONLY)
  79 + private String writeOnlyPropertyWithGetMethod;
  80 +
74 81 /**
75 82 * Propriedade para testar detecção de métodos GET e SET quando propriedade tem apenas uma letra.
76 83 */
... ... @@ -192,11 +199,26 @@ public class DummyManagedClass {
192 199 return gender;
193 200 }
194 201  
195   -
196 202 public void setGender(String gender) {
197 203 this.gender = gender;
198 204 }
199 205  
  206 + public String getReadOnlyPropertyWithSetMethod() {
  207 + return readOnlyPropertyWithSetMethod;
  208 + }
  209 +
  210 + public void setReadOnlyPropertyWithSetMethod(String readOnlyPropertyWithSetMethod) {
  211 + this.readOnlyPropertyWithSetMethod = readOnlyPropertyWithSetMethod;
  212 + }
  213 +
  214 + public String getWriteOnlyPropertyWithGetMethod() {
  215 + return writeOnlyPropertyWithGetMethod;
  216 + }
  217 +
  218 + public void setWriteOnlyPropertyWithGetMethod(String writeOnlyPropertyWithGetMethod) {
  219 + this.writeOnlyPropertyWithGetMethod = writeOnlyPropertyWithGetMethod;
  220 + }
  221 +
200 222 @ManagedOperation
201 223 public String requestScopedOperation(){
202 224 RequestScopeBeanClient client = Beans.getReference(RequestScopeBeanClient.class);
... ...