Artigo
· Nov. 1 12min de leitura

Desenvolvendo Integrações com InterSystems IRIS - REST Outbound Adapter

Projeto 8 – REST Outbound Adapter

Olá. Vamos montar nossa próxima integração utilizando o adaptador SOAP Inbound Adapter chamando um BP que chamará um BO que utilizará o REST Outbound Adapter.

O BO que vamos construir irá chamar o nosso BS que montamos no artigo https://pt.community.intersystems.com/post/desenvolvendo-integra%C3%A7%C3%B5es-com-o-intersystems-iris-aplica%C3%A7%C3%A3o-rest mas, importante, note que poderíamos chamar qualquer serviço interno no nosso integrador ou outra instância IRIS, ou externo em qualquer outro sistema com esse adaptador.

Vamos agora criar as classes de mensagem da nossa integração. Vamos reaproveitar as classes de Request e Response do serviço que montamos no artigo citado acima:

Class ws.demo.msg.Request Extends Ens.Request
{

Property string1 As %String;

Property string2 As %String;

}

Class ws.demo.msg.Response Extends Ens.Response
{

Property saida As %String;

Property status As %Boolean;

Property mensagem As %String;

Property sessionId As %Integer;

}

Vamos agora montar nosso BS que utilizará o adaptador SOAP Inbound Adapter:

Class ws.concatena.bs.Service Extends EnsLib.SOAP.Service
{

Parameter ADAPTER = "EnsLib.SOAP.InboundAdapter";

Parameter SERVICENAME = "concatena";

Method entrada(pInput As ws.demo.msg.Request) As ws.demo.msg.Response [ WebMethod ]
{
              Set tSC=..SendRequestSync("bpConcatena",pInput,.tResponse)
              Quit tResponse
}

}

Com o BS ponto podemos acessar o WSDL do serviço, já que ele é um serviço SOAP:

 

Vamos utilizar este endereço para carregar o serviço no SoapUI. Para mais informações sobre o SoapUI veja o post https://pt.community.intersystems.com/post/desenvolvendo-intergra%C3%A7%C3%B5es-com-o-intersystems-iris que tem dados de instalação e download. Faremos isso mais à frente.

Agora vamos criar nosso BO. O código está abaixo:

Class ws.concatena.bo.Operation Extends EnsLib.REST.Operation
{

Parameter INVOCATION = "Queue";

Method concatena(pRequest As ws.demo.msg.Request, Output pResponse As ws.demo.msg.Response) As %Status
{
   
   Try {

      Set pResponse = ##class(ws.demo.msg.Response).%New()
      Set tURL=..Adapter.URL_"?string1="_pRequest.string1_"&string2="_pRequest.string2
      Set tSC=..Adapter.GetURL(tURL,.tHttpResponse)
      If $$$ISERR(tSC)&&$IsObject(tHttpResponse)&&$IsObject(tHttpResponse.Data)&&tHttpResponse.Data.Size {
         Set tSC=$$$ERROR($$$EnsErrGeneral,$$$StatusDisplayString(tSC)_":"_tHttpResponse.Data.Read())
         Set pResponse.saida = ""                              
         Set pResponse.status = 0
         Set pResponse.mensagem = $SYSTEM.Status.GetErrorText(tSC)
      } Else {
                If $IsObject(tHttpResponse) {
                             Set stream=tHttpResponse.Data
               set obj = ##class(%DynamicAbstractObject).%FromJSON(stream)
               If $IsObject(obj){  
                   If obj.status = 1
                   {
                                           Set pResponse.saida = obj.saida                              
                                           Set pResponse.status = 1
                                           Set pResponse.mensagem = ""
                                           Set pResponse.sessionId=..%SessionId
                   } Else {
                                           Set pResponse.saida = ""                              
                                           Set pResponse.status = 0
                                           Set pResponse.mensagem = obj.mensagem
                                           Set pResponse.sessionId=..%SessionId                                           
                   }
               } Else {
                             Set pResponse.saida = ""                              
                             Set pResponse.status = 0
                             Set pResponse.mensagem = "Objeto não formado"
                             Set pResponse.sessionId=..%SessionId                          
                             }
                } Else {
               Set pResponse.saida = ""                              
               Set pResponse.status = 0
               Set pResponse.mensagem = "Falha na chamada do serviço REST"  
               Set pResponse.sessionId=..%SessionId            
                }
      }
   }Catch{
       Set tSC=$$$SystemError
       Set pResponse.saida = ""                              
       Set pResponse.status = 0
       Set pResponse.mensagem = $SYSTEM.Status.GetErrorText(tSC)
       Set pResponse.sessionId=..%SessionId   
   }
   Quit $$$OK
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="ws.demo.msg.Request">
    <Method>concatena</Method>
  </MapItem>
</MapItems>
}

}

Note que nosso BO estende de EnsLib.REST.Operation  por herança, e este por sua vez utiliza o adaptador EnsLib.HTTP.OutboundAdapter para as operações. Como nosso BO herda desta superclasse então esse parâmetro vem para nosso componente.

No nosso código utilizamos o método GetURL que irá chamar a URL informada com o verbo HTTP GET utilizando o servidor que está configurado no adaptador na produção (veremos como fazer isso mais à frente):

Set tURL=..Adapter.URL_"?string1="_pRequest.string1_"&string2="_pRequest.string2

Veja que utilizamos o parâmetro URL do adaptador, que é montado a partir das informações que serão preenchidas na production na configuração do nosso BO, e acrescentamos a query string que são os parâmetros que recebemos de entrada no nosso Request. Note que entre a chamada da URL e a query string temos o caracter “?” e separando cada parâmetro da query string temos o caracter “&”. Esta é a lei de formação deste tipo de chamada.

