Java

ruby

segunda, 03 de novembro de 2008

Quando Java não for suficiente

Escrito por: Alberto

Em um projeto aqui na empresa, estava precisando acessar o webservice do SugarCRM. O problema aconteceu quando descobri que o estilo de binding dele era rpc/encoded e que os projetos em Java mais atuais não estavam dando suporte a isso, alguns exemplos são : Axis2 e CXF.

Então foi que pensei, deixa eu ver se tem jeito de fazer isso em Ruby, e descobri que era até meio ridiculo…


require('md5')
require 'soap/wsdlDriver'
@wsdl = "http://localhost/settech_orcamentos/soap.php?wsdl"
@soap = SOAP::WSDLDriverFactory.new(@wsdl).create_rpc_driver
resultado = @soap.login({:user_name=>"login",:password=>MD5.new("password"),:version=>"5.1.0a"},"SugarCRM")
puts resultado.id

Isso porque o Ruby faz o parse do wsdl em tempo de execução e cria uma classe para você naquele momento, na verdade um proxy, e permite que todos os metodos sejam acessados. Ainda conta a ferramenta wsdl2ruby para fazer algo similar ao wsdl2java.

Com isso em mãos, resolvi fazer o mix de Java com Ruby, usando o Java como linguagem, mas também como plataforma para execução de código, nesse caso o Ruby através da sua implementação em Java, JRuby. Isso oferece um potencial incrível pois, por exemplo, podemos usar o potencial do Ruby para fazer algo que Java não seja muito bom ou até querer manter um código em Java que seja dinâmico, sim é permitido acessar as API’s do Java através do Ruby. Abaixo segue o código que fiz. A primeira parte em Ruby e a segunda em Java. As variaveis no código Ruby que estão com $, foram compartilhadas do código em Java para o Ruby


require('java')
include_class('br.com.settech.sugarsoap.Result')
include_class('br.com.settech.sugarsoap.helper.ContextSoapComunication')
require 'soap/wsdlDriver'
require 'MD5'
module IntegracaoSugarCRM

class SugarCRM
def initialize(name_value_pairs)
@name_value_pairs = name_value_pairs
@params = Array.new
end

def params
@name_value_pairs.each {|name_value_pair| @params.push({:name=>name_value_pair.name,:value=>name_value_pair.value})}
@params
end
end

class Integrador
def initialize
if not $context
@soap = SOAP::WSDLDriverFactory.new($info.url_wsdl).create_rpc_driver
end
end

def login
result = @soap.login({:user_name=>$info.login,:password=>MD5.new($info.password),:version=>$info.version},$info.app_name)
ContextSoapComunication.new(Result.new(result.error.number,result.error.description,result.id),@soap)
end

def logout
#logout aqui
end

#Usa as variaveis definidas no codigo java.
def executa_metodo
params = SugarCRM.new($name_value_pairs).params
result = $context.driver.set_entry($context.login_id,$which_module,params)
Result.new(result.error.number,result.error.description,result.id)
end
end
end

if not $context
IntegracaoSugarCRM::Integrador.new.login
else
IntegracaoSugarCRM::Integrador.new.executa_metodo
end

public class JRubyIntegrationTest {

private ContextSoapComunication contextSoapComunication;
private BSFHelper helper;

@Before
public void testCreateLogin() throws BSFException,IOException{
helper = new BSFHelper();
SugarInfo sugarInfo = new SugarInfo("login","password","SugarCRM","5.1.0a","http://localhost/settech_orcamentos/soap.php?wsdl");
helper.declareBean("info",sugarInfo);
this.contextSoapComunication = (ContextSoapComunication)helper.evalFile("C:\\ambiente\\ruby_project\\IntegracaoSugarCRM\\lib\\integrador.rb");
this.contextSoapComunication.loginId();

}

@Test
public void testExecuteJRubyCode() throws BSFException,IOException{
NameValuePairCreator lista = new NameValuePairCreator();
this.helper.declareBean("which_module",ModuleTypes.OPPORTUNITIES);
this.helper.declareBean("name_value_pairs",lista.addNameValuePair("lead_source","Self Generated").addNameValuePair("name","Projeto integracao2").addNameValuePair("amount","53500.55").nameValuePairList());
this.helper.declareBean("context",this.contextSoapComunication);
Result result = (Result)helper.evalFile("C:\\ambiente\\ruby_project\\IntegracaoSugarCRM\\lib\\integrador.rb");
System.out.println(result.createdId());
helper.finalize();
}
}

Para acessar o script através do Java, uso o projeto BSF(Bean Scripting Framework), ideal para quem, como eu, está no Java 5 ainda. A classe BSFHelper foi extraída do site ociweb.com. A única ressalva que faço, é que para usar um script que faça uso do require ou algo parecido, devemos forncer ao BSF a localização das bibliotecas. Para fazer isso, coloque o seguinte código:


		System.getProperties().put("jruby.lib",jrubyBase+"\\lib");
		System.getProperties().put("jruby.home",jrubyBase);

Bom, por hoje é isso, desculpem o tamanho do post, mas queria mostrar algo que foi realmente útil para mim e acho que pode ser para vocês também.

tags: , ,



newsletter

cadastre seu e-mail!  

últimas do twitter

» siga a settech no twitter

swTV

 


Atuando no mercado desde 1999, a SetWeb conta com um time de profissionais que busca soluções adequadas e eficazes para a sua empresa. Aliando estratégia à tecnologia, a SetWeb possui como foco principal o resultado de ações implementadas para cada negócio.
Esse é o nosso compromisso e o nosso desafio.