Pesquisar

Limpar filtro
Anúncio
Danusa Calixto · Jun. 12, 2023

Está finalizado o prazo de publicação para o 2º Concurso de Artigos Técnicos em Português da InterSystems!

Olá Comunidade! Está chegando ao fim o 🏆 2º Concurso de Artigos Técnicos em Português da InterSystems 🏆A partir de agora começa o período de votação dos Especialistas da Comunidade, mas a votação da comunidade ainda está valendo. Todos os artigos serão avaliados e validados de acordo com as regras do concurso, os votos e bonus serão contabilizados, e em breve será divulgado o resultado do concurso. Desde já a Comunidade de Desenvolvedores PT agradece a todos os participantes, e deseja Boa Sorte a todos! O Concurso está finalizando mas a nossa Comunidade continua ativa e contando com a colaboração de todos vocês. Continuem ligados nos anúncios e artigos da Comunidade de Desenvolvedores 😉
Artigo
Larissa Prussak · Jun. 17

Convertendo Consultas Hierárquicas do Oracle para o InterSystems IRIS: Gerando Intervalos de Datas

Se você está migrando do Oracle para o InterSystems IRIS — como muitos dos meus clientes — pode se deparar com padrões específicos de SQL do Oracle que precisam ser adaptados. Veja esse examplo: SELECT (TO_DATE('2023-05-12','YYYY-MM-DD') - LEVEL + 1) AS gap_date FROM dual CONNECT BY LEVEL <= (TO_DATE('2023-05-12','YYYY-MM-DD') - TO_DATE('2023-05-02','YYYY-MM-DD') + 1); No Oracle: LEVEL é uma pseudo-coluna usada em consultas hierárquicas (com CONNECT BY). Ela começa em 1 e incrementa de 1 em 1. CONNECT BY LEVEL <= (...) define quantas linhas a consulta deve gerar. A diferença entre as duas datas, somada a 1, resulta em 11 — então a consulta gera 11 linhas, contando de 12 de maio de 2023 para 2 de maio de 2023. Detalhamento do resultado: LEVEL = 1 → 2023-05-12 LEVEL = 2 → 2023-05-11 ... LEVEL = 11 → 2023-05-02 Agora a questão é: Como fazer isso no InterSystems IRIS, que não possui CONNECT BY? Uma solução é implementar uma consulta no estilo SQL usando ObjectScript, simulando esse comportamento. Abaixo está um exemplo de definição CREATE QUERY que aceita uma data inicial (STARTDATE) e um número de dias (DAYS), e retorna a lista decrescente de datas. ✅ InterSystems IRIS: Implementando uma consulta de intervalo de datas CREATE QUERY GET_GAP_DATE(IN STARTDATE DATE, IN DAYS INT) RESULTS (GAP_DATE DATE) PROCEDURE LANGUAGE OBJECTSCRIPT Execute(INOUT QHandle BINARY(255), IN STARTDATE DATE, IN DAYS INT) { SET QHandle("start") = STARTDATE SET QHandle("days") = DAYS SET QHandle("level") = 1 RETURN $$$OK } Fetch(INOUT QHandle BINARY(255), INOUT Row %List, INOUT AtEnd INT) { IF (QHandle("level") > QHandle("days")) { SET Row = "" SET AtEnd = 1 } ELSE { SET Row = $ListBuild(QHandle("start") - QHandle("level") + 1) SET QHandle("level") = QHandle("level") + 1 } RETURN $$$OK } Close(INOUT QHandle BINARY(255)) { KILL QHandle QUIT $$$OK } Você pode executar esse CREATE QUERY no IRIS System Management Portal, ou por ferramentas como DBeaver ou um notebook Python/Jupyter via JDBC/ODBC. 🧪 Examplo de uso: Para gerar o mesmo resultado da consulta Oracle acima, use: SELECT * FROM GET_GAP_DATE( TO_DATE('2023-05-12', 'YYYY-MM-DD'), TO_DATE('2023-05-12', 'YYYY-MM-DD') - TO_DATE('2023-05-02', 'YYYY-MM-DD') + 1 ); Isso vai gerar: GAP_DATE ---------- 2023-05-12 2023-05-11 ... 2023-05-02 (11 rows) 🔁 Uso avançado: junção com outras tabelas Você também pode utilizar essa consulta como subconsulta ou em JOINs: SELECT * FROM GET_GAP_DATE(TO_DATE('2023-05-12', 'YYYY-MM-DD'), 11) CROSS JOIN dual; Isso permite integrar intervalos de datas em workflows SQL mais complexos. Espero que isso ajude quem estiver lidando com cenários de migração de Oracle para IRIS! Se você já criou soluções alternativas ou tiver sugestões de melhorias, adoraria ouvir suas ideias.
Artigo
Vinicius Maranhao Ribeiro de Castro · Out. 7, 2020

Protegendo suas APIs com OAuth 2.0 no InterSystems API Management - Parte 1