A resposta recebida da chamada HTTP é um JSON que está dentro de um stream.

Transformamos esse stream em um objeto com a chamada abaixo:

##class(%DynamicAbstractObject).%FromJSON(stream)  e uma vez que temos o objeto

Após criado podemos então manipular o objeto dentro do nosso código com facilidade.

Agora vamos montar nosso BP. Ele terá apenas a chamada ao nosso BO:

E o código do BP:

/// 
Class ws.concatena.bp.Process Extends Ens.BusinessProcessBPL [ ClassType = persistent, ProcedureBlock ]
{

/// BPL Definition
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='ws.demo.msg.Request' response='ws.demo.msg.Response' height='2000' width='2000' >
<sequence xend='200' yend='350' >
<call name='boConcatena' target='boConcatena' async='0' xpos='200' ypos='250' >
<request type='ws.demo.msg.Request' >
<assign property="callrequest" value="request" action="set" languageOverride="" />
</request>
<response type='ws.demo.msg.Response' >
<assign property="response" value="callresponse" action="set" languageOverride="" />
</response>
</call>
</sequence>
</process>
}

Storage Default
{
<Type>%Storage.Persistent</Type>
}

}

Veja o post https://pt.community.intersystems.com/post/desenvolvendo-integra%C3%A7%C3%B5es-com-intersystems-iris-call-no-business-process para mais detalhes da montagem de um CALL em um BP.

Vamos colocar nosso BS na production. Abra o Painel de Administração e vá para a nossa production de teste. Clique no botão (+) ao lado do nome Services e preencha a tela a seguir com os dados apresentados:

 

Agora volte a production e clique no nome do nosso BS (ws.concatena.bs.Service) e veja a configuração dele. Expanda a área Parâmetros de Conexão e marque a caixa Habilitar Requisições Padrão conforme a tela abaixo:

 

A seguir clique em Atualizar e nosso BS estará pronto.

 

Volte a tela da production. Clique no botão (+) ao lado do Operations e preencha a tela conforme abaixo:

Vamos agora entrar na configuração do nosso BO e terminar de ajustar o acesso. Vá em Parâmetros Básicos e preencha conforme a tela abaixo:

Em Servidor HTTP informe o endereço local do nosso ambiente, Porta HTTP informe 80 que é a porta padrão de requisições HTTP sem SSL, e em URL o caminho configurado para nossa API REST (/api/service/entrada).

Lembre que aqui você também pode usar o TCPTRACE para monitorar o tráfego entre a chamada do nosso BO e o serviço REST que estamos chamando. Para isso ative o TCPTRACE e no parâmetro Porta HTTP do nosso BP informe a porta em que o TCPTRACE está escutando as requisições.

IMPORTANTE: Você precisará ter feito os passos descritos no artigo https://pt.community.intersystems.com/post/desenvolvendo-integra%C3%A7%C3%B5es-com-o-intersystems-iris-aplica%C3%A7%C3%A3o-rest para ter esse serviço que será consumido aqui montado e configurado no seu ambiente.

Agora vamos para o nosso BP. Clique no botão (+) ao lado de Processes e preencha a tela com o dado do nosso BP:

 

Clique em OK e o BP será colocado na production. Agora veja como a production ficou:

 

 

Vamos agora carregar o WSDL do nosso BS no SoapUI. Para mais informações sobre o SoapUI veja o artigo https://pt.community.intersystems.com/post/desenvolvendo-intergra%C3%A7%C3%B5es-com-o-intersystems-iris-soap-inbound-adapter

 

Abra o SoapUI, vá em File->New SOAP Project e preencha o campo Initial WSDL com o endereço do WSDL do nosso BS:

Clique em OK, navegue no nosso projeto e vamos ter a interface criada:

 

 

Agora no SoapUI faça um teste. Preencha os campos string1 e string2 do nosso Request e envie a requisição. Clique no botão de play e veja a resposta recebida:

Veja a resposta recebida no SoapUI:

HTTP/1.1 200 OK

Cache-Control: no-cache

Pragma: no-cache

Content-Length: 460

Content-Type: text/xml; charset=UTF-8

Expires: Thu, 29 Oct 1998 17:04:19 GMT

Server: Microsoft-IIS/10.0

Date: Fri, 01 Nov 2024 14:39:15 GMT

 

<?xml version="1.0" encoding="UTF-8" ?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'>

  <SOAP-ENV:Body><entradaResponse xmlns="http://tempuri.org"><entradaResult><saida>Lua Azul</saida>

<status>true</status><mensagem></mensagem><sessionId>2496</sessionId></entradaResult></entradaResponse></SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Vá no Integrador e veja o trace da mensagem que você recebeu em sessionId (2496). Veja o primeiro trecho do trace com os dados de entrada:

E agora clique no último trecho e veja ops dados que foram retornados ao BS:

Assim realizamos o consumo de um serviço REST com o integrador. Utilizamos o verbo GET para recuperar uma informação.

Nós poderíamos ter utilizado um adaptador REST de entrada conforme vimos no artigo https://pt.community.intersystems.com/post/desenvolvendo-integra%C3%A7%C3%B5es-com-o-intersystems-iris-aplica%C3%A7%C3%A3o-rest e também poderíamos estar realizando diversas chamadas a partir do BP, realizando orquestração a diversos BOs, recuperando outras informações, e compondo um Response com dados vindos de diversas fontes.

Lembre-se que também  podemos colocar o TCPTRACE para verificar o tráfego que corre entre o SoapUI e o nosso BS, o que é especialmente útil em situações de teste.

Com isso concluímos esta integração. Utilizamos em nosso teste o IRIS 2024.1 que está disponível para download na sua versão Community na internet.

Discussão (0)1
Entre ou crie uma conta para continuar