Compilando o WSO2 Carbon 3.0.0 e corrigindo o WSO2 Data Services Server 2.5.0
Versões novas de produtos sempre são uma alegria, seja pelos recursos novos ou somente pela novidade que sempre alegra-nos, principalmente nós desenvolvedores. Mas juntamente com as novas versões (principalmente nos primeiros releases) vem também problemas, bugs ou incompatibilidade de versões- os problemas mais comuns.
E para não pararmos no tempo, vendo que as novidades do WSO2 Data Services Server 2.5.0 seriam muito bem vindas para nós, resolvemos realizar testes para verificar a possibilidade de atualizarmos nossa versão da 2.2.1 para a 2.5.0, e surgiu aquela alegria quando vimos que não teríamos problemas de incompatibilidade como ocorreu nos testes de migração da 2.0 para WSO2 Data Services Server 2.2.1.
Mas como nem tudo são rosas, um velho bug conhecido nosso na versão 2.0 e discutido no fórum - de não aceitar valores null, tinha sido corrigido na versão 2.2.1; mas resolveu dar as caras na versão 2.5.0. E por necessitarmos das novidades dessa versão, tivemos que correr atrás e corrigir o problema, já corrigido anteriormente.
Como já conhecemos a estrutura, fomos direto ao site do projeto para realizar o download do fonte do WSO2 Data Services Server e fomos atrás do arquivo problemático (SQLQuery.java). Mas para nossa surpresa, o arquivo não estava mais lá, foi centralizado no projeto WSO2 Carbon.
Então com o arquivo de código-fonte do WSO2 Carbon 3.0.0 devidamente baixado, vamos colocar a mão na massa.
Baixando e descompactando o fonte
wget http://dist.wso2.org/products/carbon/3.0.0/wso2carbon-3.0.0-src.zip unzip wso2carbon-3.0.0-src.zip
Baixando e aplicando o patch
wget /wp-content/uploads/2010/06/wso2-dataservices-accept-null.txt cd wso2carbon-3.0.0-src patch -p1 wso2-dataservices-accept-null.patch
E a mensagem recebida aqui será algo como:
patching file components/data-services/org.wso2.carbon.dataservices.core/3.0.0/src/main/java/org/wso2/carbon/dataservices/dispatch/query/SQLQuery.java
Compilando o componente
Levando em consideração que você tenha as dependências necessárias, vai ser um passo bem demorado. Vai fazer download de alguns pacotes, compilar, testar e gerar uma nova versão do componente, com a correção.
cd components/data-services mvn install
Corrigindo o Data Services Server
Agora que temos o componente corrigido e devidamente compilado, vamos copiá-lo para a instância do WSO2 Data Services Server (levando em consideração que minha instalação fica em ~/Applications/wso2/wso2dataservices-2.5.0).
cp org.wso2.carbon.dataservices.core/3.0.0/target/org.wso2.carbon.dataservices.core-3.0.0.jar ~/Applications/wso2/wso2dataservices-2.5.0/wso2dataservices-2.5.0/repository/components/plugins/org.wso2.carbon.dataservices.core-3.0.0.jar cp org.wso2.carbon.dataservices.ui/3.0.0/target/org.wso2.carbon.dataservices.ui-3.0.0.jar ~/Applications/wso2/wso2dataservices-2.5.0/wso2dataservices-2.5.0/repository/components/plugins/org.wso2.carbon.dataservices.ui-3.0.0.jar
Conclusão
Com o patch criado, testado e aplicado. Abrimos um pedido de correção no JIRA do WSO2, para que eles possam corrigir na próxima release (provavelmente a 2.5.1). Caso você não tenha disponibilidade (de tempo ou paciência), pode baixar os componente do WSO2 Data Services Server corrigido (bastando apenas descompactá-los).
E tenho que falar, viva o código aberto e o software livre! (;
Mapas interativos e Geoprocessamento
Atualmente vemos muitas aplicações e sites utilizando mapas (nem que seja apenas pra mostrar o endereço da empresa), essa facilidade que o Google trouxe com o Google Maps é muito grande, ajudou muito na disseminação dessa tecnologia.
Essa facilidade de implementação, nos dá maiores opções para criar sistemas e interfaces bem diferenciadas, como o Zoomii Books (mesmo não usando Google Maps) que implementou uma loja virtual de livros e o Trulia, um site de uma imobiliária americana que chega até o nível de visualizar a casa como se estivessemos em frente a frente (utilizando o Street View).
Abaixo vemos o Google Maps e integrado ao Panoramio, dando até a opção de navegação panorâmica das fotos georeferenciadas.
Mas acontece que o pessoal do Google abstraiu muito a dificuldade que é trabalhar com informações georeferenciadas. Fez com que todas essas funcionalidades (busca de endereços, pontuação, pesquisa por polígonos) e informações (mapas, imagens de satélites, rotas) ficasse algo simples e totalmente transparente para o desenvolvedor. O desenvolvedor sabe que passando o endereço, aparece um ponto no mapa, e isso as vezes basta, mas quando precisamos ir mais além, vemos que a coisa não é tão simples assim.
Senti essa dificuldade tempos atrás, onde tiver que implementar um projeto utilizando tecnologias livres e nos requisitos estavam: Java, MapServer, MapScript e PostgreSQL (com PostGIS). Descobri que não é só utilizando endereço e, a inválivel dupla, latitude/longitude que identificaremos os pontos no mapa, descobri também a existência das coordenadas UTM e a diferença entre as regiões.
Posteriormente descobri que uma alternativa de desenvolvimento ao MapServer, é o GeoServer, escrito nativamente em Java, que facilitaria - e muito - o meu trabalho, pois o MapScript é uma biblioteca em C e por isso foi necessário utilizar JNI.
Com tudo isso, descobri que geoprocessamento é bem mais do que um mapa com alguns pontos e alguns polígonos, tem muito mais coelho nesse mato. O geoprocessamento e georeferenciamento não é algo tão simples, não é a toa que existem os Engenheiros Cartográficos.
Depois desse projeto, vi que curti demais a área e estou me aprofundando na medida do possível, todos os estudos que eu for realizando relatarei por aqui. E o primeiro estudo que relatarei será o OpenLayers.
Consumindo um serviço seguro utilizando PHP
Dia desses precisei colocar autenticação em um serviço que desenvolvi e passeando pelas opções da interface administrativa da WSO2 Enterprise Service Bus encontrei facilmente minha solução. Um pouco depois, li no twitter do @WSO2 um comentário sobre um novo artigo publicado sobre segurança nos Data Services, onde ensinava a fazer toda a parte de configuração: Content Filtering in Data Services with User Roles.
Só que pouco tempo depois de configurar e entregar ao cliente o serviço, veio o problema: como consumir em PHP o serviço? No artigo a solução entregue por eles para consumo é em Java, como a capacidade do cliente deixa a desejar, fiquei de fazer e enviar um exemplo de consumo do serviço desenvolvido.
Então... mãos na massa!
Configurando a ESB
Nesse ponto não irei escrever passo-a-passo a configuração que deve ser feita, o trabalho realizado pelo pessoal do WSO2 está muito bem feito nessa parte do artigo: Step 4 – Enable User Authentication for the Data Service.
Consumo sem segurança
Um pequeno trecho de PHP que mostra como consumir o serviço sem nenhum tipo de segurança. Código pequeno, limpo e objetivo.
$client = new SoapClient("http://localhost:8280/services/Tutorial?wsdl");
try {
$obj = $client->searchProductsByGroupId(array("group_id" => 1));
print_r($obj);
} catch (Exception $e) {
echo "ERRO: " . $e->getMessage();
}
Mas mesmo com toda essa objetividade, o problema do cliente não estava resolvido e eu recebia o seguinte erro:
ERRO: SOAP header missing
E, para resolver, faltava adicionar o cabeçalho com os dados de segurança.
Consumo com segurança
Agora um não-tão-pequeno trecho em PHP.
// configurações de conexão
$username = "admin";
$password = "admin";
$created = date ("Y-m-d\TH:i:s", mktime (date("H"), date("i"), date("s"), date("m"), date("d"), date("Y")))."Z";
// definição de namespaces
$ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
$wsu = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
// criando elemento UsernameToken
$token = new stdClass;
$token->Username = new SOAPVar($username, XSD_STRING, null, null, null, $ns);
$token->Password = new SOAPVar($password, XSD_STRING, null, null, null, $ns);
// criando elemento Timestamp
$timestamp = new stdClass;
$timestamp->Created = new SOAPVar($created, XSD_STRING, null, null, null, $wsu);
// criando elemento Security
$wsec = new stdClass;
$wsec->UsernameToken = new SoapVar($token, SOAP_ENC_OBJECT, null, null, null, $ns);
$wsec->Timestamp = new SoapVar($timestamp, SOAP_ENC_OBJECT, null, null, null, $wsu);
// criando header
$headers = new SOAPHeader($ns, 'Security', $wsec);
// construtor do web-service (com cabeçalho) passando o endereço do WSDL
$client = new SoapClient("http://localhost:8280/services/Tutorial?wsdl");
$client->__setSOAPHeaders($headers);
// chamada do método
try {
$obj = $client->searchProductsByGroupId(array("group_id" => 1));
print_r($obj);
} catch (Exception $e) {
echo "ERRO: " . $e->getMessage();
}
E tudo rodou normalmente, sem problemas, o cliente ficou feliz e eu matei um pouco da saudade de programar em PHP.
Na pesquisa por soluções, tentei utilizar o WSO2 Web Services Framework for PHP mas descobri que depende de instalação de módulo no Apache e não servia para meu cliente, mas anotei na pauta para testá-lo em outro momento.


