Páginas

SyntaxHighlighter

sábado, 10 de novembro de 2012

Expondo uma API para busca de CEPs com Google Cloud Endpoints

No Google IO 2012 foi lançado (por enquanto só para trusted testers) o Google Cloud Endpoints.
É um novo serviço do GAE que facilita (e muito) a publicação de APIs RESTful ou JSON RPC.
Na verdade as facilidades vão muito além do servidor. Foi incorporado no GPE (Google Plugin para Eclipse) um "gerador" que dada uma API, gera o código necessário para acessá-la de clientes: Android (Java) e/ou iOS (objective C). Além disso também é possível acessar os serviços via javascript usando o Google APIs Client Library for Javascript (mesma biblioteca utilizada para utilização das APIs Google).


Para testar esse novo serviço, me inscrevi no programa de trusted testers e criei uma aplicação que expõe uma API REST para busca de CEPs - usando uma biblioteca Java para busca de CEPs que criei um tempo atrás.
A aplicação possui apenas uma única classe: CepEndpoint. O gist abaixo mostra como o código é simples e como algumas simples anotações são suficientes para publicar um endpoint composto por alguns serviços.
Loading ....

Para testar a API publicada pode-se usar o Google APIs Explorer ou o "clientzinho web" que criei que invoca esse mesmo endpoint usando a API javascript.
Loading ....

Se derem uma olhada no código fonte, verão que aproveitei também pra dar uma treinada no desenvolvimento de aplicações HTML5 usando Angular JS e Bootstrap.

Use o link abaixo para acessar a aplicação:
http://busca-cep.appspot.com/

Setting up Jenkins on EC2 using AWS CloudFormation (including nginx as a reverse proxy)

I lost count on how many times I had to setup a CI server. Being a big fan of the concept of "Infrastructure as Code" as I am, I promised myself that the next time I'd do it differently (I needed to have it automated!).

Well, the day has come.The stack (using Cloudformation terms) I decided to create is composed by a basic Jenkins installation (standalone + winstone) running as a daemon on an Amazon Linux based EC2 intance. It also includes Nginx as a reverse proxy and a dedicated volume for storing the JENKINS_HOME files and other artifacts.

Obviously that a much easier, simpler and (I think) even cheaper alternative would be using some PaaS offering (Jenkins as a Service).

However, I ended up using AWS Cloudformation to automate the provisioning of the AWS Resources (IAM User, SecurityGroup, EBS Volumes, EC2 instance) and its cloud-init features to install and configure the necessary packages.

External repository addition, yum based package installations, configuration files adjustments, EBS volumes setup, etc. Most of the installation and configuration logic is in a shell script embedded in the UserData property.

The resulting template is right below, the input parameters are: Instance type, JENKINS_HOME volume size in gigabytes and the EC2 KeyName. The output is the Jenkins server URL!

Loading ....


sexta-feira, 6 de julho de 2012

API Java para busca de CEPs (fachada para o serviços dos Correios)

O site dos Correios disponibiliza gratuitamente um ótimo serviço para busca online de CEPs.
Porém, essa é a única forma de acessá-lo: via página HTML.
Não existe, nem é exposta, nenhuma API que facilite a integração desse serviço com outras aplicações.

Para possibilitar esse tipo de integração, criei o busca-cep-java-client que nada mais é que um componente Java (jar) cuja API abstrai a complexidade de:
  1. Fazer a requisição HTTP (GET) passando os parâmetros necessários e;
  2. Processar a resposta - extraindo os dados de CEP do HTML retornado. 
Internamente utilizo a biblioteca HtmlUnit para auxiliar no Web Scraping. Basicamente o que eu faço é simular um usuário que entra na página de busca, preenche e posta o form. Depois, já na tela de resultados, percorro o HTML retornado em busca da tabela com os dados de CEP retornados.

O trecho de código abaixo mostra o quão simples é a utilização da API:

// Obtém uma instância de CEPService
CEPService buscaCEP = CEPServiceFactory.getCEPService();
// Obtém um CEP pelo número
CEP cep = buscaCEP.obtemPorNumeroCEP(13084440);
// Obtém todos os CEPs que contém "Flordalisa" no logradouro
List<CEP> ceps = buscaCEP.obtemPorEndereco("Flordalisa");