Introdução Hoje em dia existem muitas aplicações que estão usando o Open Authorization framework (OAuth) para acessar recursos de todos os tipos de serviços de maneira segura, confiável e eficiente. O InterSystems IRIS já é compatível com a estrutura OAuth 2.0, na verdade, há um ótimo artigo na comunidade sobre OAuth 2.0 e InterSystems IRIS no seguinte link [aqui](https://community.intersystems.com/post/intersystems-iris-open-authorization-framework-oauth-20-implementation-part-1). No entanto, com o advento das ferramentas de gerenciamento de API, algumas organizações estão usando-as como um único ponto de autenticação, evitando que solicitações não autorizadas cheguem aos serviços de downstream e desacoplando as complexidades de autorização/autenticação do próprio serviço. Como você deve saber, a InterSystems lançou sua ferramenta de gerenciamento de API, chamada InterSystems API Management (IAM), que está disponível com a licença IRIS Enterprise (mas não com o IRIS Community Edition). [Aqui](https://community.intersystems.com/post/introducing-intersystems-api-manager) esta outra ótima postagem na comunidade apresentando o InterSystems API Management.  Esta é a primeira parte de uma série de artigos de três partes que mostram como você pode usar o IAM para simplesmente adicionar segurança, de acordo com os padrões do OAuth 2.0, a um serviço não autenticado implantado no IRIS anteriormente. Nesta primeira parte, serão fornecidos alguns antecedentes do OAuth 2.0 juntamente com algumas definições e configurações iniciais do IRIS e IAM para facilitar a compreensão de todo o processo de proteção de seus serviços. Após a primeira parte, esta série de artigos abordará dois cenários possíveis para proteger seus serviços com IAM. No primeiro cenário, o IAM validará apenas o token de acesso presente na solicitação de entrada e encaminhará a solicitação para o backend se a validação for bem-sucedida. No segundo cenário, o IAM irá gerar um token de acesso (atuando como um servidor de autorização) e validá-lo. Portanto, a segunda parte irá discutir e mostrar em detalhes as etapas necessárias para configurar o cenário 1 e a terceira parte irá discutir e demonstrar as configurações do cenário 2, juntamente com algumas considerações finais. Se você quiser testar o IAM, entre em contato com seu representante de vendas da InterSystems. OAuth 2.0 - A Experiência Cada fluxo de autorização OAuth 2.0 consiste basicamente em 4 partes: 1. Usuário 2. Cliente 3. Servidor de Autorização 4. Proprietário do Recurso Para simplificar, este artigo usará o fluxo OAuth “Credenciais da Senha do Proprietário do Recurso”, mas você pode usar qualquer fluxo OAuth no IAM. Além disso, este artigo não especificará nenhum escopo. Nota: Você só deve usar o fluxo de Credenciais da Senha do Proprietário do Recurso quando a aplicação cliente for altamente confiável, pois ela lida diretamente com as credenciais do usuário. Na maioria dos casos, o cliente deve ser uma aplicação primária. Normalmente, o fluxo de Credenciais da Senha do Proprietário do Recurso segue estas etapas: 1. O usuário insere as credenciais (por exemplo, nome de usuário e senha) na aplicação cliente 2. A aplicação cliente envia as credenciais do usuário junto com sua própria identificação (id do cliente e segredo do cliente, por exemplo) para o servidor de autorização. O servidor de autorização valida as credenciais do usuário e a identificação do cliente e retorna um token de acesso 3. O cliente usa o token para acessar recursos no servidor de recursos 4. O servidor de recursos valida o token de acesso recebido antes de retornar qualquer informação ao cliente Com isso em mente, existem dois cenários em que você pode usar o IAM para lidar com o OAuth 2.0: 1. O IAM atuando como um validador, verificando o token de acesso fornecido pela aplicação cliente, encaminhando a solicitação para o servidor de recursos apenas se o token de acesso for válido. Neste caso, o token de acesso seria gerado por um servidor de autorização de terceiros 2. O IAM atua como um servidor de autorização, fornecendo token de acesso ao cliente, e como um validador de token de acesso, verificando o token de acesso antes de redirecionar a solicitação ao servidor de recursos. Definições de IRIS e IAM Nesta postagem, será utilizado uma aplicação IRIS Web denominada “/SampleService”. Como você pode ver na captura de tela abaixo, este é um serviço REST não autenticado implantado no IRIS:   Adicionalmente, é configurado um serviço chamado “SampleIRISService” no lado do IAM contendo uma rota, como você pode ver na imagem abaixo:   Além disso, é configurado um consumidor chamado “ClientApp” no IAM, inicialmente sem nenhuma credencial, para identificar quem está chamando a API no IAM:   Com as configurações acima, o IAM faz proxy para o IRIS a cada solicitação GET enviada para a seguinte URL: **http://iamhost:8000/event** Neste ponto, nenhuma autenticação é usada ainda. Portanto, se enviarmos uma solicitação GET simples, sem autenticação, para a URL **http://iamhost:8000/event/1** obtemos a resposta desejada. Neste artigo, vamos usar uma aplicação chamada “PostMan” para enviar solicitações e verificar as respostas. Na captura de tela abaixo do PostMan, você pode ver a solicitação GET simples junto com sua resposta. Continue lendo até a segunda parte desta série para entender como configurar o IAM para validar os tokens de acesso presentes nas solicitações de entrada.
Artigo
Daniel Kutac · Nov. 19, 2022

Implementação do Open Authorization Framework (OAuth 2.0) na InterSystems IRIS – parte 1

Este artigo e os próximos dois artigos da série são um guia do usuário para desenvolvedores ou administradores de sistema que precisam usar o framework OAuth 2.0 (chamado de OAUTH para simplificar) em suas aplicações baseadas no produto InterSystems. Criado por Daniel Kutac, Engenheiro de vendas sênior, InterSystems # Histórico de correções e alterações após a publicação * 3 de agosto de 2016 – Correção da captura de tela da configuração do Google Client; atualização da captura de tela das APIs do Google para refletir a nova versão das páginas. * 28 de agosto de 2016 – Alterações do código JSON devido às mudanças no suporte ao JSON do Caché 2016.2. * 3 de maio de 2017 – Atualizações do texto e imagens para refletir a nova interface gráfica e os novos recursos lançados no Caché 2017.1.  * 19 de fevereiro de 2018 – Alteração de Caché para InterSystems IRIS para refletir os desenvolvimentos mais recentes. Porém, é importante salientar que, apesar da alteração do nome do produto, o **artigo aborda todos os produtos da InterSystems**: InterSystems IRIS Data Platform, Ensemble e Caché. * 17 de agosto de 2020 – Tudo muda, especialmente o software. Consulte o URL do OAuth2 do Google atualizado na resposta do Micholai Mitchko. _Parte 1. Cliente_ # **Introdução** Esta é a primeira parte de uma série de três artigos sobre a implementação do Open Authorization Framework na InterSystems. Nesta primeira parte, apresentamos uma breve introdução do tópico e mostramos um cenário simples em que a aplicação InterSystems IRIS atua como cliente de um servidor de autorização, solicitando alguns recursos protegidos. A segunda parte descreverá um cenário mais complexo, em que a InterSystems IRIS atua como servidor de autorização e também como servidor de autenticação via OpenID Connect. A última parte da série descreverá partes individuais das classes do framework OAUTH conforme implementadas pela InterSystems IRIS. ## **Sobre o Open Authorization Framework[1]** Muitos de vocês já ouviram falar do Open Authorization Framework e para que ele pode ser usado. Vamos resumir para quem ainda não tiver ouvido falar dele. O Open Authorization Framework, OAUTH, atualmente na versão 2.0, é um protocolo que permite principalmente que aplicações web troquem informações de forma segura estabelecendo uma confiança indireta entre um cliente (aplicação que solicita dados) e o proprietário dos recursos (aplicação que detém os dados solicitados). A confiança é fornecida por uma entidade que tanto o cliente quanto o servidor de recursos reconhecem e na qual confiam. Essa entidade é chamada de servidor de autorização. Veja um caso de uso simples: Vamos supor que Jenny (na terminologia do OAUTH, é o proprietário dos recursos) esteja trabalhando em um projeto na empresa JennyCorp. Ela cria um plano de projeto para um possível negócio maior e convida seu parceiro comercial John (usuário cliente) da empresa JohnInc para revisar o documento. Mas ela não está contente de dar ao John acesso à VPN de sua empresa, então ela coloca o documento no Google Drive (o servidor de recursos) ou outra ferramenta de armazenamento em nuvem similar. Ao fazer isso, ela estabeleceu uma confiança entre ela e o Google (o servidor de autorização). Ela compartilha o documento com John (John já usa o serviço Google Drive, e Jenny sabe qual é o e-mail dele). Quando John deseja ler o documento, ele faz a autenticação em sua conta do Google e, em seu dispositivo móvel (tablet, notebook, etc.), abre um editor de documentos (o servidor cliente) e carrega o arquivo do projeto da Jenny. Embora pareça bem simples, há muita comunicação entre as duas pessoas e o Google. Todas as comunicações seguem a especificação do OAuth 2.0, então o cliente de John (o leitor de documentos) precisa primeiro fazer a autenticação no Google (essa etapa não é coberta pelo OAUTH) e, após John consentir autorização no formulário fornecido pelo Google, o Google autoriza que o leitor de documentos acesse o documento emitindo um token de acesso. O leitor de documentos usa o token de acesso para emitir uma solicitação ao serviço Google Drive para obter o arquivo de Jenny. O diagrama abaixo mostra a comunicação entre todas as partes ![](/sites/default/files/inline/images/1_3.png) Nota: embora todas as comunicações do OAUTH 2.0 sejam feitas por solicitações HTTP, os servidores não precisam ser aplicações web. Vamos ilustrar esse cenário simples com a InterSystems IRIS.  # **Demonstração simples do Google Drive** Nesta demonstração, vamos criar uma aplicação de pequeno porte baseada em Cloud Solution Provider (CSP) que solicita recursos (lista de arquivos) armazenados no serviço Google Drive com nossa própria conta (e também uma lista de nossos calendários, como bônus). ## **Pré-requisitos** Antes de começarmos a programar a aplicação, precisamos preparar o ambiente. Precisaremos de um servidor web com SSL ativado e um perfil do Google. ### **Configuração do servidor web** Conforme informado acima, precisamos estabelecer comunicação com o servidor de autorização com SSL, pois isso é exigido pelo OAuth 2.0 por padrão. Queremos manter nossos dados seguros, certo? Está fora do escopo deste artigo descrever como configurar um servidor web com suporte ao SSL, então consulte os manuais de usuário do servidor web de sua preferência. Usaremos o servidor IIS da Microsoft neste exemplo específico. ### **Configuração do Google** Para nos registrarmos no Google, precisamos usar o Google API Manager: Para o propósito da demonstração, criamos uma conta GlobalSummit2016Demo. É preciso confirmar se a API do Drive está ativada ![](/sites/default/files/inline/images/o2.png) Agora, está na hora de definir as credenciais ![](/sites/default/files/inline/images/o3.png) Observe o seguinte: _Authorized JavaScript (JavaScript autorizado) –  permitimos somente scripts originados localmente em relação à página chamadora _Authorized redirect URIs (URIs de redirecionamento autorizados) –  teoricamente, podemos redirecionar nossa aplicação cliente para qualquer site, mas, ao usar a implementação do OAUTH da InterSystems IRIS, precisamos redirecioná-la para **https://localhost/csp/sys/oauth2/OAuth2.Response.cls.** É possível definir vários URIs de redirecionamento autorizados, conforme mostrado na captura de tela, mas, para esta demonstração, só precisamos da segunda entrada. Por último, precisamos configurar a InterSystems IRIS como cliente do servidor de autorização do Google ### **Configuração do Caché** A configuração do cliente OAUTH2 da InterSystems IRIS é um processo de duas etapas. Primeiro, precisamos criar uma configuração de servidor. No SMP, acesse **System Administration (Administração do Sistema) > Security (Segurança) > OAuth 2.0 > Client Configurations (Configurações do cliente)**. Clique no botão **Create Server Configuration (Criar configuração de servidor)**, preencha o formulário e salve. ![](/sites/default/files/inline/images/oauth2_1_google_server.png) Todas as informações inseridas no formulário estão disponíveis no site do console de desenvolvedores do Google. A InterSystems IRIS tem suporte à descoberta automática do Open ID. Entretanto, não estamos usando esse recurso. Inserimos todas as informações manualmente  Agora, clique no link Client Configurations (Configurações do cliente) ao lado do Issuer Endpoint (Endpoint emissor) recém-criado e clique no botão **Create Client Configuration (Criar configuração de cliente)**. ![](/sites/default/files/inline/images/2_6.png) Deixe as abas Client Information (Informações do cliente) e JWT Settings (Configurações do JWT) em branco (com os valores padrão) e preencha a aba Client credentials (Credenciais do cliente). ![](/sites/default/files/inline/images/3_5.png) Nota: estamos criando um Confidential Client (Cliente confidencial – é mais seguro que o público e significa que o segredo do cliente nunca deixa a aplicação do servidor cliente – nunca é transmitido ao navegador) Além disso, confirme se **Use SSL/TLS (Usar SSL/TLS)** está marcado e forneça o nome do host (localhost, já que estamos redirecionando localmente para a aplicação cliente) e, posteriormente, a porta e o prefixo (útil quando há várias instâncias da InterSystems IRIS na mesma máquina). Com base nas informações preenchidas, o URL de redirecionamento do cliente é computado e exibido na linha acima. Na captura de tela acima, fornecemos uma configuração SSL chamada GOOGLE. O nome é usado somente para ajudar a determinar qual configuração SSL dentre várias é usada por esse canal de comunicação específico. O Caché está usando configurações SSL/TLS para armazenar todas as informações necessárias para receber/enviar tráfego seguro ao servidor (neste caso, os URIs OAuth 2.0 do Google). Consulte mais detalhes na [documentação](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_ssltls#GCAS_ssltls_aboutconfigs). Preencha os valores Client ID (ID do cliente) e Client Secret (Segredo do cliente) obtidos pelo formulário de definição das credenciais do Google (ao fazer a configuração manual). Agora, concluímos todas as etapas de configuração e podemos prosseguir para a programação de uma aplicação CSP. ## **Aplicação cliente** A aplicação cliente é uma aplicação CSP web simples. Ela é composta por um código fonte no servidor, definido e executado pelo servidor web, e uma interface do usuário, exibida ao usuário por um navegador. O exemplo de código fornecido espera que a aplicação cliente seja executada no namespace GOOGLE. Modifique o caminho /csp/google/  para o seu namespace. ## **Servidor cliente** O servidor cliente é uma aplicação simples de duas páginas. Dentro da aplicação, nós vamos: ·        Montar o URL de redirecionamento para o servidor de autorização do Google ·        Fazer solicitações à API do Google Drive e à API do Google Agenda e exibir o resultado ### **Página 1** Esta é uma página da aplicação, na qual decidimos fazer uma chamada aos recursos do Google. Veja abaixo um código minimalista, mas completamente funcional, que representa a página. Class Web.OAUTH2.Google1N Extends %CSP.Page { Parameter OAUTH2CLIENTREDIRECTURI = "https://localhost/csp/google/Web.OAUTH2.Google2N.cls"; Parameter OAUTH2APPNAME = "Google"; ClassMethod OnPage() As %Status { &html<<html> <head> </head> <body style="text-align: center;"> <!-- insert the page content here --> <h1>Google OAuth2 API</h1> <p>This page demo shows how to call Google API functions using OAuth2 authorization. <p>We are going to retrieve information about user and his/her Google Drive files as well as calendar entries. > // we need to supply openid scope to authenticate to Google set scope="openid https://www.googleapis.com/auth/userinfo.email "_ "https://www.googleapis.com/auth/userinfo.profile "_ "https://www.googleapis.com/auth/drive.metadata.readonly "_ "https://www.googleapis.com/auth/calendar.readonly" set properties("approval_prompt")="force" set properties("include_granted_scopes")="true" set url=##class(%SYS.OAuth2.Authorization).GetAuthorizationCodeEndpoint(..#OAUTH2APPNAME,scope, ..#OAUTH2CLIENTREDIRECTURI,.properties,.isAuthorized,.sc) w !,"<p><a href='"_url_"'><img border='0' alt='Google Sign In' src='images/google-signin-button.png' ></a>" &html<</body> </html>> Quit $$$OK } ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ] { #dim %response as %CSP.Response set scope="openid https://www.googleapis.com/auth/userinfo.email "_ "https://www.googleapis.com/auth/userinfo.profile "_ "https://www.googleapis.com/auth/drive.metadata.readonly "_ "https://www.googleapis.com/auth/calendar.readonly" if ##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,scope,.accessToken,.idtoken,.responseProperties,.error) { set %response.ServerSideRedirect="Web.OAUTH2.Google2N.cls" } quit 1 } } Veja abaixo uma breve explicação do código: 1.      Método OnPreHTTP: primeiro, verificamos se, por acaso, já obtivemos um token de acesso válido como resultado de uma autorização do Google. Isso pode acontecer, por exemplo, quando simplesmente atualizamos a página. Caso não tenhamos, precisamos fazer a autorização. Se já tivermos o token, apenas redirecionamos para a página que mostra os resultados 2.       Método OnPage: só chegamos a este método se não tivermos um token de acesso válido disponível. Então, precisamos iniciar a comunicação: fazer a autenticação e autorização no Google para que ele nos conceda o token de acesso. 3.       Definimos uma string de escopo e uma array de propriedades que modificam o comportamento da janela de autenticação do Google (precisamos fazer a autenticação no Google antes que ele possa nos autorizar com base em nossa identidade). 4.       Por último, recebemos o URL de uma página de login do Google e a mostramos ao usuário, seguida pela página de consentimento. Mais uma nota: Especificamos a verdadeira página de redirecionamento em no parâmetro OAUTH2CLIENTREDIRECTURI. Entretanto, usamos a página de sistema do framework OAUTH da InterSystems IRIS na definição das credenciais do Google! O redirecionamento é tratado internamente por nossa classe manipuladora OAUTH. ### **Página 2** Esta página mostra os resultados da autorização do Google e, em caso de êxito, fazemos chamadas à API do Google para obter os dados. Novamente, o código abaixo é minimalista, mas completamente funcional. Deixamos a exibição dos dados recebidos de uma maneira mais estruturada para a imaginação dos leitores. Include %occInclude Class Web.OAUTH2.Google2N Extends %CSP.Page { Parameter OAUTH2APPNAME = "Google"; Parameter OAUTH2ROOT = "https://www.googleapis.com"; ClassMethod OnPage() As %Status { &html<<html> <head> </head> <body>> // Check if we have an access token set scope="openid https://www.googleapis.com/auth/userinfo.email "_ "https://www.googleapis.com/auth/userinfo.profile "_ "https://www.googleapis.com/auth/drive.metadata.readonly "_ "https://www.googleapis.com/auth/calendar.readonly" set isAuthorized=##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,scope,.accessToken,.idtoken,.responseProperties,.error) if isAuthorized { // Google has no introspection endpoint - nothing to call - the introspection endpoint and display result -- see RFC 7662. w "<h3>Data from <span style='color:red;'>GetUserInfo API</span></h3>" // userinfo has special API, but could be also retrieved by just calling Get() method with appropriate url try { set tHttpRequest=##class(%Net.HttpRequest).%New() $$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).AddAccessToken(tHttpRequest,"query","GOOGLE",..#OAUTH2APPNAME)) $$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).GetUserinfo(..#OAUTH2APPNAME,accessToken,,.jsonObject)) w jsonObject.%ToJSON() } catch (e) { w "<h3><span style='color: red;'>ERROR: ",$zcvt(e.DisplayString(),"O","HTML")_"</span></h3>" } /****************************************** * * * Retrieve info from other APIs * * * ******************************************/ w "<hr>" do ..RetrieveAPIInfo("/drive/v3/files") do ..RetrieveAPIInfo("/calendar/v3/users/me/calendarList") } else { w "<h1>Not authorized!</h1>" } &html<</body> </html>> Quit $$$OK } ClassMethod RetrieveAPIInfo(api As %String) { w "<h3>Data from <span style='color:red;'>"_api_"</span></h3><p>" try { set tHttpRequest=##class(%Net.HttpRequest).%New() $$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).AddAccessToken(tHttpRequest,"query","GOOGLE",..#OAUTH2APPNAME)) $$$THROWONERROR(sc,tHttpRequest.Get(..#OAUTH2ROOT_api)) set tHttpResponse=tHttpRequest.HttpResponse s tJSONString=tHttpResponse.Data.Read() if $e(tJSONString)'="{" { // not a JSON d tHttpResponse.OutputToDevice() } else { w tJSONString w "<hr/>" /* // new JSON API &html<<table border=1 style='border-collapse: collapse'>> s tJSONObject={}.%FromJSON(tJSONString) set iterator=tJSONObject.%GetIterator() while iterator.%GetNext(.key,.value) { if $isobject(value) { set iterator1=value.%GetIterator() w "<tr><td>",key,"</td><td><table border=1 style='border-collapse: collapse'>" while iterator1.%GetNext(.key1,.value1) { if $isobject(value1) { set iterator2=value1.%GetIterator() w "<tr><td>",key1,"</td><td><table border=0 style='border-collapse: collapse'>" while iterator2.%GetNext(.key2,.value2) { write !, "<tr><td>",key2, "</td><td>",value2,"</td></tr>" } // this way we can go on and on into the embedded objects/arrays w "</table></td></tr>" } else { write !, "<tr><td>",key1, "</td><td>",value1,"</td></tr>" } } w "</table></td></tr>" } else { write !, "<tr><td>",key, "</td><td>",value,"</td></tr>" } } &html<</table><hr/> > */ } } catch (e) { w "<h3><span style='color: red;'>ERROR: ",$zcvt(e.DisplayString(),"O","HTML")_"</span></h3>" } } }     Vamos dar uma olhada no código: 1.       Antes de tudo, precisamos verificar se temos um token de acesso válido (para verificarmos se fomos autorizados) 2.       Caso afirmativo, podemos enviar solicitações às APIs oferecidas pelo Google usando o token de acesso emitido 3.       Para isso, usamos a classe padrão %Net.HttpRequest, mas adicionamos o token de acesso ao método GET ou POST de acordo com a especificação da API chamada 4.       Como é possível ver, o framework OAUTH implementou o método GetUserInfo() para sua comodidade, mas você pode obter as informações do usuário diretamente usando a especificação da API do Google da mesma maneira como feito no método auxiliar RetrieveAPIInfo() 5.       Como é comum no mundo do OAUTH trocar dados no formato JSON, apenas lemos os dados recebidos e os colocamos no navegador. Cabe ao desenvolvedor da aplicação analisar e formatar os dados recebidos para apresentá-los ao usuário de alguma forma que faça sentido. Mas isso está além do escopo desta demonstração. (Embora tenhamos colocado um código comentado que mostra como a análise pode ser feita.)  Veja abaixo uma captura de tela da saída exibindo os dados JSON não tratados. ![](/sites/default/files/inline/images/6_0.png) Prossiga para a [parte 2](https://community.intersystems.com/post/cach%C3%A9-open-authorization-framework-oauth-20-implementation-part-2), que descreve como a InterSystems IRIS atua como servidor de autorização e provedor do OpenID Connect.   [1] https://tools.ietf.org/html/rfc6749, https://tools.ietf.org/html/rfc6750
Anúncio
Angelo Bruno Braga · Nov. 9, 2020

Webinar InterSystems Brasil - "Solução para Monitoramento e Auditoria de Integrações" com a parceira Confluence Informática

Junte-se à nós para mais um Webcast da InterSystems Brasil, desta vez em parceria com a Confluence Informática com o tema "Solução para Monitoramento e Auditoria de Integrações", que será realizado no dia 12 de novembro às 11h (Horário de Brasília). Inscreva-se, as vagas são limitadas
Artigo
Vinicius Maranhao Ribeiro de Castro · Dez. 21, 2020

Protegendo suas APIs com OAuth 2.0 no InterSystems API Management – Parte 2

Nesta série de artigos de três partes, é mostrado como você pode usar o IAM para simplesmente adicionar segurança, de acordo com os padrões do OAuth 2.0, a um serviço não autenticado anteriormente implantado no IRIS. Na [primeira parte](https://pt.community.intersystems.com/post/protegendo-suas-apis-com-oauth-20-no-intersystems-api-management-parte-1), foram fornecidos alguns conhecimentos sobre o OAuth 2.0, juntamente com algumas definições e configurações iniciais do IRIS e IAM, para facilitar a compreensão de todo o processo de proteção dos seus serviços. Esta parte, agora, discutirá e mostrará em detalhes as etapas necessárias para configurar o IAM para validar o token de acesso presente na solicitação de entrada e encaminhar a solicitação para o back-end se a validação for bem-sucedida. A [última parte](https://pt.community.intersystems.com/post/protegendo-suas-apis-com-oauth-20-no-intersystems-api-management-parte-3) desta série discutirá e demonstrará as configurações necessárias para o IAM gerar um token de acesso (atuando como um servidor de autorização) e validá-lo, junto com algumas considerações finais importantes. Se você quiser testar o IAM, entre em contato com seu representante de vendas InterSystems. Cenário 1: IAM como um validador de token de acesso Neste cenário, será usado um servidor de autorização externo que gera um token de acesso em formato JWT (JSON Web Token). Este JWT é assinado usando o algoritmo RS256 junto com uma chave privada. Para verificar a assinatura do JWT, a outra parte (neste caso, o IAM) precisa ter a chave pública, fornecida pelo servidor de autorização. Este JWT gerado pelo servidor de autorização externo também inclui, em seu corpo, uma declaração chamada “exp” contendo o carimbo de data/hora (timestamp) de quando esse token expirará, e outra declaração chamada “iss” contendo o endereço do servidor de autorização. Portanto, o IAM precisa verificar a assinatura do JWT com a chave pública do servidor de autorização e o carimbo de data/hora de expiração contido na declaração "exp" dentro do JWT antes de encaminhar a solicitação ao IRIS. Para configurar isso no IAM, vamos começar adicionando um plugin chamado “JWT” ao nosso “SampleIRISService” no IAM. Para isso, acesse a página Services do IAM e copie o id do “SampleIRISService”, que usaremos posteriormente. Depois disso, vá em Plugins, clique no botão “New Plugin”, localize o plugin “JWT” e clique em Enable. Na página seguinte, cole o id do “SampleIRISService” no campo “service\_id” e selecione a caixa “exp” no parâmetro “config.claims\_to_verify”. Observe que o valor do parâmetro “config.key\_claim\_name” é “iss”. Vamos usar isso mais tarde. Em seguida, clique no botão “Create”. Feito isso, vá até a seção “Consumers” no menu à esquerda e clique em nosso “ClientApp” criado anteriormente. Acesse a aba “Credentials” e clique no botão “New JWT Credential”. Na página seguinte, selecione o algoritmo usado para assinar o JWT (neste caso RS256) e cole a chave pública no campo “rsa\_public\_key” (esta é a chave pública fornecida a você pelo servidor de autorização em formato PEM). No campo “key”, você precisa inserir o conteúdo da declaração JWT que você inseriu no campo “config.key\_claim\_name” ao adicionar o plugin JWT. Portanto, neste caso, preciso inserir o conteúdo da declaração iss do meu JWT, que, no meu caso, é o endereço do servidor de autorização. Em seguida, clique no botão “Create”. Dica: para fins de depuração, existe uma ferramenta on-line de decodificação de JWT que você pode usar para verificar as declarações e seus valores e verificar a assinatura colando a chave pública. Aqui está o link desta ferramenta on-line: https://jwt.io/#debugger Agora, com o plugin JWT adicionado, não é mais possível enviar a solicitação sem uma autenticação. Como você pode ver abaixo, em uma simples solicitação GET, sem autenticação, para a URL **http://iamhost:8000/event/1** retorna uma mensagem não autorizada juntamente com o código de status “401 Não autorizado”. Para obter os resultados do IRIS, precisamos adicionar o JWT à solicitação. Portanto, primeiro precisamos solicitar o JWT ao servidor de autorização. O servidor de autorização personalizado que estamos usando aqui retorna um JWT se uma solicitação POST for feita junto com alguns pares de valores-chave no corpo, incluindo informações de usuário e cliente, para a seguinte URL: **https://authorizationserver:5001/auth** Isto é como se parece essa solicitação e a sua resposta: Em seguida, você pode adicionar o JWT obtido na resposta abaixo no cabeçalho de autorização como um Bearer Token e enviar uma solicitação GET para a mesma URL usada anteriormente: **http://iamhost:8000/event/1** Ou você também pode adicioná-lo como um parâmetro de querystring, com a chave de querystring sendo o valor especificado no campo “config.uri\_param\_names” ao adicionar o plugin JWT que, neste caso, é “jwt”: Finalmente, existe também a opção de incluir JWT na solicitação como um cookie, se algum nome for inserido no campo “config.cookie_names”. Continue lendo até a terceira e última parte desta série para entender as configurações necessárias para o IAM gerar um token de acesso e validá-lo, junto com algumas considerações finais importantes.
Anúncio
Benjamin De Boe · Abr. 8, 2021

Versão 2020.4 do InterSystems IRIS e IRIS for Health já se encontram disponíveis

A versão 2020.4 do InterSystems IRIS, IRIS for Health e IRIS Studio já se encontram disponíveis para uso geral. A plataforma de dados InterSystems IRIS 2020.4 torna inda mais fácil desenvolver, implantar e gerenciar akes it even easier to develop, deploy and manage aplicações de ponta e processos de negócio que unem dados e silos de aplicações. Ela possui várias novas funcionalidades, incluindo: Melhorias para desenvolvedores de aplicações e interfaces, incluindo: Suporte ao Java SE 11 LTS, tanto usando o Oracle OpenJDK quanto o AdoptOpenJDK Suporte a Pooling de Conexão para JDBC Uma nova ação "foreach" nas regras de roteamento para documentos virtuais segmentados Melhorias para administradores de bases de dados e sistemas, incluindo: O ICM agora suporta a implantação do SAM (System Alerting and Monitoring) e do IAM (InterSystems API Manager) Extensões para nossa sintaxe SQL para tarefas comuns de administração Implantação simplificada do InterSystems Reports O InterSystems IRIS for Health 2020.4 contém todas as melhorias acima do InterSystems IRIS 2020.4 e, ainda: Suporte Aprimorado ao FHIR, incluindo suporte a perfís FHIR. Suporte ao perfil IHE RMD. Suporte ao DataGate nas Ferramentas de Migração HL7 Maiores detalhes sobre estas funcionalidades podem ser encontradas na documentação do produto: Documentação e notas da versão para o InterSystems IRIS 2020.4 Documentação e notas da versão para o InterSystems IRIS for Health 2020.4 Como esta é uma versão CD (Continuous Delivery), está disponível apenas como OCI (Open Container Initiative) também conhecido como formato em contêiner Docker. As imagens de contêiners são disponibilizadas para mecanismos de tempo de execução compatíveis com OCI para as plataformas Linux x86-64 e Linux ARM64, conforme detalhado em documento de Plataformas Suportadas. As imagens de contêineres para a Edição Enterprise e todos os componentes correspondentes estão disponíveis a partir do InterSystems Container Registry utilizando os seguintes comandos: docker pull containers.intersystems.com/intersystems/iris:2020.4.0.547.0 docker pull containers.intersystems.com/intersystems/irishealth:2020.4.0.547.0 Para uma lista completa das imagens disponíveis, verifiquem por favor a documentação do ICR (InterSystems Container Registry). Imagens de contêineres para a Edição Edição Community também podem ser obtidas a partir do Docker store através do uso dos seguintes comandos: docker pull store/intersystems/iris-community:2020.4.0.547.0 docker pull store/intersystems/iris-community-arm64:2020.4.0.547.0 docker pull store/intersystems/irishealth-community:2020.4.0.547.0 docker pull store/intersystems/irishealth-community-arm64:2020.4.0.547.0 De forma alternativa, versões tarball de todas as imagens de todos os contêineres são disponibilizadas através da página de download de versões CD do WRC. Nossas listagens correspondentes nos principais marketplaces na nuvem serão atualizadas nos próximos dias. InterSystems IRIS Studio 2020.4 é um ambiente de desenvolvimento integrado (IDE) para utilização no Windows da Microsoft e pode ser baixado através da página de download de componentes do WRC. Ele funciona com a versão 2020.4 e versões anteriores do InterSystems IRIS e IRIS for Health. A InterSystems também suporta o plugin de VSCode para ObjectScript para desenvolvimento de aplicações para o InterSystems IRIS utilizando-se o Visual Studio Code, que está disponível para Microsoft Windows, Linux and MacOS. Outros componentes da plataforma InterSystems IRIS 2020.4, como o driver ODBC e o Gateway Web também estão disponíveis na página de download de componentes do WRC.
Anúncio
Angelo Bruno Braga · Maio 20, 2021

Ganhe seu acesso GRÁTIS ao Serviço Acelerador FHIR InterSystems IRIS (FHIRaaS) na AWS!

Olá Desenvolvedores, O período de registro para o Concurso de Programação Acelerador FHIR da InterSystems está em pleno andamento! Nós convidamos todos os desenvolvedores FHIR para criar uma aplicação nova ou testar aplicações existentes utilizando o InterSystems IRIS FHIR Accelerator Service (FHIRaaS) on AWS. E agora você tem uma grande oportunidade para ganhar um acesso GRÁTIS ao FHIRaaS na AWS! Então, para dar o primeiro passo para dominar o FHIRaaS, você precisa se registrar em nosso Portal FHIR Portal utilizando este link: 👉🏼 https://portal.trial.isccloud.io/account/signup Clique no link acima para se tornar um mestre do FHIRaaS com a InterSystems! ✌🏼 Fiquem a vontade para colocarem suas dúvidas sobre a competição aqui ou no canal discord-concursos. Boa codificaçãoi!
Artigo
Fernando Ferreira · Mar. 3, 2022

Continuação - Migrando para InterSystems IRIS – Parte 02 – (Trocando de sistema operacional e de hardware).

Continuação:Migrando para InterSystems IRIS – Parte 02 – Trocando de sistema operacional e de hardware. Olá, comunidade! Nesta continuação da segunda parte do artigo vamos apresentar dicas do processo de migração do InterSystems Caché e ou Ensemble para IRIS com um desafio um pouco maior, pois agora vamos trocar de máquina e sistema operacional. Como comentado na 1ª parte do artigo, a ideia é passar dicas e não substituir os documentos oficiais que estão disponíveis no WRC, que são eles: InterSystems IRIS Adoption Guide; How to migrate to InterSystems IRIS. Cenário atual: O ambiente está rodando em uma máquina que não possui mais garantia do fabricante e o sistema operacional atual é o um RedHat 6 com uma instância de Ensemble 2018.1.5. O desafio é migrar para InterSystems IRIS 2021.1 para um novo hardware com o RedHat 8. Como parte do processo de migração, você já verificou os pré-requisitos das plataformas suportadas para a plataforma InterSystems IRIS, de qualquer forma vou deixar o link aqui para que você possa consultar novamente: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ISP_technologies#ISP_platforms_server Sistema operacional: Ensemble: A aplicação que roda nesta instância possui um único namespace com dois bancos de dados, sendo: Database para globais; Database para rotinas. Aqui vai a primeira dica, é recomendado que a base das suas rotinas e globais sejam segregadas. Para ambientes onde rotinas e globais convivem no mesmo banco de dados é demando procedimentos adicionais que serão tratados nos próximos artigos. Uma observação (sempre vale a pena lembrar) para o cenário atual, a migração aqui apresentada é válida para as plataformas InterSystems Caché e Ensemble, o que difere nos procedimentos é que para Ensemble possuem as etapas da Produção, e todas as dicas aqui mencionadas são baseadas na documentação oficial da InterSystems que vocês podem fazer o download no WRC. Instalação corrente do Ensemble: Namespace com bancos segregados: Estrutura no SO: Dados: Rotinas: Agora que já conhecemos o cenário atual, vamos para primeira etapa do processo de migração: BACKUP / BACKUP / BACKUP / BACKUP / BACKUP / BACKUP / BACKUP / BACKUP / BACKUP E realizar o procedimento em: AMBIENTE DE TESTE / AMBIENTE DE TESTE / AMBIENTE DE TESTE / AMBIENTE DE TESTE Pronto backup realizado, vamos para a etapa seguinte: Vamos desligar a produção: Uma dica importante: caso você possua mais de uma produção, lembre-se que você pode para todas as produções via terminal: Agora vamos parar o Ensemble ou Caché com segurança: Lembre-se de passar o nome da instância, e no nosso exemplo a instância se chama: PRODENSEMBLE Importante verificar o ccconsole.log se não ocorreu nenhum problema durante o shutdown: Antes de continuar os próximos passos, vamos aqui para algumas dicas, mediante questionamentos que já obtivemos de alguns clientes. Um dos principais questionamentos: “Preciso mesmo fazer uma parada total do ambiente para copiar os dados para o novo servidor? Não possa executar o utilitário de backup do InterSystems Caché e ou Ensemble?” Tenho duas respostas para esse questionamento: Neste caso depende de como sua aplicação está escrita, pois não se faz necessário para o ambiente todo, e sim o banco que será copiado, ou seja, o banco que será copiado precisa estar desmontado. Não é possível utilizar o procedimento de backup no InterSystems Caché e ou Ensemble e restaurar no InterSystems IRIS, se faz a necessidade uma cópia fria do banco. Neste caso vamos exemplificar o banco desmontado: Agora que executamos a parada total do ambiente ou o banco está desmontado, se faz necessário copiar o CACHE.dat para o novo servidor. Novo ambiente: Temos como premissa que a nova instância do InterSystems IRIS já se encontra instalado na nova máquina. Caso tenha alguma dúvida no procedimento de instalação do IRIS, você pode consultar nossa documentação no seguinte link: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCI Vamos confirmar alguns dados do novo ambiente: Sistema operacional: Instalação do IRIS: Aqui você pode perceber algumas diferenças: Nome da nova instância: PRODIRIS Diretório de instalação: /opt/iris Portas defaults (Webserver): (SuperServer port = 1972, WebServer = 52773) Vamos verificar a instalação da nova instância agora: É possível observar que só existem os namespaces defaults da instalação. Para banco de dados a mesma situação, somente os bancos defaults da nova instalação. Agora que já verificamos que o ambiente o novo ambiente está operacional, vamos para as etapas de trazer os dados e as aplicações do ambiente anterior: Como primeira etapa da migração dos dados, precisamos relembrar uma dica da primeira parte do artigo: verificar a tabela de Endiannes. Se ainda possui alguma dúvida passa lá na primeira parte do artigo: https://pt.community.intersystems.com/post/migrando-para-o-intersystems-iris-parte-1 Agora precisamos renomear o nome dos bancos, com é citado no guia: InterSystems IRIS Adoption Guide, existe um capítulo com o nome: Different Names. Onde é possível ver com detalhes as diferenças de nomes do ambiente InterSystems Caché e ou Ensemble para o Intersystems IRIS, com exemplo: Vamos verificar a estrutura dos arquivos pós a cópia: Agora com os nomes renomeados: Com os nomes renomeados vamos criar o banco de dados dentro do Portal: Quando selecionado o caminho com o banco de dados copiado, o IRIS identificará que o banco já existe. Com os bancos de dados criados, agora é possível criar o namespace apontando para os bancos: Com os bancos criados e namespace criados, antes de ir para o próximo passo, fica como dica verificar a integridade do banco de dados. Após a execução verifique o Log de integridade: Nesta etapa para o cenário que existam páginas CSP, elas precisam ser copiadas também para a nova estrutura e criar o aplicativo no portal: Com tudo copiado, vamos compilar as Rotinas, Classes e CSP, mesmo procedimento executado na sessão deste artigo: https://pt.community.intersystems.com/node/511436 Com tudo compilado, podemos verificar os dados via SQL ou Globais Agora é testar a aplicação e a produção: Obrigado por acompanhar este artigo e até a próxima parte que o tema será: Migrando uma instância com Mirror/Shadow de Caché/Ensemble para IRIS
Anúncio
Rochael Ribeiro · Mar. 7, 2022

Novas versões de manutenção para o Caché, Ensemble e InterSystems IRIS estão agora disponíveis

Três novos conjuntos de lançamentos de manutenção estão agora disponíveis:: Caché 2018.1.6, Ensemble 2018.1.6 e HSAP 2018.1.6 InterSystems IRIS 2020.1.2, IRIS for Health 2020.1.2 e HealthShare Health Connect 2020.1.2 InterSystems IRIS 2021.1.1, IRIS for Health 2021.1.1 e HealthShare Health Connect 2021.1.1 Os kits de instalação e contêineres podem ser baixados do site de Distribuição de Soluções do WRC. As imagens de contêineres para as Edições Enterprise do InterSystems IRIS e do IRIS for Health, assim como todos os componentes correspondentes estão disponíveis a partir do InterSystems Container Registry. Estas são versões de manutenção com várias atualizações em várias partes dos produtos. Para informações sobre as correções contidas nestas versões, verifique a documentação da versão, que inclui as Notas da Versão, o Checklist para Atualização, uma lista de Alterações da Versão, assim como a Referência de Classes e um conjunto completo de guias , referências, tutoriais e artigos. Toda a documentação pode ser acessada através de docs.intersystems.com. Os identificadores das versões estão na tabela abaixo: Versão Produto Identificador 2018.1.6 Caché e Ensemble 2018.1.6.717.0 2018.1.6 Avaliação do Caché 2018.1.6.717.0su 2018.1.6 HealthShare Health Connect (HSAP) 2018.1.6HS.9063.0 2020.1.2 InterSystems IRIS 2020.1.2.517.0 2020.1.2 IRIS for Health 2020.1.2.517.0 2020.1.2 HealthShare Health Connect 2020.1.2.517.0 2020.1.2 IRIS Studio 2021.1.2.517.0 2021.1.1 InterSystems IRIS 2021.1.1.324.0 2021.1.1 IRIS for Health 2021.1.1.324.0 2021.1.1 HealthShare Health Connect 2021.1.1.324.0 2021.1.1 IRIS Studio 2021.1.1.324.0 As imagens de contêineres do InterSystems IRIS e IRIS for Health, assim como todos os componentes correspondentes estão disponíveis a partir do InterSystems Container Registry utilizando os seguintes comandos para a versão 2020.1.2: docker pull containers.intersystems.com/intersystems/iris:2020.1.2.517.0 docker pull containers.intersystems.com/intersystems/irishealth:2020.1.2.517.0 docker pull containers.intersystems.com/intersystems/iris-arm64:2020.1.2.517.0 docker pull containers.intersystems.com/intersystems/irishealth-arm64:2020.1.2.517.0 Para imagens dos contêineres para a versão 2021.1.1: docker pull containers.intersystems.com/intersystems/iris:2021.1.1.324.0 docker pull containers.intersystems.com/intersystems/irishealth:2021.1.1.324.0 docker pull containers.intersystems.com/intersystems/iris-arm64:2021.1.1.324.0 docker pull containers.intersystems.com/intersystems/irishealth-arm64:2021.1.1.324.0 Para uma lista completa das imagens disponíveis verifique a documentação do ICR.
Anúncio
Angelo Bruno Braga · Jul. 5, 2021

Bem vindos ao Programa de Acesso Antecipado InterSystems: Webinar Especial de Lançamento do Python Incorporado!

Olá Desenvolvedores, Temos ótimas novidades para vocês : 💥 Participantes do Concurso de Inteligência Artificial InterSystems podem utilizar Python Incorporado em suas soluções! Ou seja, se você ainda não é membro do Programa de Acesso Antecipado ao Python Incorporado InterSystems (EAP), agora é a hora! Solicite a adesão em python-interest@intersystems.com e você ganhará acesso GRÁTIS às funcionalidades do Python Incorporado da plataforma de dados InterSystems IRIS. Além disso, nós convidamos todos os participantes do Programa de Acesso Antecipado para o Webinar Especial de Lançamento do Python Incorporado que irá ocorrer amanhã, dia 6 de Julho às 11:00 horário de brasília – uma forma fácil de começar a entender como utilizar o Python Incorporado! Também serão apresentados no webinar: Uma demonstração das novas funcionalidades da plataforma de dados, aplicações de exemplo e, é claro, as recompensas. Depois de se tornar um membro do Programa de Acesso Antecipado (EAP), você irá receber um link especial para se juntar ao webinar de lançamento: ➡️ RSVP: python-interest@intersystems.com Então, Agora qualquer desenvolvedor Python pode facilmente se juntar ao Concurso de Inteligência Artificial InterSystems em andamento ! Duração: de 28 de Junho a 28 de Julho de 2021 Premiação Total: US$8.750 ,00 Não perca esta oportunidade!
Anúncio
Angelo Bruno Braga · Out. 13, 2022

[Vídeo] InterSystems Clinical Viewer & Aplicação de Navegação Clínica: Novidades & O que vem por aí 2022

Olá Comunidade, Neste vídeo, você aprenderá sobre os novos recursos do InterSystems Healthshare Clinical Viewer e o que está por vir: ⏯ Clinical Viewer & Aplicação de Navegação Clínica: Novidades & O que vem por aí@ Global Summit 2022 🗣 Apresentador: @Julie.Smith, Gerente de Produtos Clinico, InterSystems Fique ligado para mais vídeos no canal de Desenvolverdores InterSystems no YouTube!
Artigo
Danusa Calixto · Abr. 3, 2023

Entrega contínua de sua solução InterSystems usando GitLab – Parte IX: Arquitetura do contêiner

[Nesta série de artigos](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-índice), quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como: * Git básico * Fluxo Git (processo de desenvolvimento) * Instalação do GitLab * Fluxo de trabalho do GitLab * Entrega contínua * Instalação e configuração do GitLab * CI/CD do GitLab * Por que contêineres? * Infraestrutura dos contêineres * CD usando contêineres * CD usando ICM * **Arquitetura do contêiner** Neste artigo, falaríamos sobre como criar e implantar seu próprio contêiner. ## ## %SYS durável Como os contêineres são bastante efêmeros, eles não devem armazenar nenhum dado do aplicativo. O recurso [%SYS Durável](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ADOCK#ADOCK_iris_durable) permite exatamente isso — armazenar configurações, definições, dados %SYS, etc. em um volume de host, especificamente: * O arquivo iris.cpf. * O diretório /csp, contendo a configuração do web gateway e os arquivos do log. * O arquivo /httpd/httpd.conf, o arquivo de configuração do servidor Web privado da instância. * O diretório /mgr, contendo o seguinte: * O banco de dados do sistema IRISSYS, composta pelos arquivos IRIS.DAT e iris.lck e diretório de stream, e iristemp, irisaudit, iris e os diretórios do usuário, com os bancos de dados do sistema IRISTEMP, IRISAUDIT, IRIS e USER. * O arquivo do registro de log de imagem de gravação, IRIS.WIJ. * O diretório /journal com os arquivos do registro de log. * O diretório /temp para arquivos temporários. * Arquivos de registro, incluindo messages.log, journal.log e SystemMonitor.log. ## Arquitetura do contêiner Por outro lado, precisamos armazenar o código do aplicativo dentro do nosso contêiner para atualizá-lo quando necessário. Tudo isso nos leva a esta arquitetura: ![](/sites/default/files/inline/images/snimok_51.png) Para fazer isso durante o tempo de compilação, precisamos, no mínimo, criar um banco de dados adicional (para armazenar o código do aplicativo) e mapeá-lo no namespace do aplicativo. No meu exemplo, eu usaria o namespace USER para manter os dados do aplicativo, como ele já existe e é durável. ## Instalador Com base no descrito acima, nosso [instalador](https://community.intersystems.com/post/deploying-applications-intersystems-cache-installer) precisa: * Criar o namespace/banco de dados APP * Carregar o código no namespace APP * Mapear as classes do aplicativo para o namespace USER * Fazer todas as outras instalações (nesse caso, criei o web app CSP e o app REST) Class MyApp.Hooks.Local { Parameter Namespace = "APP"; /// See generated code in zsetup+1^MyApp.Hooks.Local.1 XData Install [ XMLNamespace = INSTALLER ] { <Manifest> <Log Text="Creating namespace ${Namespace}" Level="0"/> <Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Ensemble="" Data="IRISTEMP"> <Configuration> <Database Name="${Namespace}" Dir="/usr/irissys/mgr/${Namespace}" Create="yes" MountRequired="true" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true"/> </Configuration> <Import File="${Dir}Form" Recurse="1" Flags="cdk" IgnoreErrors="1" /> </Namespace> <Log Text="End Creating namespace ${Namespace}" Level="0"/> <Log Text="Mapping to USER" Level="0"/> <Namespace Name="USER" Create="no" Code="USER" Data="USER" Ensemble="0"> <Configuration> <Log Text="Mapping Form package to USER namespace" Level="0"/> <ClassMapping From="${Namespace}" Package="Form"/> <RoutineMapping From="${Namespace}" Routines="Form" /> </Configuration> <CSPApplication Url="/" Directory="${Dir}client" AuthenticationMethods="64" IsNamespaceDefault="false" Grant="%ALL" Recurse="1" /> </Namespace> </Manifest> } /// This is a method generator whose code is generated by XGL. /// Main setup method /// set vars("Namespace")="TEMP3" /// do ##class(MyApp.Hooks.Global).setup(.vars) ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer) As %Status [ CodeMode = objectgenerator, Internal ] { Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install") } /// Entry point ClassMethod onAfter() As %Status { try { write "START INSTALLER",! set vars("Namespace") = ..#Namespace set vars("Dir") = ..getDir() set sc = ..setup(.vars) write !,$System.Status.GetErrorText(sc),! set sc = ..createWebApp() } catch ex { set sc = ex.AsStatus() write !,$System.Status.GetErrorText(sc),! } quit sc } /// Modify web app REST ClassMethod createWebApp(appName As %String = "/forms") As %Status { set:$e(appName)'="/" appName = "/" _ appName #dim sc As %Status = $$$OK new $namespace set $namespace = "%SYS" if '##class(Security.Applications).Exists(appName) { set props("AutheEnabled") = $$$AutheUnauthenticated set props("NameSpace") = "USER" set props("IsNameSpaceDefault") = $$$NO set props("DispatchClass") = "Form.REST.Main" set props("MatchRoles")=":" _ $$$AllRoleName set sc = ##class(Security.Applications).Create(appName, .props) } quit sc } ClassMethod getDir() [ CodeMode = expression ] { ##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR")) } } Para criar o banco de dados não durável, usei um subdiretório de **/usr/irissys/mgr**, que não é persistente. Observe que a chamada para ##class(%File).ManagerDirectory() retorna um caminho para o diretório durável, e não para o diretório do contêiner interno. ##   ## Configuração da entrega contínua [Confira a parte VII](https://community.intersystems.com/post/continuous-delivery-your-intersystems-solution-using-gitlab-part-vii-cd-using-containers) para ver as informações completas, mas tudo o que você precisa fazer é adicionar estas duas linhas (em negrito) à configuração existente. run image: stage: run environment: name: $CI_COMMIT_REF_NAME url: http://$CI_COMMIT_REF_SLUG.docker.eduard.win/index.html tags: - test script: - docker run -d --expose 52773 --volume /InterSystems/durable/$CI_COMMIT_REF_SLUG:/data --env ISC_DATA_DIRECTORY=/data/sys --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win --name iris-$CI_COMMIT_REF_NAME docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log O argumento do volume monta o diretório do host para o contêiner e a variável **ISC\_DATA\_DIRECTORY** mostra ao InterSystems IRIS qual diretório usar. Para citar a documentação: > * Ao executar um contêiner InterSystems IRIS usando essas opções, ocorre o seguinte: > * O volume externo especificado é montado. > * Se o diretório %SYS durável especificado pela variável de ambiente ISC_DATA_DIRECTORY, iconfig/ no exemplo anterior, já existe e contém os dados %SYS duráveis, todos os ponteiros internos da instância são redefinidos para esse diretório e a instância usa os dados que contém. > * Se o diretório %SYS durável especificado na variável de ambiente ISC_DATA_DIRECTORY já existir, mas não conter os dados %SYS duráveis, nenhum dado é copiado e a instância é executada usando os dados na árvore de instalação dentro do contêiner, ou seja, os dados específicos da instância não são persistentes. Por esse motivo, é recomendável incluir nos scripts uma verificação para essa condição antes de executar o contêiner. > * Se o diretório %SYS durável especificado por ISC_DATA_DIRECTORY não existir: > * É criado o diretório %SYS durável. > * Os diretórios e arquivos listados no conteúdo do Diretório %SYS Durável são copiados dos locais instalados para o diretório %SYS durável (os originais permanecem no local). > * Todos os ponteiros internos da instância são redefinidos para o diretório %SYS durável e a instância usa os dados que contém. ##   ## Atualizações Quando o aplicativo evoluir e uma nova versão (contêiner) for lançada, às vezes é necessário executar algum código. Pode ser antes ou depois dos hooks de compilação, das migrações do esquema e dos testes de unidade, mas é necessário executar código arbitrário. Por isso, você precisa de um framework que gerencie seu aplicativo. [Em artigos anteriores](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-índice), descrevi a estrutura básica desse framework, mas, é claro, ele pode ser consideravelmente ampliado para atender a requisitos específicos do aplicativo. Conclusão A criação de um aplicativo em contêiner requer algumas considerações, mas o InterSystems IRIS oferece vários recursos para facilitar esse processo. Links * [Índice](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-índice) * [Código do artigo](https://github.com/intersystems-ru/GitLab/tree/master/docker) * [Projeto de teste](http://gitlab.eduard.win/test/docker) * [Configuração de CD completa](https://github.com/intersystems-ru/GitLab/blob/master/docker/.gitlab-ci.yml) * [Configuração de CD completa com %SYS durável](http://gitlab.eduard.win/test/docker/blob/master/.gitlab-ci.yml)
Artigo
Danusa Calixto · Fev. 23, 2023

Entrega contínua de sua solução InterSystems usando GitLab – Parte VI: Infraestrutura dos contêineres

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como: * Git básico * Fluxo Git (processo de desenvolvimento) * Instalação do GitLab * Fluxo de trabalho do GitLab * Entrega contínua * Instalação e configuração do GitLab * CI/CD do GitLab * Por que contêineres? * **Infraestrutura dos contêineres** * CI/CD do GitLab usando contêineres No [primeiro artigo](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-parte-i-git), abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software. No [segundo artigo](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-parte-ii-fluxo-de-trabalho-do), abordamos o fluxo de trabalho do GitLab: um processo inteiro do ciclo de vida do software e a entrega contínua. No [terceiro artigo](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-parte-iii-instalação-e), abordamos a instalação e configuração do GitLab e a conexão dos seus ambientes a ele No [quarto artigo](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-parte-iv-configuração-da-cd), escrevemos uma configuração de CD. No [quinto artigo](https://pt.community.intersystems.com/post/entrega-contínua-de-sua-solução-intersystems-usando-gitlab-–-parte-v-por-que-contêineres), falamos sobre contêineres e como (e por que) eles podem ser usados. Neste artigo, vamos discutir os principais componentes necessários para executar um pipeline de entrega contínua com contêineres e como eles trabalham juntos. A configuração deve ser assim: ![](/sites/default/files/inline/images/4fa92c35-5a00-4e7a-929e-e5ae4b99701a-1.jpg.png) Aqui podemos ver a separação de três etapas principais: * Criação * Envio * Execução ### Criação Nas partes anteriores, a criação era frequentemente incremental — calculamos a diferença entre o ambiente e a codebase atuais e modificamos nosso ambiente para corresponder à codebase. Com contêineres, cada build é completo. O resultado de um build é uma imagem que pode ser executada em qualquer lugar com dependências. ### Envio Depois que nossa imagem é criada e aprovada nos testes, ela é carregada no registro — servidor especializado para hospedar imagens docker. Então, é possível substituir a imagem anterior pela mesma tag. Por exemplo, devido ao novo commit para o master branch, nós construímos a nova imagem (project/version:master) e, se os testes funcionarem, podemos substituir a imagem no registro pela nova com a mesma tag, então todos que extraírem project/version:master obtêm uma nova versão. ### Execução Por fim, nossas imagens são implantadas. Uma solução de CI, como o GitLab, pode controlar isso ou um orquestrador especializado, mas o ponto é o mesmo: algumas imagens são executadas, verificadas periodicamente quanto à integridade e atualizadas se uma nova versão estiver disponível. Confira o [webinar docker](https://blog.docker.com/2018/02/ci-cd-with-docker-ee/) explicando esses diferentes estágios. Como alternativa, do ponto de vista do commit: ![](/sites/default/files/inline/images/asset-3.png) Na nossa configuração de entrega: * Enviamos código para o repositório do GitLab * Criamos a imagem docker * Testamos * Publicamos a imagem no nosso registro docker * Trocamos o contêiner antigo pela nova versão do registro Para fazer isso, precisamos do seguinte: * Docker * Registro docker * Domínio registrado (opcional, mas recomendado) * Ferramentas de GUI (opcional) ##   ## Docker Primeiro de tudo, precisamos executar o docker em algum lugar. Recomendo começar com um servidor mais convencional tipo o Linux, como Ubuntu, RHEL ou Suse. Não use distribuições voltadas para a nuvem, como CoreOS, RancherOS etc. — elas não são destinadas a iniciantes. Não se esqueça de trocar o [driver de armazenamento para devicemapper](http://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GICM_containers_install).  Em caso de grandes implantações, usar ferramentas de orquestração de contêineres, como Kubernetes, Rancher ou Swarm, pode automatizar a maioria das tarefas, mas não vamos discuti-las (pelo menos nesta parte). ##   ## Registro docker Esse é o primeiro contêiner que precisamos executar e é um aplicativo do lado do servidor escalável e sem estado que armazena e permite distribuir imagens Docker. Use o registro se quiser: *  controlar rigidamente onde as imagens estão sendo armazenadas *  possuir totalmente o pipeline de distribuição das imagens *  integrar o armazenamento e a distribuição de imagens firmemente no seu fluxo de trabalho de desenvolvimento interno Veja a [documentação](https://docs.docker.com/registry/) do registro. ### Conexão do registro e do GitLab > Observação: o GitLab inclui registro integrado. Você pode executá-lo em vez do registro externo. Leia os documentos do GitLab vinculados neste parágrafo. Para conectar seu registro ao GitLab, você precisará executar seu registro com [suporte HTTPS](https://docs.docker.com/registry/configuration/)  — eu uso o Let's Encrypt para obter os certificados e segui este [Gist](https://gist.github.com/PieterScheffers/63e4c2fd5553af8a35101b5e868a811e) para obter e transmitir os certificados a um contêiner. Depois de garantir a disponibilidade do registro em HTTPS (você pode verificar no navegador), siga estas [instruções sobre como conectar o registro ao GitLab](https://docs.gitlab.com/ee/administration/container_registry.html).  Essas instruções diferem com base no que você precisa e na sua instalação do GitLab. No meu caso, a configuração foi adicionar o certificado do registro e a chave (com o nome adequado e as permissões corretas) a /etc/gitlab/ssl e estas linhas a /etc/gitlab/gitlab.rb: registry_external_url 'https://docker.domain.com' gitlab_rails['registry_api_url'] = "https://docker.domain.com" Depois de [reconfigurar o GitLab](https://docs.gitlab.com/ee/administration/restart_gitlab.html), pude ver a nova guia do Registro, com informações sobre como marcar corretamente as imagens recém-criadas para que elas apareçam aqui. ![](/sites/default/files/inline/images/snimok_35.png) ##   ## Domínio Na nossa configuração de Entrega Contínua, construímos automaticamente uma imagem por branch e, se a imagem passar nos testes, ela é publicada no registro e executada automaticamente. Para que nosso aplicativo fique disponível em todos os "estados" de maneira automática, por exemplo, podemos acessar: * Vários recursos de ramificações em <featureName>.docker.domain.com * Versão de teste em master.docker.domain.com * Versão pré-produção em preprod.docker.domain.com * Versão de produção em prod.docker.domain.com Para isso, precisamos de um nome de domínio e adicionamos um [registro DNS curinga](https://en.wikipedia.org/wiki/Wildcard_DNS_record) que aponta *.docker.domain.com ao endereço IP de docker.domain.com. Outra opção seria usar portas diferentes. ### Proxy Nginx Como temos várias ramificações de recursos, precisamos redirecionar os subdomínios automaticamente para o contêiner correto. Para fazer isso, podemos usar o Nginx como proxy reverso. Veja aqui um [guia](https://cloud.google.com/community/tutorials/nginx-reverse-proxy-docker). ## Ferramentas de GUI Para começar a trabalhar com contêineres, você pode usar a linha de comando ou uma das interfaces GUI. Há várias disponíveis, por exemplo: * Rancher * MicroBadger * Portainer * Simple Docker UI * [...](https://www.google.com/search?q=gui+container+managers) Eles permitem que você crie contêineres e os gerencie a partir da GUI em vez da CLI. Veja como o Rancher aparenta: ![](/sites/default/files/inline/images/snimok_36.png) ##   ## Runner do GitLab Como antes, para executar scripts em outros servidores, precisaremos instalar o runner do GitLab. Discuti isso no [terceiro artigo](https://community.intersystems.com/post/continuous-delivery-your-intersystems-solution-using-gitlab-part-iii-gitlab-installation-and). Você precisará usar o executor Shell, e não o executor Docker. O executor Docker é usado quando você precisa de algo de dentro da imagem, por exemplo, você está criando um aplicativo Android em um contêiner java e precisa apenas de um apk. No nosso caso, precisamos de um contêiner inteiro e, para isso, precisamos do executor Shell. ##   ## Conclusão É fácil começar a executar contêineres e há muitas ferramentas disponíveis. A entrega contínua usando contêineres difere da configuração usual de várias maneiras: * As dependências são atendidas no momento da compilação e, após a criação da imagem, você não precisa pensar nas dependências. * Reprodutibilidade — é possível reproduzir facilmente qualquer ambiente existente ao executar o mesmo contêiner localmente. * Velocidade — como os contêineres não têm nada além do que você adicionou explicitamente, eles podem ser construídos com mais rapidez e, principalmente, eles são construídos uma vez e usados sempre que necessário. * Eficiência — como acima, os contêineres produzem menos sobrecarga do que, por exemplo, VMs. * Escalabilidade — com ferramentas de orquestração, você pode dimensionar automaticamente seu aplicativo para a carga de trabalho e consumir apenas os recursos necessários no momento. O que vem a seguir No próximo artigo, vamos falar sobre a criação da configuração de CD que usa o contêiner Docker do InterSystems IRIS.
Artigo
Danusa Calixto · Dez. 22, 2022

Entrega contínua de sua solução InterSystems usando GitLab – Parte IV: Configuração da CD

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como: * Git básico * Fluxo Git (processo de desenvolvimento) * Instalação do GitLab * Fluxo de trabalho do GitLab * Entrega contínua * Instalação e configuração do GitLab * **CI/CD do GitLab** No [primeiro artigo](https://pt.community.intersystems.com/post/entrega-cont%C3%ADnua-de-sua-solu%C3%A7%C3%A3o-intersystems-usando-gitlab-%E2%80%93-parte-i-git), abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software. No [segundo artigo](https://pt.community.intersystems.com/post/entrega-cont%C3%ADnua-de-sua-solu%C3%A7%C3%A3o-intersystems-usando-gitlab-%E2%80%93-parte-ii-fluxo-de-trabalho-do), abordamos o fluxo de trabalho do GitLab: um processo inteiro do ciclo de vida do software e a entrega contínua. No [terceiro artigo](https://pt.community.intersystems.com/post/entrega-cont%C3%ADnua-de-sua-solu%C3%A7%C3%A3o-intersystems-usando-gitlab-%E2%80%93-parte-iii-instala%C3%A7%C3%A3o-e), abordamos a instalação e configuração do GitLab e a conexão dos seus ambientes a ele Neste artigo, finalmente, vamos escrever uma configuração de CD. ## Plano ### Ambientes Em primeiro lugar, precisamos de vários ambientes e branches que correspondam a eles: Environment Branch Delivery Who can commit Who can merge Test master Automatic Developers Owners Developers Owners Preprod preprod Automatic No one Owners Prod prod Semiautomatic (press button to deliver) No one Owners ### Ciclo de desenvolvimento E, como exemplo, desenvolveremos um novo recurso usando o fluxo do GitLab e o entregaremos usando a CD do GitLab. 1. O recurso é desenvolvido em um branch de recursos. 2. O branch de recurso é revisado e mesclado no master branch. 3. Depois de um tempo (vários recursos mesclados), o master é mesclado com o preprod 4. Depois de um tempo (teste do usuário, etc.), o preprod é mesclado com o prod Veja como isso ficaria (marquei as partes que precisamos desenvolver para o CD em itálico): 1. Desenvolvimento e teste * O desenvolvedor envia o código para o novo recurso em um branch de recursos separado * Depois que o recurso se torna estável, o desenvolvedor mescla nosso branch de recursos no master branch * _O código do branch master é entregue ao ambiente de teste, onde é carregado e testado_ 2. Entrega para o ambiente de pré-produção * O desenvolvedor cria a solicitação de mesclagem do branch master para o branch de pré-produção * Depois de algum tempo, o proprietário do repositório aprova a solicitação de mesclagem * _O código do branch de pré-produção é entregue ao ambiente de pré-produção_ 3. Entrega para o ambiente de produção * O desenvolvedor cria a solicitação de mesclagem do branch de pré-produção para o branch de produção * Depois de algum tempo, o proprietário do repositório aprova a solicitação de mesclagem * O proprietário do repositório aperta o botão "Implantar" * _O código do branch de produção é entregue ao ambiente de produção_ Ou o mesmo, mas em formato de gráfico: ### Aplicativo Nosso aplicativo consiste em duas partes: * API REST desenvolvida na plataforma InterSystems * Web application de JavaScript cliente ## Estágios Com o plano acima, podemos determinar as etapas que precisamos definir na nossa configuração de entrega contínua: * Carregamento — para importar o código do lado do servidor para o InterSystems IRIS * Teste — para testar o código do servidor e cliente * Pacote — para criar o código do cliente * Implantação — para "publicar" o código do cliente usando o servidor web Veja como isso fica no arquivo de configuração gitlab-ci.yml: stages: - load - test - package - deploy ### Scripts #### Carregamento Em seguida, vamos definir os scripts. [Documentos de scripts](https://docs.gitlab.com/ee/ci/yaml/README.html). Primeiro, vamos definir um script load server que carrega o código do lado do servidor: load server: environment: name: test url: http://test.hostname.com only: - master tags: - test stage: load script: csession IRIS "##class(isc.git.GitLab).load()" O que acontece aqui? * load server é o nome de um script * em seguida, descrevemos o ambiente em que esse script é executado * only: master — informa ao GitLab que esse script só deve ser executado quando houver um commit para o master branch * tags: test especifica que esse script só deve ser executado em um runner com a tag test * stage especifica o estágio para um script * script define o código para executar. No nosso caso, chamamos o classmethod load da classe isc.git.GitLab > **Observação importante** > > Para InterSystems IRIS, troque _csession_ por _iris session_. > > Para Windows, use: _irisdb -s ../mgr -U TEST "##class(isc.git.GitLab).load()_   Agora, vamos escrever a classe isc.git.GitLab correspondente. Todos os pontos de entrada nessa classe ficam desta forma: ClassMethod method() { try { // code halt } catch ex { write !,$System.Status.GetErrorText(ex.AsStatus()),! do $system.Process.Terminate(, 1) } } Observe que esse método pode terminar de duas maneiras: * interrompendo o processo atual — que é registrado no GitLab como uma conclusão bem-sucedida * chamando $system.Process.Terminate — que termina o processo de maneira anormal e o GitLab registra isso como um erro Dito isso, aqui está nosso código de carregamento: /// Do a full load /// do ##class(isc.git.GitLab).load() ClassMethod load() { try { set dir = ..getDir() do ..log("Importing dir " _ dir) do $system.OBJ.ImportDir(dir, ..getExtWildcard(), "c", .errors, 1) throw:$get(errors,0)'=0 ##class(%Exception.General).%New("Load error") halt } catch ex { write !,$System.Status.GetErrorText(ex.AsStatus()),! do $system.Process.Terminate(, 1) } } Dois métodos de utilitários são chamados: * getExtWildcard — para obter uma lista das extensões de arquivo relevantes * getDir — para obter o diretório do repositório Como podemos obter o diretório? Quando o GitLab executa um script, primeiro, ele especifica várias [variáveis de ambiente](https://docs.gitlab.com/ce/ci/variables/README.html). Uma delas é a CI_PROJECT_DIR — o caminho completo onde o repositório é clonado e onde o job é executado. Ele pode ser obtido facilmente no nosso método getDir : ClassMethod getDir() [ CodeMode = expression ] { ##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR")) } ####Testes Aqui está o script de teste: load test: environment: name: test url: http://test.hostname.com only: - master tags: - test stage: test script: csession IRIS "##class(isc.git.GitLab).test()" artifacts: paths: - tests.html O que mudou? O nome e o código do script, é claro, mas o artefato também foi adicionado. Um artefato é uma lista de arquivos e diretórios que são anexados a um job depois que ele é concluído com sucesso. No nosso caso, depois que os testes forem concluídos, podemos gerar a página HTML redirecionando para os resultados dos testes e disponibilizá-la a partir do GitLab.  Observe que há bastante copiar e colar do estágio de carregamento — o ambiente é o mesmo, partes do script, como ambientes, podem ser rotuladas separadamente e anexadas a um script. Vamos definir o ambiente de teste: .env_test: &env_test environment: name: test url: http://test.hostname.com only: - master tags: - test Agora, nosso script de teste fica assim: load test: <<: *env_test script: csession IRIS "##class(isc.git.GitLab).test()" artifacts: paths: - tests.html Em seguida, vamos executar os testes usando o [framework UnitTest](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT). /// do ##class(isc.git.GitLab).test() ClassMethod test() { try { set tests = ##class(isc.git.Settings).getSetting("tests") if (tests'="") { set dir = ..getDir() set ^UnitTestRoot = dir $$$TOE(sc, ##class(%UnitTest.Manager).RunTest(tests, "/nodelete")) $$$TOE(sc, ..writeTestHTML()) throw:'..isLastTestOk() ##class(%Exception.General).%New("Tests error") } halt } catch ex { do ..logException(ex) do $system.Process.Terminate(, 1) } } A definição do teste, nesse caso, é um caminho relativo à raiz do repositório onde os testes de unidade são armazenados. Se estiver vazio, pulamos testes. O método writeTestHTML é usado para gerar o html com um redirecionamento para os resultados dos testes: ClassMethod writeTestHTML() { set text = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), "html").Data.Read() set text = $replace(text, "!!!", ..getURL()) set file = ##class(%Stream.FileCharacter).%New() set name = ..getDir() _ "tests.html" do file.LinkToFile(name) do file.Write(text) quit file.%Save() } ClassMethod getURL() { set url = ##class(isc.git.Settings).getSetting("url") set url = url _ $system.CSP.GetDefaultApp("%SYS") set url = url_"/%25UnitTest.Portal.Indices.cls?Index="_ $g(^UnitTest.Result, 1) _ "&$NAMESPACE=" _ $zconvert($namespace,"O","URL") quit url } ClassMethod isLastTestOk() As %Boolean { set in = ##class(%UnitTest.Result.TestInstance).%OpenId(^UnitTest.Result) for i=1:1:in.TestSuites.Count() { #dim suite As %UnitTest.Result.TestSuite set suite = in.TestSuites.GetAt(i) return:suite.Status=0 $$$NO } quit $$$YES } XData html { <html lang="en-US"> <head> <meta charset="UTF-8"/> <meta http-equiv="refresh" content="0; url=!!!"/> <script type="text/javascript"> window.location.href = "!!!" </script> </head> <body> If you are not redirected automatically, follow this <a href='!!!'>link to tests</a>. </body> </html> } #### Pacote Nosso cliente é uma página HTML simples: <html> <head> <script type="text/javascript"> function initializePage() { var xhr = new XMLHttpRequest(); var url = "${CI_ENVIRONMENT_URL}:57772/MyApp/version"; xhr.open("GET", url, true); xhr.send(); xhr.onloadend = function (data) { document.getElementById("version").innerHTML = "Version: " + this.response; }; var xhr = new XMLHttpRequest(); var url = "${CI_ENVIRONMENT_URL}:57772/MyApp/author"; xhr.open("GET", url, true); xhr.send(); xhr.onloadend = function (data) { document.getElementById("author").innerHTML = "Author: " + this.response; }; } </script> </head> <body onload="initializePage()"> <div id = "version"></div> <div id = "author"></div> </body> </html> E, para criá-la, precisamos substituir ${CI_ENVIRONMENT_URL} pelo seu valor. Claro, um aplicativo real provavelmente exigiria npm, mas esse é apenas um exemplo. Aqui está o script: package client: <<: *env_test stage: package script: envsubst < client/index.html > index.html artifacts: paths: - index.html #### Implantação Por fim, implantamos nosso cliente ao copiar index.html para o diretório raiz do servidor web. deploy client: <<: *env_test stage: deploy script: cp -f index.html /var/www/html/index.html É isso! ### Vários ambientes O que fazer se você precisar executar o mesmo script (semelhante) em vários ambientes? Partes do script também podem ser rótulos, então aqui está uma configuração de exemplo que carrega o código em ambientes de teste e pré-produção: stages: - load - test .env_test: &env_test environment: name: test url: http://test.hostname.com only: - master tags: - test .env_preprod: &env_preprod environment: name: preprod url: http://preprod.hostname.com only: - preprod tags: - preprod .script_load: &script_load stage: load script: csession IRIS "##class(isc.git.GitLab).loadDiff()" load test: <<: *env_test <<: *script_load load preprod: <<: *env_preprod <<: *script_load Assim, podemos fugir de copiar e colar o código. Veja a configuração de CD completa [aqui](https://github.com/intersystems-ru/GitLab/blob/master/.gitlab-ci.yml). Ela segue o plano original de mover código entre os ambientes de teste, pré-produção e produção. ## Conclusão A entrega contínua pode ser configurada para automatizar qualquer fluxo de trabalho de desenvolvimento necessário. ## Links * [Repositório de hooks (e configuração de exemplo)](https://github.com/intersystems-ru/GitLab) * [Repositório de teste](http://gitlab.eduard.win/test/testProject) * [Documentos de scripts](https://docs.gitlab.com/ee/ci/yaml/README.html) * [Variáveis de ambiente disponíveis](https://docs.gitlab.com/ce/ci/variables/README.html) ## O que vem a seguir No próximo artigo, vamos criar a configuração de CD que usa o contêiner Docker do InterSystems IRIS.