Rechercher

Article
· Oct 23, 2024 3m de lecture

Desenvolvendo Integrações com InterSystems IRIS - CALL no Business Process

CALL no Business Process

Montando as integrações para esta série de postagens, vi que precisava me aprofundar um pouco mais na questão do componente CALL do BP. Assim montei este novo documento mostrando algumas informações importantes deste componente.

O componente CALL é utilizado para chamar ou um BP ou um BO de maneira síncrona (o componente aguarda o retorno da chamada realizada) ou assíncrona (a chamada é feita mas o componente não aguarda o retorno, sendo verificado se houve resposta em uma etapa mais a frente por um componente SYNC).

Para entendermos melhor o componente CALL vamos primeiro ver a configuração básica do nosso BP. Ao ser chamado o BP deve receber um objeto de entrada (request) e devolve um objeto de retorno (response). O tipo dos objetos de request e response do BP são definidos na aba Contexto do BP:

 

O request e response do BP ou BO a ser chamado pelo BP não é necessariamente o mesmo que o do próprio BP chamador. Pode ser, mas pode ser algo completamente diferente, montado em tempo de execução do BP chamador a partir de informações que ele vai recuperando.

Um CALL tem dois objetos que representam sua chamada: callrequest e callresponse, que são respectivamente o request utilizado na chamada ao componente que o CALL chamará e o response devolvido nesta chamada. Assim, por exemplo, se o objeto de chamada do meu CALL for o mesmo que o de entrada do BP podemos ter algo assim na configuração do CALL:

Ou seja, o callrequest será criado com o mesmo valor que o request do meu BP. Podemos fazer o mesmo com o response:

Ou seja, o response do meu BP será o response recebido pelo CALL do componente que ele chamou.

Aqui podemos ou utilizar o request e response diretamente, ou ainda, colocar os objetos recebidos no contexto do nosso BP. Para isso basta criar um objeto de contexto e fazer a atribuição:

 

Criado o objeto no contexto podemos ir no nosso CALL e atribuir a callrequest o valor deste objeto, por exemplo:

Nossa configuração de CALL então ficou assim:

O mesmo pode ser feito com o response, ou seja, posso criar um objeto no contexto e receber o que chegou no callresponse do CALL e atribuir o valor a esse objeto no contexto, e continuar utilizando dentro do código do BP.

O componente CALL é especialmente poderoso pois posso fazer as atribuições de valores das propriedades do objeto dentro dele, o que facilita o entendimento e a manutenção do código.

Assim, podemos resumir essa postagem ao seguinte:

  • request é o objeto que tem a entrada de informações do BP. Ele é válido em todo o contexto do BP. A atribuição da classe deste objeto é feita no Contexto do BP;
  • response é o objeto de resposta do BP. Ele também é válido em todo o contexto do BP. A atribuição da classe deste objeto é feita no Contexto do BP;
  • callrequest é o objeto que tem a entrada de informações do CALL que está sendo executado, e que será usado para chamar o componente configurado no CALL. Ele é válido apenas dentro do contexto do CALL em execução;
  • callresponse é o objeto que tem o retorno de informações do CALL que está sendo executado. Ele é válido apenas dentro do contexto do CALL em execução;

Lembre-se ainda que o IRIS implementa polimorfismo. O polimorfismo habilita que um objeto de uma classe seja manipulado como um objeto de uma outra classe, desde que esta outra classe seja uma superclasse da minha classe. Por exemplo, funcionário tem como superclasse pessoa, então funcionário herda todos os métodos e propriedades de pessoa. Posso então manipular funcionário com os mesmos códigos que manipulo pessoa. Isso no contexto do nosso CALL pode ser traduzido dizendo que se ele espera receber um objeto do tipo pessoa, caso receba um objeto do tipo funcionário ele vai trabalhar corretamente também. O inverso não é verdadeiro pois pessoa pode ter métodos e propriedades a menos que funcionário.

O IRIS também implementa herança múltipla, ou seja, uma classe pode herdar métodos e propriedades de diversas superclasses.

Assim fechamos mais este artigo. Em breve teremos mais postagens mostrando novas integrações. Até lá.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Article
· Oct 23, 2024 9m de lecture

