Computação em nuvem: redefinindo a TI
No último ano, a computação em nuvem teve um enorme aumento para incluir uma ampla variedade de aplicativos—como Salesforce CRM e Google Apps— e serviços —como IBM® DB2® hospedados em Amazon Elastic Compute Cloud (Amazon EC2), Google App Engine e na plataforma Force.com por Salesforce. Esses serviços são geralmente chamados de Platform-as-a-Service (PaaS, plataforma como um serviço), porque os serviços fornecem uma plataforma completa em que as empresas podem criar e hospedar seus próprios aplicativos de TI.
As ofertas de PaaS são hospedadas em um ambiente com vários arrendatários, em que a infraestrutura de hardware e software é compartilhada. Esses ambientes são configurados para assegurar que os dados de cada organização sejam isolados de maneira segura de outras organizações—de maneira similar a leasing em vez de comprar espaço no escritório, para que você não precise se preocupar com manutenção e atualizações. Com PaaS, as organizações percebem não só reduções de custos significativas, mas também vantagens exclusivas, como atualizações automáticas e manutenção zero. O modelo também oferece uma vantagem exclusiva para reduzir os riscos comuns com os novos projetos de TI que geralmente ultrapassam o orçamento e os prazos estabelecidos.
Salesforce é um exemplo de provedor PaaS. A empresa começou fornecendo uma solução de CRM hospedada, e essa oferta forneceu uma solução pronta para uso para aplicativos de negócios comuns, como vendas, gerenciamento de relacionamento com o parceiro e marketing. O Salesforce criado nessa plataforma para o lançamento de Force.com, uma PaaS para criar aplicativos de negócios customizados em um navegador ou usando o ambiente de desenvolvimento integrado (IDE) de Force.com com base em Eclipse. Os aplicativos podem também ser customizados com uma linguagem de programação como Java™proprietária chamada Apex.
Salesforce permite interagir com o servidor usando SOAP, que tem a vantagem de ser independente de linguagem e plataforma. Use Web Services Description Language (WSDL) para descrever quais operações estão disponíveis no servidor. Um documento WSDL descreve uma série de terminais de rede chamados de porta e define o formato de XML para as mensagens ou os dados sendo trocados com o servidor.
As amostras deste artigo usam Java API for XML Web Services (JAX-WS). JAX-WS fornece inúmeras ferramentas para simplificar o trabalho com XML e SOAP, incluindo a geração automática dos objetos de domínio necessários de um documento WSDL e a ligação automática do XML aos objetos Java.
Integrando Salesforce a aplicativos corporativos
É possível criar aplicativos integrados ao Salesforce de várias formas. O primeiro método é configurar um fluxo de trabalho no Salesforce para enviar uma mensagem usando os serviços da Web sempre que um registro for criado ou atualizado. Esse processo usa uma mensagem de saída WSDL—um processo similar para configurar um acionador em um banco de dados. Um fluxo de trabalho configura Salesforce para enviar uma mensagem SOAP a destino de URL pré-configurado sempre que dados forem criados, atualizados ou excluídos. Por exemplo, no exemplo de milhagem neste artigo, é possível enviar o relatório de milhagem a um sistema interno sempre que um novo relatório é adicionado.
O segundo método permite interagir diretamente com Salesforce usando serviços da Web SOAP. Esse método usa arquivos WSDL gerados por Salesforce que são consumidos pelos serviços da Web customizados. Para esse tipo de integração, Salesforce fornece dois tipos principais de WSDL:
- Partner WSDL é livremente tipado e pode ser usado em várias organizações; é mais difícil de se trabalhar com Partner WSDL porque o XML precisa ser serializado na representação de objeto correta para a organização.
- Enterprise WSDL é fortemente tipado e vinculado a uma única organização; dessa forma, é mais fácil de se trabalhar com o WSDL, mas ele funciona apenas com o esquema de uma organização. Além disso, todas as alterações efetuadas nos objetos exigem que se gere WSDL novamente.
Este artigo mostra a integração com Salesforce com a expansão de um exemplo usado no Workbook Force.com: um aplicativo de rastreamento de mensagem (consulte Recursos para obter links para os tutoriais). Para as amostras, você usará os serviços da Web WSDL corporativos.
Para trabalhar com serviços da Web de Salesforce, é preciso ter um token de segurança. Para receber ou reconfigurar o token de segurança, use a UI do Salesforce. Clique em Setup > My Personal
Information > Reset your security token. Nela, você verá uma opção de redefinir o token de segurança e enviá-lo ao seu endereço de e-mail. Após ter o seu token de segurança, use-o em conjunto com a senha para efetuar o login. Por exemplo, caso a sua senha seja aaaaaa , e o toque de segurança, XXXXXXXXXX, será preciso digitar aaaaaaXXXXXXXXXX no lugar da sua senha.
Integrando com Salesforce por meio de serviços da Web
Para apresentar um exemplo de como usar XML para integração com Salesforce, desenvolvi um aplicativo Java de exemplo que faz login no Salesforce, consulta dados e cria novos registros. Toda a comunicação com Salesforce é feita por meio de canal HTTPS seguro. Siga essas etapas para configurar os serviços da Web Java para integração com Salesforce:
- Gere o documento Enterprise WSDL no Salesforce.
Faça login na conta Salesforce de sua organização e clique em Setup > Develop > API. Em seguida, clique com o botão direito do mouse no documento WSDL que deseja gerar.
- Gere os objetos de domínio e as classes Java do WSDL.
Para o exemplo, eu usei a ferramenta wsimport incluída no kit de ferramentas JAX-WS. Para simplificar o processo de execução de wsimport, a amostra usa o modelo de desenvolvimento que faz parte das amostras de Salesforce. Os objetos de domínio Java que essa ferramenta gera permitem que os documentos XML sejam automaticamente vinculados a objetos Java para simplificar a comunicação com o servidor.
- Faça login no Salesforce por meio dos serviços da Web.
É preciso fazer login primeiro para obter uma URL de servidor e um ID da sessão. O código na Listagem 1 mostra como fazer login.
Uma parte importante do login é obter a URL do servidor. Salesforce é executado em várias instâncias, como na1.salesforce.com ou na2.salesforce.com, para aprimorar a confiabilidade e o desempenho. Quando você fizer login em um servidor, será preciso usar a mesma URL para todas as chamadas de serviço da Web subsequentes para manter as informações da sessão.
Listagem 1. Login no Salesforce
public void doLogin(String userName, String password) {
if (userName.length() == 0 || password.length() == 0) {
throw new RuntimeException("user name length and/or password length
cannot be 0 length. \n",
new IllegalArgumentException("Invalid password or user name\n"));
} else {
try {
URL wsdlLocation =
this.getClass().getClassLoader().
getResource("etc/enterprise.wsdl");
if (wsdlLocation == null) {
WebServiceException e =
new WebServiceException("enterprise.wsdl not found!");
//exceptionLogger(e.getMessage(), e);
throw e;
}
port = new SforceService(wsdlLocation,
new QName("urn:enterprise.soap.sforce.com",
"SforceService")).getSoap();
} catch (WebServiceException wse) {
//exceptionLogger("Error creating salesface port ", wse);
throw wse;
}
try {
loginResponse = port.login(userName, password);
} catch (Exception e) {
System.out.println("Error logging in to Salesforce.com " + e);
return;
}
System.out.println("Login was successful.");
System.out.print("The returned session id is: ");
System.out.println(loginResponse.getSessionId());
System.out.print("Your logged in user id is: ");
System.out.println(loginResponse.getUserId() + " \n\n");
System.out.print("The server url is: ");
System.out.println(loginResponse.getServerUrl() + " \n\n");
// on a successful login, you should always set up your session id
// and the url for subsequent calls
....
|
Agora que você configurou a sessão do cliente, é possível chamar o servidor e interagir com ele por meio de chamadas de serviços da Web. Este documento mostra duas operações: leitura de dados do servidor por meio de consultas e adição de novos registros ao servidor.
Consultando Salesforce por meio de serviços da Web
Para consultar dados de Salesforce, é preciso usar uma linguagem especial chamada pelo Salesforce Object
Query Language (SOQL). É possível usar consultas SOQL para procurar objetos ou campos específicos de um objeto, similar a SELECT consulta campos específicos em uma tabela. É possível também usar consultas SOQL para contar o número de registros que atendam a um critério de pesquisa e classifiquem os resultados em uma ordem específica.
A melhor forma de se familiarizar com SOQL é usar o Schema Explorer no IDE Force.com (consulte a Figura 1). Para a brir o Schema Explorer em um projeto, clique duas vezes em salesforce.schema na raiz do seu projeto. No Schema Explorer, é possível navegar em todos os objetos da sua organização; avaliando os vários objetos, é possível selecionar campos ou objetos individuais para gerar automaticamente uma consulta. É possível também incluir objetos relacionados em uma consulta avaliando a listagem de relacionamentos-filho de um objeto.
Figura 1. Schema Explorer
Quando tiver aperfeiçoado a consulta SOQL que deseja executa, integre-a à sua chamada de serviços da Web. O resultado dessa consulta é uma representação XML dos seus dados. Esse documento XML é automaticamente vinculado aos objetos de domínio Java que você gerou anteriormente com JAX-WS.
Para o aplicativo de amostra, serão obtidos todos os registros de milhagem. Os resultados da consulta são vinculados aos objetos de domínio gerados na configuração, como na Listagem 2.
Listagem 2. Resultados da consulta para a pesquisa de milhagem
public void getMileageReports(ForceLogin login) throws UnexpectedErrorFault,
InvalidSObjectFault, InvalidIdFault, InvalidQueryLocatorFault,
MalformedQueryFault, InvalidFieldFault {
QueryResult queryResult = login.port
.query("Select Contact__c, Date__c, Miles__c from Mileage__c");
if (queryResult.getSize() > 0) {
List<SObject> records = queryResult.getRecords();
for (SObject record : records) {
MileageC mileageC = (MileageC) record;
System.out.println(mileageC.getMilesC().getValue()
+ " " + mileageC.getContactC().getValue());
}
}
}
|
Uma coisa importante a ser lembrada ao escrever essas consultas é distinguir campos e objetos customizados de campos e objetos padrão. Os objetos customizados são tabelas de banco de dados do Salesforce customizadas específicas de uma organização. Para assegurar que objetos e campos customizados sejam exclusivos em relação a objetos Salesforce padrão com o mesmo nome, anexe __c após o nome do objeto. Isso os distingue dos objetos e campos padrão.
A consulta na Listagem 2 obtém todos os registros do objeto Mileage .
Observe a convenção __c que mostra nomes de campos customizados do objeto de milhagem. É possível iterar pelos resultados da consulta, vinculando-os ao objeto MileageC , um objeto de domínio que foi gerado a partir do WSDL corporativo. Os objetos MileageC serão preenchidos automaticamente com os dados reais dos registros de milhagem.
A consulta anterior retornou todos os registros de milhagem, que geralmente é mais do que você precisa. Felizmente, é possível especificar um critério de filtro—por exemplo, uma data ou contato, —para que você obtenha apenas um determinado subconjunto de registros. Suponha que você queira encontrar todos os relatórios de milhagem em que as milhas foram maiores que 300. É possível alterar a consulta para que seja:
Select Name, Miles__c From Mileage__c where Miles__c > 300 |
Outra forma de filtrar os dados é obter somente os dados que mudaram dentro de um determinado período. Para fazer isso, use o método getUpdated
em vez de executar uma consulta, o que leva à pesquisa de atualizações do objeto junto com uma data de início e uma de término. getUpdated retorna todos os objetos que mudaram dentro do período especificado. O código na Listagem 3
retorna todos os registros de milhagem que mudaram no último mês.
Listagem 3. Obter registros de milhagem atualizados
GregorianCalendar cal =
port.getServerTimestamp().getTimestamp().
toGregorianCalendar();
GregorianCalendar calEnd = (GregorianCalendar) cal.clone();
cal.add(GregorianCalendar.MONTH, -1);
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
GetUpdatedResult updatedRecords = port.getUpdated("Mileage",
datatypeFactory.newXMLGregorianCalendar(cal),
datatypeFactory.newXMLGregorianCalendar(calEnd));
|
Uma operação similar para getUpdated é
getDeleted. Esse método tem a mesma assinatura de método e retorna todos os registros excluídos dentro de um determinado período.
A outra opção para consulta Salesforce é usando Salesforce Object Search Language (SOSL). SOSL é similar a procuras baseadas em texto, permitindo uma procura em uma formato mais livre. Com SOSL, é possível procurar em vários objetos não relacionados, mesmo quando você não souber quais objetos contêm os dados. As consultas feitas com SOSL podem também retornar vários objetos não relacionados.
O código na Listagem 4—um exemplo de consulta SOSL da amostra de Salesforce JAX-WS—é um excelente exemplo dessa flexibilidade. Esse código consulta contatos, perspectivas de vendas e contas em busca de números de telefone, mostrando como é possível pesquisar em vários objetos não relacionados.
Listagem 4. Pesquisando um número de telefone em vários objetos
SearchResult searchResult = port
.search("find {4159017000} in phone fields returning
contact(id, phone, firstname, lastname),
lead(id, phone, firstname, lastname),
account(id, phone, name)");
List<SearchRecord> records = searchResult.getSearchRecords();
List<Contact> contacts = new ArrayList<Contact>();
List<Lead> leads = new ArrayList<Lead>();
List<Account> accounts = new ArrayList<Account>();
if (records != null && !records.isEmpty()) {
for (SearchRecord recordType : records) {
SObject record = recordType.getRecord();
if (record instanceof Contact) {
contacts.add((Contact) record);
} else if (record instanceof Lead) {
leads.add((Lead) record);
} else if (record instanceof Account) {
accounts.add((Account) record);
}
}
}
|
Nesse exemplo, o método search é usado em vez de query para executar uma consulta SOSL. Os resultados são mapeados para um objeto SearchResults , e os registros individuais dos resultados da pesquisa são inspecionados para determinar o seu tipo.
Adicionando dados a Salesforce por meio de serviços da Web
Para adicionar dados ao Salesforce, use os mesmos objetos de domínio gerados a partir do WSDL corporativo. Esses objetos são preenchidos como objetos normais e serializados como XML para o servidor como persistência. O único desafio é criar relacionamentos entre os diferentes objetos. Por exemplo, suponha que você queira adicionar um novo registro de milhagem para um contato específico. Primeiro, é necessário pesquisar o ID do contato que deseja usar. Nesse exemplo, você pesquisa contatos de uma pessoa pelo nome Edna, como na Listagem 5.
Listagem 5. Descobrir um contato específico no banco de dados
QueryResult qr = login.port
.query("Select Id, FirstName, LastName, AccountId " +
"from Contact where FirstName = 'Edna'");
String contactID = null;
if (qr.getSize() > 0) {
Contact contact = (Contact) qr.getRecords().get(0);
contactID = contact.getId().getValue();
}
|
Essa consulta fornece o ID do primeiro contato em uma lista. (Em um aplicativo real, você quer fazer uma verificação de erros mais abrangente para ter certeza de que tem o registro correto.) Quando tiver o ID do usuário, armazene isso no seu novo registro de milhagem, na Listagem 6.
Listagem 6. Criar um novo registro de milhagem
MileageC mileageC = new MileageC();
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date());
XMLGregorianCalendar activityDate =
DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
mileageC.setDateC(soFactory.createMileageCDateC(activityDate));
mileageC.setMilesC(soFactory.createMileageCMilesC(new Double(300)));
mileageC.setContactC(soFactory.createMileageCContactC(contactID));
|
Agora que você configurou o registro de milhagem, chame o método create
no serviço da Web para persistir o registro para Salesforce. Observe que
create usa uma lista de objetos, permitindo que você adicione um lote de registros de milhagem. A Listagem 7 mostra o código para persistir os dados para Salesforce.
Listagem 7. Salvando um novo registro de milhagem no banco de dados
// call the create method passing the array of tasks as Sobjects
ArrayList list = new ArrayList();
list.add(mileageC);
List<SaveResult> saveResults = login.port.create(list);
for (SaveResult saveResult : saveResults) {
if (saveResult.isSuccess()) {
System.out.println("saveResult success, id= " + saveResult.getId());
} else {
System.out.println("saveResult error");
// there were errors during the create call, go through the
// errors and write them to the screen
List<Error> errorList = saveResult.getErrors();
for (Error error : errorList) {
System.out.println("Error code is: "
+ error.getStatusCode().toString());
System.out
.println("Error message: " + error.getMessage() + "\n\n");
}
}
}
|
Esse código persiste o registro para Salesforce e retorna uma lista dos resultados da gravação, que mostra se a gravação foi bem-sucedida ou falhou. As mensagens de erro retornadas do Salesforce tendem a ser bastante descritiva, facilitando a descoberta do que deu errado. Entretanto, essa abordagem simplista não assegura que os dados sejam salvos corretam ente no Salesforce. Para dados críticos, considere a recuperação automática para salvar os dados até eles serem salvos com êxito.
Da maneira similar, é possível atualizar os dados em Salesforce. A forma mais fácil é consultar primeiro o registro que deseja alterar e carregar o registro em um objeto. É possível atualizar o objeto e chamar o método update
.
A outra opção de atualização dos dados é mesclar registros duplicados. Com uma operação de mesclagem, você especifica um registro principal junto com o registro a ser mesclado. Dessa forma, você atualiza o registro principal com todos os dados do registro de mesclagem. É possível mesclar até três registros por vez.
Ao usar todos os benefícios do XML, é possível integrar com facilidade os dados da nuvem aos aplicativos corporativos existentes. XML fornece um formato de dados comum que pode ser trocado entre uma variedade de serviços e linguagens. O aplicativo de amostra deste artigo mostrou como é possível interagir com Salesforce por meio de serviços da Web XML usando SOAP especificamente.
Essa técnica de usar serviços da Web para integrar aplicativos no site aos dados na nuvem pode também ser usada com uma grande variedade de aplicativos diferentes, desde Google Apps a Basecamp. Na integração com serviços na nuvem, as organizações podem rapidamente criar uma variedade de novos aplicativos na nuvem e ainda aproveitar os investimentos existentes em software.
Aprender
- Princípios básicos de Force.com: obtenha mais informações sobre como Force.com trabalha com a nuvem.
- Workbook Force.com: saiba mais sobre o uso da plataforma Force.com para criar seu próprio aplicativo on demand com o workbook Force.com.
- JAX-WS: saiba mais sobre JAX-WS, que define APIs e convenções que oferecem suporte a protocolos de Chamada de Procedimento Real (RPC na plataforma Java.
- Guia do usuário JAX-WS: saiba o necessário para usar JAX-WS.
- Certificação XML da IBM: Descubra como se tornar um Desenvolvedor Certificado pela IBM em XML e tecnologias relacionadas.
- Biblioteca técnica de XML: Consulte a zona de XML para obter uma ampla gama de artigos técnicos e dicas, tutoriais, padrões e Redbooks da IBM.
- eventos técnicos e webcasts do developerWorks
: Mantenha-se atualizado em relação à tecnologia nessas sessões.
- Livraria de tecnologia: Procure livros sobre esses e outros tópicos técnicos.
- Podcasts do developerWorks: Ouça entrevistas e discussões interessantes para desenvolvedores de software.
Obter produtos e tecnologias
- Código de origem de milhagem: faça o download do código de origem do tutorial de milhagem do workbook Force.com.
- versões de avaliação de produto IBM: Faça o download ou explore as versões de teste on-line no IBM SOA Sandbox e entre em contato com as ferramentas de desenvolvimento de aplicativos e produtos de middleware do DB2®, Lotus®, Rational®, Tivoli®e WebSphere®.
Discutir
- Fóruns de discussão da zona de XML: Participe de qualquer uma das várias discussões relacionadas à XML.
- Blogs do developerWorks: confira estes blogs e participe da comunidade do developerWorks.
Ryan Knight é Senior Technical Consultant com mais de 12 anos de experiência ajudando empresas a utilizar as tecnologias mais recentes. Trabalha com empresas grandes e pequenas, como Oracle, IBM e Williams Pipeline, e já utilizou tecnologias que vão da computação em nuvem à arquitetura empresarial. É possível ler mais sobre sua ampla experiência em tecnologia Adobe Flex e Java no seu blog em anvilflex.com.