The simplest “micro” deployment (ArqTip #2)

read the asciidoc based version of this post here.

The second Arquillian tip is the simplest “micro” deployment. Its a Arquillian deployment that uses the hole project as deployment with no need for adding individual classes, packages or libraries:

simplest-deployment

@RunWith(Arquillian.class)
public class SimplestDeployment {

    @Deployment
    public static Archive<?> createDeployment() {
        WebArchive war = ShrinkWrap.create(ZipImporter.class, "cdi-crud.war").
                importFrom(new File("target/cdi-crud.war")).as(WebArchive.class);
        war.addAsResource("persistence.xml", "META-INF/persistence.xml");//replace with test persistence
        return war;
    }

    @Inject
    CarService carService;


    @Test
    @UsingDataSet("car.yml")
    public void shouldCountCars() {
        assertNotNull(carService);
        assertEquals(carService.crud().count(), 4);
    }
}

This basically uses a previously builded project as deployment and just replaces its persistence.xml to use a test database.

Compare it with a traditional deployment here.

Of course that this simplicity comes with a price:

1 – Its not a true micro deployment because it uses the hole application. If your application is big the deployment can take considerable time(seconds);

2 – You need to build the application before running the test. Here you lose a big advantage of Arquillian which is to not build the application if a test (even functional tests) has failed.

To overcome problem #2 you can execute the tests in surefire integration-tests phase:

<profile>
    <id>simple-deployment</id>
    <build>
        <plugins>
            <plugin>
                <artifactid>maven-surefire-plugin</artifactid>
                <version>2.16</version>
                <executions>
                    <execution>
                        <id>after-package</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                        <configuration>
                            <skiptests>false</skiptests>
                            <includes>
                                <include>**/*SimplestDeployment.java</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

There is an issue from 2012 in Arquillian issue tracker which address this feature of a “simplest deployment”  using a single annotation , see the issue here: https://issues.jboss.org/browse/ARQ-74.

Source code of this post can be found here: https://github.com/rmpestano/cdi-crud/blob/cdi-crud-universe/src/test/java/com/cdi/crud/it/SimplestDeployment.java

 

Advertisements

Acessando informações de um projeto maven

Neste post vou mostrar como podemos acessar informações de um projeto maven a partir do arquivo pom.xml e exibir estas informações em uma aplicação web.

iremos utilizar como exemplo o seguinte pom.xml:

<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”&gt;

…..

…..

<properties>
 <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <mojarra.version>2.1.5</mojarra.version>
 <myfaces.version>2.1.7</myfaces.version>
 <myfaces.codi.version>1.0.5</myfaces.codi.version>
 <primefaces.version>3.3</primefaces.version>
 <primefaces-ext.version>0.4.0</primefaces-ext.version>
 <primefaces.theme.version>1.0.5</primefaces.theme.version>
 <conventions.version>0.7-SNAPSHOT</conventions.version>
 <openwebbeans.version>1.1.4</openwebbeans.version>
 <hibernate.version>4.1.3.Final</hibernate.version>
 <netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server>
</properties>
<dependencies>
  //dependencias
</dependencies>
<build>
 <resources>
 <resource>
 <directory>src/main/resources</directory>
 <filtering>true</filtering>
 </resource>
 </resources>
</build>
...
...
</project>

Para conseguirmos acessar as propriedades (declaradas dentro da tag properties) do pom.xml devemos informar a localização do diretório resources da nossa applicação atravéz da tag <resources> e além disto devemos criar um arquivo .properties neste diretório(src/main/resources), e informar  a entrada abaixo:

application.properties = ${project.properties}

este arquivo será o elo entre nossa aplicação e o arquivo pom.xml, é o famoso arquivo de bundle utilizado para internacionalização.

Com as configurações acima agora somos capazes de acessar as propriedades do arquivo pom, segue o código do bean que irá acessar as propriedades e guarda-las em um mapa:

/**
 *
 * @author rmpestano
 */
@Named
@ApplicationScoped
public class ApplicationInfoMBean implements Serializable{

   private Map<String,String> infoMap = new HashMap<String, String>();
   @Inject
   private ResourceBundle resourceBundle;

   @PostConstruct
   public void initialize(){

     String appProperties = resourceBundle.getString("application.properties");
     appProperties = appProperties.substring(1, appProperties.indexOf("}"));
     String[] arrayProperties = appProperties.split("[\\s,]+");//separa cada propriedade por vírgula ignorando espaços
     for (String prop : arrayProperties) {
       String[] keyValue = prop.split("=");  
       infoMap.put(keyValue[0], keyValue[1]);//coloca nome da propripriedade na chave e a versão no valor do mapa
      }
   }
  public Map<String, String> getInfoMap() {
   return infoMap;
  }
  public void setInfoMap(Map<String, String> infoMap) {
   this.infoMap = infoMap;
  }

}

seguem imagens mostrando como as propriedades do pom.xml chegam no bean

:

Após popularmos o mapa de propriedades nós acessamos esse mapa na tela passando o nome da propriedade como chave e o mapa nos retorna a versão como valor, segue o código da pagina .xhtml

Mojarra #{applicationInfoMBean.infoMap['mojarra.version']}, Primefaces #{applicationInfoMBean.infoMap['primefaces.version']},....e por aí vai

Agora quando atualizarmos as dependencias do projeto não precisamos mais alterar a tela que exibe essas informações.