Desenvolvendo Integrações com InterSystems IRIS - Chamada Assíncrona no BP

Projeto 6 – Chamada Assíncrona no BP

Vamos montar nossa próxima integração utilizando o adaptador SOAP Inbound Adapter chamando um BP que vai orquestrar chamadas a dois BOs em modo assíncrono.

Vamos começar criando as mensagens de Request e Response do nosso serviço:

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

Property cpf As %String(PATTERN = "1N.N");

}

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

Property nome As %String;

Property cpf As %String(PATTERN = "1N.N");

Property autorizado As %Boolean;

Property servico As %String;

Property status As %Boolean;

Property mensagem As %String;

Property sessionId As %Integer;

}

Agora vamos ver o nosso BS, que como mencionado acima usa o SOAP Inbound Adapter:

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

Parameter ADAPTER = "EnsLib.SOAP.InboundAdapter";

Parameter SERVICENAME = "credito";

Method consulta(pInput As ws.credito.msg.Request) As ws.credito.msg.Response [ WebMethod ]
{
              Set tSC=..SendRequestSync("bpCredito",pInput,.tResponse)
              Quit tResponse
}

}

Vamos agora 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.credito.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 de teste estará pronto.

Vamos agora ver nosso BO. Desta vez vamos colocar o BO na production duas vezes, com nomes diferentes. Cada BO vai simular a chamada a um serviço de validação de crédito com tempos de retorno diferentes para cada requisição. Abaixo o código do nosso BO:

Class ws.credito.bo.Operation Extends Ens.BusinessOperation [ ProcedureBlock ]
{

Method consulta(pRequest As ws.credito.msg.Request, Output pResponse As ws.credito.msg.Response) As %Library.Status
{
 Hang $R(10)+1
 Set pResponse=##Class(ws.credito.msg.Response).%New()
 Set pResponse.nome="NOME DA PESSOA "_pRequest.cpf
 Set pResponse.cpf=pRequest.cpf
 Set pResponse.autorizado=0
 If pRequest.cpf="11111111111"
 {
               Set pResponse.nome="PESSOA NUMERO 1"
               Set pResponse.autorizado=1
 }
 If pRequest.cpf="22222222222"
 {
               Set pResponse.nome="PESSOA NUMERO 2"
               Set pResponse.autorizado=1
 }
 If pRequest.cpf="33333333333"
 {
               Set pResponse.nome="PESSOA NUMERO 3"
               Set pResponse.autorizado=1
               Set pResponse.status=1
 }
 If pRequest.cpf="44444444444"
 {
               Set pResponse.nome="PESSOA NUMERO 4"
               Set pResponse.autorizado=1
               Set pResponse.status=1
 } 
 Set pResponse.status=1
 Set pResponse.mensagem="OK"
 Set pResponse.sessionId=..%SessionId 
 Quit $$$OK
}

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

}

A linha Hang $R(10)+1 vai definir um tempo de espera entre 1 e 10 segundos para as requisições que o BO for atender. Isso é para simular um tempo de resposta no serviço.

Feito o código do BO vamos coloca-lo na production. Primeiro vamos colocar o BO com o nome de boConsultaCreditoABC. Para isso clique no botão de (+) ao lado do nome Operations na nossa production e preencha a tela conforme abaixo:

 

Depois repita a operação, agora incluindo o BO boConsultaCreditoXYZ:

 

Pronto. Temos os nossos dois BOs na production. Agora vamos ver o nosso BP:

O nosso BP tem agora dois BOs que estão sendo chamados sem espera e depois tem um componente SYNC que aguarda o retorno destas chamadas pelo tempo configurado. É importante verificar que nas chamadas dos BOs (componente CALL) temos que marcar a caixa informado que a chamada será ASSÍNCRONA:

 

Faça o mesmo para o boConsultaCreditoXYZ:

 

 

Agora, no nosso componente SYNC vamos dizer que devem ser esperadas as respostas dos nossos BOs e o tempo de espera:

 

Na caixa Chamadas informamos os nomes dos BOs a aguardar (boConsultaCreditoABC e boConsultaCreditoXYZ) e na caixa Timeout o tempo de espera (5 segundos). Lembre-se: um BP pode chamar outros BPs ou outros BOs.

 