Para mais detalhes em como utilizar esse componente, sugiro dar uma olhada nos testes unitários.
Todo o código fonte também está disponível no Github.
Além disso, publiquei a versão 1.1 do componente num repositório Maven (também no Github).
Para quem usa essa ferramenta basta alterar o pom.xml para incluir o repositório:

<repository>
        <id>Talesolutions</id>
        <url>https://raw.github.com/fabito/talesolutions-mvn-repo/master/</url>
        <snapshots>
                <enabled>true</enabled>
        </snapshots>
        <releases>
                <enabled>true</enabled>
        </releases>
</repository>

E adicionar essa dependência:

    <dependency>
      <groupId>org.talesolutions</groupId>
      <artifactId>busca-cep-client</artifactId>
      <version>1.1</version>
    </dependency>

Considerações Finais

O busca-cep-client ajuda a integrar funcionalidades de busca de CEPs à aplicações Java. Principalmente porque dispensa a criação de uma base de CEPs local e como é só uma façade para o serviço oficial dos Correios temos a "garantia" de estarmos sempre acessando dados atuais e corretos.
A principal desvantagem é a dependência da disponibilidade e formato desse serviço - alto acoplamento. Se o site dos Correios sair do ar sua aplicação certamente será impactada. Além disso, como os dados de CEPs são extraidos de uma página HTML, qualquer mudança no markup gerado afetará o funcionamento do componente.

quinta-feira, 12 de abril de 2012

JMeter - Using BSF Assertion to fail samples based on JSON response


I've tested some web applications whose unexpected errors or exceptions were handled by the application code and encoded in the response body as JSON.

A hypothetical response is shown below:

{
    data: null,
    message: "TimeoutException: Transaction rolled back after 3000 seconds.",
    success: false
}

The problem with this approach is that most of the times the HTTP response code is 200 (OK) which  jmeter interprets as a successful sample.
I'm not a big fan of this solution I'd rather have it returning 4XX or 5XX response codes, in which case jmeter would fail the sample.

In order to workaround this, I normally use a BSF Assertion containing javascript code similar to:

try {
   eval('var response = ' + prev.getResponseDataAsString());
   if (!response.success) {
      prev.setSuccessful(false);
      prev.setResponseMessage(response.message);
   }
} catch(e) {
      prev.setSuccessful(false);
      prev.setResponseMessage("Invalid response. Expected a valid JSON.");
}

First I try to evaluate the response string into a valid javascript object. If that succeeds I check the success flag and handle it properly, otherwise, in the catch block, I force the sample to fail due to a bad response format.
Note that in both failure scenarios I invoke the setSuccessful and the setResponseMessage methods to signal a sample failure and have better detailed error messages respectively.

And that's it!
Happy load testing!

JMeter - Changing sample label/name at runtime

When creating jmeter's test plans, sometimes its useful to change the samples names in order to have more accurate and meaningful reports. To achieve this I normally use one of these two approaches:

Using variables (placeholders) in the sampler name

If the variables you need to form the new sample name are already available just fill the the name's text field using the syntax ${variable name}.
The only problem with this approach is that the name shown in test plan tree (left panel) might end up being not so intuitive.


Dynamically setting it in BSF Post Processors

Just use the variable prev (which gives access to the previous SampleResult) and use the method setSampleLabel to set the new label.
In the example below I'm using the value of another variable (named url) previously put in the vars object:

quinta-feira, 9 de fevereiro de 2012

Instalando a slackline (sem árvores) com auxílio de âncora - Parte 2

Comecei a execução do meu projeto.
Abaixo algumas fotos do sistema de ancoragem que montei no meu quintal para instalar minha slackline.

1) Escavação



2) Preparando da âncora



3) Enterrando a âncora


   


4) Finalmente, armando a slack


Slackline / Waterline in the Colombian Caribbean

Slackline and waterline sessions during my last trip to the Colombian Caribbean. 
This video includes waterlining in the Lover's bridge (between Providencia and Santa Catalina Island) and slacklining in Johnny Cay - in San Andres Island.