O código completo do nosso BP está abaixo:

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

/// BPL Definition
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='ws.credito.msg.Request' response='ws.credito.msg.Response' height='2000' width='2000' >
<sequence xend='200' yend='1450' >
<call name='boConsultaCreditoABC' target='boConsultaCreditoABC' async='1' xpos='200' ypos='250' >
<request type='ws.credito.msg.Request' >
<assign property="callrequest" value="request" action="set" languageOverride="" />
</request>
<response type='ws.credito.msg.Response' >
<assign property="response" value="callresponse" action="set" languageOverride="" />
</response>
</call>
<call name='boConsultaCreditoXYZ' target='boConsultaCreditoXYZ' async='1' xpos='200' ypos='350' >
<request type='ws.credito.msg.Request' >
<assign property="callrequest" value="request" action="set" languageOverride="" />
</request>
<response type='ws.credito.msg.Response' >
<assign property="response" value="callresponse" action="set" languageOverride="" />
</response>
</call>
<sync name='Aguarda Operations' calls='boConsultaCreditoABC,boConsultaCreditoXYZ' timeout='5' type='all' xpos='200' ypos='450' />
<if name='Recebeu ABC' condition='$IsObject(syncresponses.GetAt("boConsultaCreditoABC"))' xpos='200' ypos='550' xend='200' yend='1350' >
<true>
<assign name="Atribui response ABC" property="response" value="syncresponses.GetAt(&quot;boConsultaCreditoABC&quot;)" action="set" languageOverride="" xpos='200' ypos='700' />
<assign name="Atribui servico" property="response.servico" value="&quot;ABC&quot;" action="set" languageOverride="" xpos='200' ypos='800' />
</true>
<false>
<if name='Recebeu XYZ' condition='$IsObject(syncresponses.GetAt("boConsultaCreditoXYZ"))' xpos='470' ypos='700' xend='470' yend='1250' >
<true>
<assign name="Atribui response XYZ" property="response" value="syncresponses.GetAt(&quot;boConsultaCreditoXYZ&quot;)" action="set" languageOverride="" xpos='470' ypos='850' />
<assign name="Atribui servico" property="response.servico" value="&quot;XYZ&quot;" action="set" languageOverride="" xpos='470' ypos='950' />
</true>
<false>
<assign name="Atribui CPF" property="response.cpf" value="request.cpf" action="set" languageOverride="" xpos='740' ypos='850' />
<assign name="Atribui status Erro" property="response.status" value="0" action="set" languageOverride="" xpos='740' ypos='950' />
<assign name="Atribui msg Erro" property="response.mensagem" value="&quot;Sem resposta do serviço&quot;" action="set" languageOverride="" xpos='740' ypos='1050' />
<assign name="Atribui SessionID" property="response.sessionId" value="..%Process.%SessionId" action="set" languageOverride="" xpos='740' ypos='1150' />
</false>
</if>
</false>
</if>
</sequence>
</process>
}

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

}

 

Com nossos componentes na production clique na bola verde ao lado de bpCredito e veja as ligações dos componentes:

Vamos visualizar o WSDL do nosso serviço. Para isso abra o navegador e vá para o endereço http://localhost/iris_iss/csp/integra/ws.credito.bs.Service.cls?WSDL=1 (troque íris_iss pelo nome da sua configuração IRIS e integra pelo namespace onde você está colocando seu código). Você verá uma tela assim:

 

Abra então o SoapUI e importe o WSDL. Vá em File->New SOAP Project e na janela que será apresentada coloque o endereço do WSDL na caixa Initial WSDL e a seguir clique em OK:

 

 

Project Name será preenchido automaticamente. Após o OK será disponibilizada a interface de teste do serviço:

 

 

Substitua o ? no XML pelo valor do CPF a consultar. Veja no BO as opções possíveis para respostas válidas. Por exemplo, 11111111111:

 

 

Veja que recebemos um XML com a resposta do serviço, informando qual BO atendeu nossa chamada:

 

 

 

 

<?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><consultaResponse xmlns="http://tempuri.org"><consultaResult><nome>PESSOA NUMERO 1</nome><cpf>11111111111</cpf><autorizado>true</autorizado><servico>XYZ</servico><status>true</status><mensagem>OK</mensagem><sessionId>2266</sessionId></consultaResult></consultaResponse></SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

Verificando o trace da integração de SessionID 2266 vemos o que ocorreu:

Pelo trace podemos ver que o Response do boConsultaCreditoXYZ voltou rapidamente, enquanto que o Response do BO boConsultaCreditoABC demorou e voltou apenas depois do tempo de espera do componente SYNC. Ou seja, o componente SYNC aguardou até 5 segundos pelo retorno dos BOs. Uma vez superado o tempo de espera verificamos quais os BOs que responderam e realizamos o tratamento desejado. Veja a lógica nos IFs que temos no nosso BP.

Lembre-se que podemos colocar o TCPTRACE para verificar o tráfego que ocorre 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.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Question
· Oct 23, 2024

How to search message details in LIVE based on MRN

Hello Experts ,

Could you help to search message details based on MRN in intersytems iris. 

We have created 100+ interfaces and currenly in live (interystems cloud) . Now I try to search message details based on MRN using below query. it is working fine in DEV. but in prod it is taking ages.

SELECT Header.SessionId, Header.SourceConfigName ,Body.RawContent
FROM Ens.MessageHeader AS Header 
JOIN EnsLib_HL7.Message AS Body ON Header.MessageBodyId = Body.ID     
 where  Body.TimeCreated BETWEEN '2023-03-15 13:10:22.993' AND '2023-03-15 13:10:25.993'
 AND Body.RawContent LIKE '%40103262%'

could you please provide me any idea .

thanks you

2 Comments
Discussion (2)3
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Oct 23, 2024

20,000 members on the InterSystems Developer Community!

Drumroll, please...

🎉 The InterSystems Developer Community has officially surpassed 20,000 registered members! 🎉

But that’s not all – we’ve also achieved some impressive milestones:

📝 21,500 published posts

👁 10,000,000 views

We want to take a moment to celebrate with all of you who have made this possible!

In what feels like the blink of an eye, our community has EXPLODED in size 🤯. We’ve doubled in size in just two years' time! It’s not just numbers — it’s the impact YOU are making, and we couldn’t be more grateful!

This phenomenal growth is all thanks to you — our amazing community of developers, contributors, and trailblazers! Whether you're sharing your expertise and next-level insights, asking thought-provoking questions, or collaborating with others, you are the heartbeat of this Community. ❤️‍🔥 You’re transforming this platform into a powerhouse of ideas and solutions, and we are here for it!

🌍🫂 With six regional communities in different languages (EN, ES, PT, JP, CN, FR), we’re uniting developers from all over the globe, making the InterSystems Developer Community a truly global hub.

👏 A special shoutout to our superstar moderators, content managers, and admins who keep this incredible machine running smoothly. Your dedication keeps the gears turning, and we couldn’t do it without you!

But guess what? This is just the beginning!
We’re excited to keep growing, learning, and innovating TOGETHER. Whether you're new to the community or a long-time member, there’s so much more ahead for all of us!

THANK YOU!

---

Sincerely yours,
InterSystems Developer Community Team

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Article
· Oct 23, 2024 1m de lecture

file2Xml 一个将文件转换成Studio导出的xml格式的工具

file2Xml 

一个将文件转换成Studio导出的xml格式的工具

通过此工具可以将本地文件转换成xml格式文件,然后通过Studio导入到服务器中,而不再需要其他工具将文件传至服务器。


下面以为ensemble2016自带的一个示例界面增加背景图为例。

http://localhost:57772/csp/samples/cinema/Cinema.csp

1.选择数据版本信息并录入web应用程序(SMP--系统--安全管理--Web 应用程序)

确定此示例界面的Web应用程序为:/csp/samples

2.点击“选择文件”,选择需要转换的文件

选择本地电脑要作为背景图的图片

3.录入每个文件导入后相对于web应用程序的路径和导入后的文件名

想要放到cinema下,故相对于web应用程序的路径为:cinema

想要将文件命名为:search_bg.jpg

4.勾选最终需要转换的文件,并点击“转换”

5.录入转换出的xml文件名,点击“确定”

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer