#InterSystems IRIS

0 Seguidores · 854 Postagens

InterSystems IRIS é uma plataforma de dados completa
A InterSystems IRIS oferece tudo que você precisa para capturar, compartilhar, entender e agir com base no ativo mais valioso de sua organização - seus dados.
Como uma plataforma completa, a InterSystems IRIS elimina a necessidade de integração de múltiplas tecnologias de desenvolvimento. As aplicações requerem menos código, menos recursos do sistema e menos manutenção.

Pergunta Marcelo Witt · Jul. 21, 2025

Olá pessoal!
Estamos construindo uma aplicação utilizando React+IRIS, mas precisamos ter a opção de multilinguagem para essa situação, e gostaria de saber qual a melhor prática/forma para fazer essas traduções. Da aplicação diretamente até é mais fácil montando-se um 'de/para', entretanto, minha preocupação maior é diretamente com dados cadastrados, para que esses possam ser traduzidos também conforme a linguagem cadastrada para o usuário. Obrigado!!!

5
0 48
Artigo Heloisa Paiva · Out. 30, 2025 4m read

Ao usar SQL padrão ou a camada de objetos no InterSystems IRIS, a consistência dos metadados é geralmente mantida por meio de validação integrada e imposição de tipo. No entanto, sistemas legados que ignoram essas camadas—acessando globals diretamente—podem introduzir inconsistências sutis e graves.

1
0 13
Anúncio Danusa Calixto · Out. 30, 2025

Olá Comunidade,

Você é um desenvolvedor Python? Se sim, você já pode começar a criar aplicativos com o InterSystems IRIS sem precisar aprender uma nova linguagem de programação! 

Use Python with InterSystems IRIS. Try the exercise. 

👨‍💻Experimente este exercício para começar rapidamente a usar a interface familiar DB-API do Python para se conectar a um banco de dados InterSystems IRIS e executar consultas SQL.

💬 Qual foi a sua experiência com o exercício? Conte-me nos comentários!

0
0 13
InterSystems Oficial Danusa Calixto · Out. 28, 2025

Visão Geral 

Esta versão se concentra em aprimorar a confiabilidade, expandir a segurança e aprimorar a experiência de suporte em diversos Serviços em Nuvem da InterSystems. Com esta versão, todas as principais ofertas — incluindo FHIR Server, InterSystems Data Fabric Studio (IDS), IDS com Supply Chain e IRIS Managed Services — agora oferecem suporte ao Advanced Security, proporcionando uma postura de segurança unificada e aprimorada.

Novos Recursos e Melhoria

0
0 9
Artigo Heloisa Paiva · Out. 23, 2025 1m read

Olá a todos,

Esta é uma dica rápida sobre como usar URLs em serviços REST API sem distinção entre maiúsculas e minúsculas.

Se você tem uma classe que estende de %CSP.REST e Ens.BusinessService para criar um serviço REST API, e você definiu seu WebApplication em minúsculas:

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/user" Method="POST" Call="User"/>
    <Route Url="/login" Method="POST" Call="Login"/>
</Routes>
}

Ele só aceitará URLs em minúsculas, por exemplo: http://myserver/myproduction/user

0
0 19
Artigo Heloisa Paiva · Out. 17, 2025 3m read

Para gerenciar o acúmulo de dados de produção, o InterSystems IRIS permite aos usuários controlar o tamanho do banco de dados eliminando (expurgando) periodicamente os dados. Esta purga pode ser aplicada a mensagens, registros, processos de negócio e alertas gerenciados.

Consulte a documentação para obter mais detalhes sobre a configuração da tarefa de expurgo:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=EGMG_purge#EGMG_purge_settings

0
0 16
Artigo Heloisa Paiva · Out. 16, 2025 13m read

.

Estou muito emocionado de continuar com a minha série de artigos "InterSystems para Dummies", e hoje queremos contar tudo sobre uma das funções mais potentes que temos para a interoperabilidade.

Mesmo que já as tenha utilizado, planejamos analisar a fundo como aproveitá-las ao máximo e melhorar ainda mais nossa produção.

O que é um Record Mapper?

Essencialmente, um Record Mapper é uma ferramenta que permite mapear dados de arquivos de texto a mensagens de produção e vice-versa. A inteface do Portal de Administração, por outro lado, permite criar uma representação visual de um arquivo de texto e um modelo de objeto válido desses dados para mapear-los a um único objeto de mensagem de produção persistente.

Portanto, se você deseja importar dados de um arquivo CSV à sua classe persistente, pode tentar com um par de classes de entrada (por FTP ou diretório de arquivos). Mas não se apresse! Vamos abordar cada um desses pontos no seu devido tempo.


TIP: Todos os exemplos e classes descritos nessse artigo podem ser baixados no seguinte link: https://github.com/KurroLopez/iris-recordmap-fordummies.git


Como começar?

Vou direto ao ponto e especifico nosso cenário.

Precisamos importar informações de nossos clientes, incluindo seu nome, data de nascimento, número de identificação nacional, endereço, cidade e país.

Abra seu portal IRIS e selecione Interoperabilidade – Criar – Record Maps. image

Crie um novo Record Maps com o nome do pacote e a classe. image

Em nosso exemplo, o nome do pacote é Demo.Data, enquanto o nome da classe é es PersonalInfo.

O primeiro passo é configurar o arquivo CSV. Isso significa determinar o caractere separador, se os campos de string têm aspas duplas, etc. image

Se você usa o sistema operacional Windows, o terminador de registro comum é CRLF (Char(10) Char(12)).

Como meu arquivo CSV é padrão, separado por ponto e vírgula (;), devo definir o caractere do separador de campos.

Agora, vou declarar os campos do perfil do cliente (nome, sobrenome, data de nascimento, número de identificação nacional, endereço, cidade e país). image

Esta é uma definição básica, mas você pode estabelecer mais condições em relação ao seu arquivo CSV, se desejar. image

Lembre-se de que, por padrão, um campo %String tem um comprimento máximo de 50 caracteres. Portanto, atualizarei este valor para permitir mais caracteres no campo de endereço (um máximo de 100).

Também definirei o formato de data usando o formato ISO (aaaa-mm-dd), que corresponde ao número 3.

Além disso, tornarei os campos Nome, Sobrenome e Data de Nascimento obrigatórios. image

Pronto! Vamos pressionar o botão "Gerar" para criar a classe persistente! image

Dê uma olhada na classe gerada: /// THIS IS GENERATED CODE. DO NOT EDIT.
/// RECORDMAP: Generated from RecordMap 'Demo.Data.PersonalInfo' /// on 2025-07-14 at 08:37:00.646 [2025-07-14 08:37:00.646 UTC] /// by user SuperUser Class Demo.Data.PersonalInfo.Record Extends (%Persistent, %XML.Adaptor, Ens.Request, EnsLib.RecordMap.Base) [ Inheritance = right, ProcedureBlock ] {

Parameter INCLUDETOPFIELDS = 1;

Property Name As %String [ Required ];

Property Surname As %String [ Required ];

Property DateOfBirth As %Date(FORMAT = 3) [ Required ];

Property NationalId As %String;

Property Address As %String(MAXLEN = 100);

Property City As %String;

Property Country As %String;

Parameter RECORDMAPGENERATED = 1;

Storage Default
{
<Data name="RecordDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>%Source</Value>
</Value>
<Value name="4">
<Value>DateOfBirth</Value>
</Value>
<Value name="5">
<Value>NationalId</Value>
</Value>
<Value name="6">
<Value>Address</Value>
</Value>
<Value name="7">
<Value>City</Value>
</Value>
<Value name="8">
<Value>Country</Value>
</Value>
<Value name="9">
<Value>Surname</Value>
</Value>
</Data>
<DataLocation>^Demo.Data.PersonalInfo.RecordD</DataLocation>
<DefaultData>RecordDefaultData</DefaultData>
<ExtentSize>2000000</ExtentSize>
<IdLocation>^Demo.Data.PersonalInfo.RecordD</IdLocation>
<IndexLocation>^Demo.Data.PersonalInfo.RecordI</IndexLocation>
<StreamLocation>^Demo.Data.PersonalInfo.RecordS</StreamLocation>
<Type>%Storage.Persistent</Type>
}

}

Como você pode ver, cada propriedade tem o nome dos campos em nosso arquivo CSV.

Neste ponto, criaremos um arquivo CSV com a seguinte estrutura para testar nosso Record Mapper:

Name;Surname;DateOfBirth;NationalId;Address;City;Country Matthew O.;Wellington;1964-31-07;208-36-1552;1485 Stiles Street;Pittsburgh;USA Deena C.;Nixon;1997-03-03;495-26-8850;1868 Mandan Road;Columbia;USA Florence L.;Guyton;2005-04-10;21 069 835 790;Invalidenstrasse 82;Contwig;Germany Maximilian;Hahn;1945-10-17;92 871 402 258;Boxhagener Str. 97;Hamburg;Germany Amelio;Toledo Zavala;1976-06-07;93789292F;Plaza Mayor, 71;Carbajosa de la Sagrada;Spain

Você pode usá-lo como teste agora.

Clique em "Selecionar arquivo de amostra" selecione a amostra em /irisrun/repo/Samples e escolha PersonalInfo-Test.csv. image

Neste momento, você poderá observar como seus dados são importados: image

Os Problemas Aumentam

Justo quando você pensa que está tudo pronto, você recebe uma nova especificação do seu chefe:

"Precisamos dos dados para poder carregar o número de telefone do cliente e armazenar mais de um (fixo, celular, etc.)".

Ops... Preciso atualizar meu Record Map e adicionar um número de telefone. No entanto, deve haver mais de um... Como posso fazer isso?


Nota: Você pode fazer isso diretamente na mesma classe. No entanto, criarei uma nova para fins explicativos e a salvarei nos exemplos. Desta forma, você pode revisar e executar o código seguindo todos os passos deste artigo.


Bem, é hora de reabrir o Record Map que acabamos de criar.

Adicione o novo campo "Phone", mas lembre-se de indicar que este campo é "Repetido". image

Como atribuímos este campo como "Repetido", devemos definir o caractere separador para os dados replicados. Este indicador está no mesmo lugar onde normalmente especificamos o separador de campo. image

Perfeito! Vamos carregar o arquivo CSV de exemplo com os números de telefone separados por #. image

Se dermos uma olhada na classe persistente que produzimos, podemos ver que o campo "Phone" é do tipo %String:

Property Phone As list Of %String(MAXLEN = 20);

Ok, Kurro, mas como podemos enviar este arquivo?

Essa é uma pergunta muito boa, caro leitor.

O InterSystems IRIS nos fornece duas classes de entrada (inbound): EnsLib.RecordMap.Service.FileServiceEnsLib.RecordMap.Service.FTPService

Não vou me aprofundar nessas classes porque seria muito longo. No entanto, podemos revisar suas funções principais.

Em resumo, o serviço monitora os processos em uma pasta definida, captura os arquivos armazenados nesse diretório, os carrega, os lê linha por linha e envia esse registro para o Processo de Negócio designado.

Isso ocorre tanto no servidor quanto nos diretórios FTP.

Vamos ao que interessa...


Nota: Apresentarei meus exemplos usando a classeEnsLib.RecordMap.Service.FileService. No entanto, a classe EnsLib.RecordMap.Service.FTPService realiza as mesmas operações.


Se você baixou o código de exemplo, verá que uma produção foi criada com dois componentes:

Uma classe de Serviço (EnsLib.RecordMap.Service.FileService), que carregará os arquivos, e uma classe de Negócio (Demo.BP.ProcessData),que processará cada um dos registros lidos do arquivo. Neste caso, usaremos este último apenas para ver os rastros de comunicação.

É importante configurar alguns parâmetros na classe do Business Service. image

File Path: É um registro que a classe usa para monitorar se há arquivos pendentes de processamento. Ao colocar um arquivo neste diretório, o processo de carregamento é ativado automaticamente e envia cada registro para a classe definida como Processo de Negócios.

File Spec: É um padrão de arquivo para buscar (por padrão, é *, mas podemos definir alguns arquivos que desejamos diferenciar de outros processos). Por exemplo, podemos ter duas classes de escuta de entrada no mesmo diretório, cada uma com uma classe RecordMap diferente. Podemos atribuir a extensão .pi1 aos arquivos que a classe PersonalInfo processará, enquanto .pi2 marcará os arquivos que serão processados pela classe PersonalInfoPhone.

Archive Path: É um diretório onde os arquivos são movidos após serem processados.

Work Path: É um caminho onde o adaptador deve colocar o arquivo de entrada enquanto processa os dados. Esta configuração é útil quando se usa o mesmo nome de arquivo para envios repetidos. Se o WorkPath não for especificado, o adaptador não moverá o arquivo durante o processamento.

Call Interval: É a frequência (calculada em segundos) das verificações do adaptador para os arquivos de entrada nos locais especificados.

RecordMap: É o nome da classe Record Map, que contém a definição dos dados no arquivo.

Target Config Name: É o nome do Processo de Negócio que manipula os dados armazenados no arquivo.

image

Subdirectory Levels: É um espaço onde o processo busca um novo arquivo. Por exemplo, se um processo adiciona um arquivo a cada dia (segunda, terça, quarta, quinta e sexta), ele buscará em todos os subdiretórios, começando pelo diretório raiz, sempre que especificarmos o nível 1. Por padrão, o nível 0 significa que ele buscará apenas no diretório raiz.

Delete From Server: Esta função indica que, se o diretório dos arquivos processados não for especificado, o arquivo será excluído do diretório raiz.

File Access Timeout: É um tempo definido (calculado em segundos) para acessar o arquivo. Se o arquivo for somente leitura ou houver algum problema que impeça o acesso ao diretório, será exibido um erro.

Header Count:: É uma característica importante que indica o número de cabeçalhos que devem ser ignorados. Por exemplo, se o arquivo tiver um cabeçalho que especifica os campos que contém, você deve indicar quantas linhas de cabeçalho ele contém para que possam ser ignoradas e apenas as linhas de dados possam ser lidas.

Carregar um Arquivo

Como mencionei anteriormente, o processo de carregamento é ativado quando um arquivo é colocado no diretório do processo

Nota: As seguintes instruções são baseadas no código de exemplo. Na pasta "samples", você encontrará o arquivo PersonalInfoPhone-Test.csv. Você deve copiar este arquivo para a pasta do processo para que ele seja processado automaticamente.


NOTA: Se estiver trabalhando com Docker, use o seguinte comando: docker cp .\PersonalInfoPhone-Test.csv containerId:/opt/irisbuild/process/containerId é o ID do seu contêiner, ex: : docker cp .\PersonalInfoPhone-Test.csv 66f96b825d43398ba6a1edcb2f02942dc799d09f1b906627e0563b1392a58da1:/opt/irisbuild/process/` image


Para cada registro, ele dispara uma chamada para o Processo de Negócio com todos os dados. image

Excelente trabalho! Em apenas alguns passos, você conseguiu criar um processo que pode ler arquivos de um diretório e gerenciar esses dados de forma rápida e fácil. O que mais você poderia pedir aos seus processos de interoperabilidade?

Complex Record Map (Mapa de Registro Complexo)

Ninguém quer ter uma vida complexa, mas eu prometo que você vai se apaixonar pelos Complex Record Maps.

Os Complex Record Maps são exatamente o que o nome indica. Trata-se de uma combinação de vários Record Maps que nos fornece informações mais completas e estruturadas.

Imaginemos que nosso chefe nos contacta e nos apresenta os seguintes requisitos:

“Precisamos de informações do cliente com mais números de telefone, incluindo códigos de país e prefixos. Também precisamos de mais endereços de contato, incluindo códigos postais, países e nomes de estados.

Um cliente pode ter um número de telefone, dois ou nenhum”.

Se precisarmos de mais informações sobre números de telefone e endereços, como vimos anteriormente, incluir essas informações em uma única linha seria muito complicado. Vamos separar as diferentes partes de que precisamos:

  • Informações do cliente necessárias.
  • Números de telefone (de 0 a 5).
  • Endereço postal (de 0 a 2).

Para cada seção, criaremos um apelido para diferenciar o tipo de informação que inclui.

Vamos construir cada seção:

Passo 1 Projete um novo Record Maps para as informações do cliente (Nome, Sobrenome, Data de Nascimento e Documento Nacional de Identidade) e inclua um identificador para indicar que se trata da seção USER. image

O nome da seção deve ser único para os tipos de dados "USER", pois são responsáveis por configurar as colunas e posições de cada dado. O conteúdo deve ser semelhante ao seguinte: USER|Matthew O.;Wellington;1964-07-31;208-36-1552 Em NEGRITO, o nome da seção, em ITALICO, o conteúdo.

Passo 2 Crie as seções PHONE e ADDRESS para os números de telefone e os endereços postais.

Lembre-se de especificar o nome da seção e ativar a opção Complex Record Map. imageimage

Agora devemos ter três classes:

  • Demo.Data.ComplexUser
  • Demo.Data.ComplexPhone
  • Demo.Data.ComplexAddress

Passo 3 Complete o Complex Record Map.

Abra a opção "Complex Record Maps": image

A primeira coisa que vemos aqui é uma estrutura com um cabeçalho e um rodapé. O cabeçalho pode ser outro mapa de registros para armazenar informações do pacote de dados (por exemplo, informações do departamento do usuário, etc.).

Como estas seções são opcionais, vamos ignorá-las em nosso exemplo. image

Defina o nome deste registro (por exemplo, PersonalInfo) e adicione novos registros para cada seção. image

Se quisermos que uma das seções tenha repetições, devemos indicar os valores mínimos e máximos de repetição. image

De acordo com as especificações anteriores, o arquivo com as informações se parecerá com isto:

USER|Matthew O.;Wellington;1964-07-31;208-36-1552
PHONE|1;305;2089160
PHONE|1;805;9473136
ADDR|1485 Stiles Street;Pittsburgh;15286;PA;USA

Se quisermos carregar um arquivo, precisamos de um serviço que possa ler este tipo de arquivos, e o InterSystems IRIS nos fornece duas classes de entrada para isso:

EnsLib.RecordMap.Service.ComplexBatchFileServiceEnsLib.RecordMap.Service.ComplexBatchFTPService Como mencionei anteriormente, usaremos a classe EnsLib.RecordMap.Service.ComplexBatchFileService como exemplo. No entanto, o processo para FTP é idêntico.

Utilize a mesma configuração que o Record Map, exceto pelo número de linha do cabeçalho, porque este tipo de arquivo não precisa de um: image

Como mencionei anteriormente, o processo de carregamento é ativado quando um arquivo é colocado no diretório do processo.

Nota: As seguintes instruções são baseadas no código de exemplo.

Na pasta "samples", você encontrará o arquivo PersonalInfoComplex.txt. Você deve copiar este arquivo para a pasta do processo para que ele seja processado automaticamente.


NOTA: Se estiver trabalhando com o exemplo do Docker, utilize o seguinte comando:

docker cp .\ PersonalInfoComplex.txt containerId:/opt/irisbuild/process/p
containerId é o ID do seu contêiner, ex: docker cp .\ PersonalInfoComplex.txt 66f96b825d43398ba6a1edcb2f02942dc799d09f1b906627e0563b1392a58da1:/opt/irisbuild/process/

Aqui podemos ver cada linha chamando o Business Service: imageimageimage

Como você já deve ter notado, os Record Maps são uma ferramenta potente para importar dados de forma complexa e estruturada. Permitem salvar informações em tabelas relacionadas ou processar cada dado de forma independente.

Graças a esta ferramenta, você pode criar rapidamente processos de carregamento de dados em lote e armazená-los sem a necessidade de realizar leituras complexas de dados, separação de campos, validação de tipos de dados, etc.

Espero que este artigo seja útil.

Nos vemos no próximo "InterSystems para Dummies".

0
0 17
Artigo Davi Massaru Teixeira Muta · Out. 11, 2025 10m read

Documentação Técnica — Quarkus IRIS Monitor System

1. Objetivo e Escopo

Este módulo permite a integração entre aplicações Java baseadas em Quarkus e as capacidades nativas de monitoramento de performance do InterSystems IRIS.
Ele possibilita que o desenvolvedor anote métodos com @PerfmonReport, acionando automaticamente as rotinas ^PERFMON do IRIS durante a execução do método e gerando relatórios de performance sem intervenção manual.


2. Componentes do Sistema

2.1 Anotação: @PerfmonReport

  • Definida como InterceptorBinding do CDI.
  • Pode ser aplicada a métodos ou classes.
  • Instrui o framework a envolver a execução do método com a lógica de monitoramento do IRIS.

2.2 Interceptor: PerfmonReportInterceptor

  • Intercepta chamadas a métodos anotados.

  • Fluxo de execução:

    1. Registrar evento de início (LOG.infof("INIT: …"))
    2. Chamar monitorSystem.startPerfmon()
    3. Prosseguir com context.proceed()
    4. No bloco finally:
      • Chamar monitorSystem.generateReportPerfmon(...)
      • Chamar monitorSystem.stopPerfmon()
      • Registrar evento de fim com tempo de execução
  • Garante que o monitoramento sempre será encerrado, mesmo se ocorrer uma exceção.

2.3 Bean DAO: MonitorSystem

  • Bean CDI anotado com @ApplicationScoped.

  • Mantém uma única instância de IRIS inicializada na inicialização.

  • Configuração injetada via @ConfigProperty (URL JDBC, usuário, senha).

  • Utiliza DriverManager.getConnection(...) para obter uma IRISConnection nativa.

  • Contém os métodos:

    • startPerfmon()
    • generateReportPerfmon(String reportName)
    • stopPerfmon()
  • Cada método chama as correspondentes rotinas ObjectScript em iris.src.dc.AdapterPerfmonProc via iris.classMethodVoid(...).

2.4 Adapter ObjectScript: iris.src.dc.AdapterPerfmonProc

  • Define as rotinas que encapsulam a lógica do ^PERFMON:

      Class iris.src.dc.AdapterPerfmonProc Extends %RegisteredObject
      {
          ClassMethod start() As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              set status = $$Stop^PERFMON()
              set status = $$Start^PERFMON()
              zn namespace
              return status
          }
    
          ClassMethod generateReport(nameReport As %String = "report.txt") As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              Set tempDirectory = ##class(%SYS.System).TempDirectory()
              set status = $$Report^PERFMON("R","R","P", tempDirectory_"/"_nameReport)
              zn namespace
    
              return status
          }
    
          ClassMethod stop() As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              Set status = $$Stop^PERFMON()
              zn namespace
    
              return status
          }
      }
    

    Opera no namespace %SYS para acessar as rotinas ^PERFMON e, em seguida, retorna para o namespace original.

  • Opera no namespace %SYS para acessar as rotinas ^PERFMON, retornando ao namespace original.


3. Fluxo de Execução

  1. Uma requisição entra na aplicação Quarkus.

  2. O interceptor CDI detecta a anotação @PerfmonReport e intercepta a chamada do método.

  3. monitorSystem.startPerfmon() é invocado, acionando o monitoramento ^PERFMON do IRIS.

  4. O método de negócio é executado normalmente (acesso a dados, transformações, lógica, etc.).

  5. Após o método retornar ou lançar uma exceção, o interceptor garante que:

    • monitorSystem.generateReportPerfmon(...) seja chamado para criar um relatório de performance .txt.
    • monitorSystem.stopPerfmon() seja executado para encerrar a sessão de monitoramento.
    • O tempo total de execução do lado Java seja registrado usando Logger.infof(...).
  6. O arquivo de relatório gerado é armazenado no diretório temporário do IRIS, normalmente: /usr/irissys/mgr/Temp/

    • O nome do arquivo segue o padrão: <ClassName><MethodName><timestamp>.txt

4. Desafios Técnicos e Soluções

DesafioSolução
ClassCastException ao usar conexões JDBC pooladasUse DriverManager.getConnection(...) para obter uma IRISConnection nativa, em vez do ConnectionWrapper poolado.
Sobrecarga por abrir conexões repetidamenteMantenha uma única instância de IRIS dentro de um bean @ApplicationScoped, inicializada via @PostConstruct.
Garantir que ^PERFMON seja sempre encerrado, mesmo em exceçõesUse try-finally no interceptor para chamar stopPerfmon() e generateReportPerfmon().
Portabilidade de configuraçãoInjete as configurações de conexão (jdbc.url, username, password) usando @ConfigProperty e application.properties.
Gerenciamento de sessões de monitoramento concorrentesEvite anotar endpoints com alta concorrência. Versões futuras podem implementar isolamento por sessão.

5. Casos de Uso e Benefícios

  • Permite visibilidade em tempo real da atividade do IRIS a partir do código Java.
  • Simplifica a análise de performance e otimização de consultas para desenvolvedores.
  • Útil para benchmarking, profiling e testes de regressão do sistema.
  • Pode servir como um registro leve de auditoria de performance para operações críticas.

6. Exemplo Prático de Uso

O código-fonte completo e o setup de deployment estão disponíveis em:


6.1 Visão Geral

A aplicação roda um servidor Quarkus conectado a uma instância InterSystems IRIS configurada com o namespace FHIRSERVER.
A camada ORM é implementada usando Hibernate ORM com PanacheRepository, permitindo mapeamento direto entre entidades Java e classes do banco IRIS.

Quando a aplicação é iniciada (via docker-compose up), são iniciados:

  • O container IRIS, hospedando o modelo de dados FHIR e rotinas ObjectScript (incluindo AdapterPerfmonProc);
  • O container Quarkus, expondo endpoints REST e conectando-se ao IRIS via driver JDBC nativo.

6.2 Endpoint REST

Um recurso REST expõe um endpoint simples para recuperar informações de pacientes:

@Path("/patient")
public class PatientResource {

    @Inject
    PatientService patientService;

    @GET
    @Path("/info")
    @Produces(MediaType.APPLICATION_JSON)
    public PatientInfoDTO searchPatientInfo(@QueryParam("key") String key) {
        return patientService.patientGetInfo(key);
    }
}

Este endpoint aceita um parâmetro de consulta (key) que identifica o recurso do paciente dentro do repositório de dados FHIR.


6.3 Camada de Serviço com @PerfmonReport

A classe PatientService contém a lógica de negócio para recuperar e compor informações do paciente.
Ela é anotada com @PerfmonReport, o que significa que cada requisição para /patient/info aciona o monitoramento de performance do IRIS:

@ApplicationScoped
public class PatientService {

    @Inject
    PatientRepository patientRepository;

    @PerfmonReport
    public PatientInfoDTO patientGetInfo(String patientKey) {

        Optional<Patient> patientOpt = patientRepository.find("key", patientKey).firstResultOptional();
        Patient patient = patientOpt.orElseThrow(() -> new IllegalArgumentException("Patient not found"));

        PatientInfoDTO dto = new PatientInfoDTO();
        dto.setKey(patient.key);
        dto.setName(patient.name);
        dto.setAddress(patient.address);
        dto.setBirthDate(patient.birthDate != null ? patient.birthDate.toString() : null);
        dto.setGender(patient.gender);
        dto.setMedications(patientRepository.findMedicationTextByPatient(patientKey));
        dto.setConditions(patientRepository.findConditionsByPatient(patientKey));
        dto.setAllergies(patientRepository.findAllergyByPatient(patientKey));

        return dto;
    }
}

6.4 Fluxo de Execução

Uma requisição é feita para: GET /patient/info?key=Patient/4

O Quarkus encaminha a requisição para PatientResource.searchPatientInfo().

O interceptor CDI detecta a anotação @PerfmonReport em PatientService.patientGetInfo().

Antes de executar a lógica de serviço:

  • O interceptor invoca MonitorSystem.startPerfmon(), que chama a classe IRIS iris.src.dc.AdapterPerfmonProc.start().

  • O método executa a lógica de negócio, consultando dados do paciente usando os mapeamentos Hibernate PanacheRepository.

Após a conclusão do método:

  • MonitorSystem.generateReportPerfmon() é chamado para criar o relatório de performance.

  • MonitorSystem.stopPerfmon() interrompe o monitoramento de performance do IRIS.

Um relatório .txt é gerado em: usr/irissys/mgr/Temp/

Exemplo de nome de arquivo: PatientService_patientGetInfo_20251005_161906.txt

6.5 Resultado

O relatório gerado contém estatísticas detalhadas de execução do IRIS, por exemplo:

                         Routine Activity by Routine

Started: 10/11/2025 05:07:30PM                    Collected: 10/11/2025 05:07:31PM

Routine Name                        RtnLines  % Lines   RtnLoads  RtnFetch  Line/Load Directory
----------------------------------- --------- --------- --------- --------- --------- ---------
Other                                     0.0       0.0       0.0       0.0         0
PERFMON                                  44.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%occLibrary                         3415047.0      34.1   48278.0       0.0      70.7 /usr/irissys/mgr/irislib/
iris.src.dc.AdapterPerfmonProc.1          7.0       0.0       2.0       0.0       3.5 /usr/irissys/mgr/FHIRSERVER/
%occName                            5079994.0      50.7       0.0       0.0         0 /usr/irissys/mgr/irislib/
%apiDDL2                            1078497.0      10.8   63358.0       0.0      17.0 /usr/irissys/mgr/irislib/
%SQL.FeatureGetter.1                 446710.0       4.5   66939.0       0.0       6.7 /usr/irissys/mgr/irislib/
%SYS.WorkQueueMgr                       365.0       0.0       1.0       0.0     365.0 /usr/irissys/mgr/
%CSP.Daemon.1                            16.0       0.0       1.0       0.0      16.0 /usr/irissys/mgr/irislib/
%SYS.TokenAuth.1                         14.0       0.0       5.0       0.0       2.8 /usr/irissys/mgr/
%Library.PosixTime.1                      2.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislib/
%SYS.sqlcq.uEXTg3QR7a7I7Osf9e8Bz...      52.0       0.0       1.0       0.0      52.0 /usr/irissys/mgr/
%SYS.SQLSRV                              16.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%apiOBJ                                 756.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislib/
FT.Collector.1                            0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
SYS.Monitor.FeatureTrackerSensor.1        0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%SYS.Monitor.Control.1                    0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%SYS.DBSRV.1                            252.0       0.0       4.0       0.0      63.0 /usr/irissys/mgr/
%sqlcq.FHIRSERVER.cls12.1                19.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls13.1                74.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls14.1                74.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls15.1                52.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%SYS.System.1                             1.0       0.0       0.0       0.0         0 /usr/irissys/mgr/

Esses dados fornecem uma visão precisa sobre quais rotinas foram executadas internamente pelo IRIS durante aquela chamada REST — incluindo compilação de SQL, execução e acesso a dados FHIR.

Observação: As rotinas %sqlcq.FHIRSERVER.* registram todas as consultas SQL cache executadas pelo Quarkus dentro do método. Monitorar essas rotinas permite aos desenvolvedores analisar a execução das queries, compreender o comportamento do código e identificar possíveis gargalos de performance. Isso as torna uma ferramenta poderosa para desenvolvimento e depuração de operações relacionadas ao FHIR.

image

6.6 Resumo

Este exemplo demonstra como um serviço padrão Quarkus pode utilizar de forma transparente as ferramentas nativas de monitoramento do IRIS usando a anotação @PerfmonReport.
Ele combina:

  • Interceptadores CDI (Quarkus)
  • Hibernate PanacheRepositories (ORM)
  • Rotinas ObjectScript nativas do IRIS (^PERFMON)

O resultado é um mecanismo de profiling de performance totalmente automatizado e reproduzível, que pode ser aplicado a qualquer método de serviço na aplicação.

0
0 17
Artigo Yuri Marx · Out. 9, 2025 4m read

A linguagem ObjectScript possui um suporte incrível a JSON por meio de classes como %DynamicObject e %JSON.Adaptor. Esse suporte se deve à imensa popularidade do formato JSON em relação ao domínio anterior do XML. O JSON trouxe menos verbosidade à representação de dados e aumentou a legibilidade para humanos que precisavam interpretar conteúdo JSON. Para reduzir ainda mais a verbosidade e aumentar a legibilidade, o formato YAML foi criado. O formato YAML, muito fácil de ler, rapidamente se tornou o formato mais popular para representar configurações e parametrizações, devido à sua legibilidade

0
0 16
Artigo Heloisa Paiva · Out. 8, 2025 3m read

Parece-me que, por alguma razão, isto não chegou à documentação oficial e aparenta ser pouco conhecido, embora já tenha sido implementado no IRIS 2020.1.

Graças a @Dan Pasco, obtive uma pista sobre as classes envolvidas. Usei a sequência recomendada de como utilizá-lo. Tudo foi retirado diretamente da Referência de Classe e eu apenas compilei para criar uma primeira visão geral.

1
0 22
Artigo Heloisa Paiva · Out. 7, 2025 2m read

Com a rápida adoção da telemedicina, consutlas remotas e digitação digital, profissionais da saúde estão se comunicano mais do que nunca por voz. Pacientes em conversas virtuais geram uma vasta quantidade de dados sonoros não estruturados, então como clínicos e administradores pesquisam e extraem informações d horas de gravações de voz? 

Apresentamos o IRIS Audio Query – um aplicativo full-stack que transforma áudio em uma base de conhecimento pesquisável. Com ele, você pode:

0
0 22
Anúncio Danusa Calixto · Out. 7, 2025

Olá Comunidade, 

Estamos felizes em compartilhar um novo tutorial do Instruqt: 

🧑‍🏫 RAG usando a Pesquisa Vetorial do InterSystems IRI

Este laboratório prático orienta você na construção de um chatbot de IA de Geração Aumentada de Recuperação (RAG) com tecnologia InterSystems IRIS Vector Search. Você verá como a pesquisa vetorial pode ser utilizada para fornecer respostas atualizadas e precisas, combinando os pontos fortes do IRIS com a IA generativa.

✨ Por que tentar?

0
0 13
Artigo Heloisa Paiva · Set. 30, 2025 3m read

Oi pessoal!  Esse artigo é para quem está começando com InterSystems IRIS. Espero que ajude!

O InterSystems IRIS é uma plataforma de dados unificada: uma base de dados de alta performance com ferramentas de interoperabilidade e análise integradas em um só produto. Você tem SQL e NoSQL na mesma máquina, além de jeitos nativos de rodar Python com seus dados. Em resumo: menos peças móveis, mais capacidade de processamento.

Por que engenheiros escolhem IRIS

0
0 28
Artigo Larissa Prussak · Set. 18, 2025 1m read

Se um dos seus pacotes no OEX recebe uma avaliação, você é notificado pelo OEX apenas sobre o seu próprio pacote.
A classificação reflete a experiência do avaliador com o status encontrado no momento da avaliação.
É como uma fotografia instantânea e pode já ter mudado desde então.
As avaliações feitas por outros membros da comunidade são marcadas com * na última coluna.

1
0 15
Artigo Danusa Calixto · Set. 17, 2025 3m read

Olá, pessoal! Tendo me integrado recentemente à InterSystems, percebi que, apesar de ter uma Edição Comunitária totalmente gratuita e incrível, não é muito claro como obtê-la. Decidi escrever um guia destacando todas as diferentes maneiras de acessar a Edição Comunitária do InterSystems IRIS:

Obtenha o InterSystems IRIS Community Edition como um contêiner

Trabalhar com uma instância em contêiner da Community Edition é a abordagem recomendada para quem está começando a desenvolver no InterSystems IRIS e, na minha opinião, é a mais simples. A Community Edition do InterSystems IRIS pode ser encontrada no DockerHub; se você tiver uma conta InterSystems SSO, também poderá encontrá-la no Registro de Contêineres da InterSystems.

Em ambos os casos, você vai querer extrair a imagem desejada usando o Docker CLI:

docker pull intersystems/iris-community:latest-em
// or
docker pull containers.intersystems.com/intersystems/iris-community:latest-em

Em seguida, você precisará iniciar o contêiner: para interagir com o IRIS de fora do contêiner (por exemplo, para usar o portal de gerenciamento), você precisará publicar algumas portas. O comando a seguir executará o contêiner IRIS Community Edition com as portas do superservidor e do servidor web publicadas; observe que você não pode executar nada que dependa das portas 1972 ou 52773!

docker run --name iris -d --publish 1972:1972 --publish 52773:52773 intersystems/iris-community:latest-em
0
0 35
Artigo Heloisa Paiva · Set. 16, 2025 3m read

Começar a usar ObjectScript é realmente empolgante, mas também pode parecer um pouco estranho se você está acostumado com outras linguagens. Muitos iniciantes tropeçam nos mesmos obstáculos, então aqui estão alguns "pegadinhas" que você vai querer evitar. (Além de algumas dicas amigáveis para contorná-las.)

Nomear Coisas Aleatoriamente

Todos nós já fomos culpados de nomear algo como Test1 ou MyClass apenas para seguir em frente rapidamente. Mas quando seu projeto cresce, esses nomes se tornam um pesadelo.

0
0 35
Artigo Heloisa Paiva · Set. 12, 2025 3m read

Uma coisa que aprendi ao longo dos anos é que, não importa o quão aprimorada seja a lógica do seu aplicativo, o desempenho do banco de dados acabará por determinar o sucesso ou fracasso da experiência do usuário. Trabalhando com o InterSystems IRIS, recentemente vivenciei isso em primeira mão. Um de nossos clientes estava construindo um painel de relatórios que funcionava perfeitamente durante os testes, mas assim que o conjunto de dados de produção cresceu para milhões, os tempos de resposta ficaram extremamente lentos.

0
0 47
Artigo Heloisa Paiva · Set. 11, 2025 1m read

Um benefício de usar o Doxygenerate é que ele faz mais do que um simples output HTML. Altere o arquivo Doxyfile que informa ao Doxygen o que fazer e você poderá facilmente criar um PDF. Nosso exemplo de aplicação MARINA gerou um PDF de 524 páginas. Aqui está a página 94:

Você pode olhar todas as páginas aqui.

No print acima, note que nós só temos detalhes da superclasse que é parte do app (AuditHistory) A superclasse primeira superclasse, %Library.SerialObject é mostrada desbotada e sem detalhes do que o BankDetails herda dela.

0
0 18
Artigo Heloisa Paiva · Set. 9, 2025 3m read

Rubrica InterSystems FAQ

Você pode verificar o espaço em disco a qualquer momento usando a classe utilitária do sistema: SYS.Database e a consulta: FreeSpace.

Aqui está como testar no terminal IRIS (vá para o namespace %SYS e então execute):

zn"%SYS"set stmt=##class(%SQL.Statement).%New()
set st=stmt.%PrepareClassQuery("SYS.Database","FreeSpace")
set rset=stmt.%Execute()
do rset.%Display()

O exemplo de resultado de saída é o seguinte:

0
0 20
Artigo Heloisa Paiva · Set. 6, 2025 1m read

Rubrica InterSystems FAQ

O mirror sincroniza apenas arquivos de banco de dados.

Para sincronizar outros arquivos necessários para sua aplicação (arquivos CSP, imagens, documentos, etc.) entre os dois servidores que compõem o conjunto de espelhamento, siga uma das seguintes abordagens:

  1. Coloque esses arquivos em um disco compartilhado, usando um NAS ou dispositivo similar.
  2. Ou use um software de sincronização de arquivos para sincronizá-los entre os dois servidores.
0
0 20
Artigo Robert Cemper · Set. 5, 2025 4m read

O artigo foi motivado pelo 2025 September Article Bounty
********************************************************

O princípio do Docker é simplesmente convincente para mim.

  • Obtenha uma área restrita onde você pode brincar e tentar o que quiser/precisar fazer.
  • Depois de terminar, você pode descartá-la sem deixar rastros em seu ambiente de trabalho.

Essa foi a base técnica que me permitiu executar cerca de 700 revisões no OEX 
quase sem efeitos colaterais  (exceto aqueles causados por mim mesmo).

Para iniciantes, vou começar com o IRIS puro, sem *health, *ML, *whatever.

0
0 26
Artigo Heloisa Paiva · Ago. 21, 2025 4m read

O artigo do August Article Bounty sobre Global Masters, e um dos tópicos propostos me pareceu bastante interessante para uso futuro em minhas aulas. Então, é isso que eu gostaria de dizer aos meus alunos sobre tabelas no IRIS e como elas se correlacionam com o modelo de objeto.

Primeiro, o InterSystems IRIS possui um modelo de dados unificado. Isso significa que, ao trabalhar com dados, você não está preso a um único paradigma. Os mesmos dados podem ser acessados e manipulados como uma tabela SQL tradicional, como um objeto nativo, ou até mesmo como um array multidimensional (um global). Isso significa que, ao criar uma tabela SQL, o IRIS cria automaticamente uma classe de objeto correspondente. Ao definir uma classe de objeto, o IRIS a torna automaticamente disponível como uma tabela SQL. Os dados em si são armazenados apenas uma vez no eficiente motor de armazenamento multidimensional do IRIS. O motor SQL e o motor de objeto são simplesmente diferentes "lentes" para visualizar e trabalhar com os mesmos dados.

Primeiro, vamos ver a correlação entre o modelo relacional e o modelo de objeto:

Relacional Objeto
Tabela Classe
Coluna Propriedade
Linha Objeto
Chave primária Identificador de objeto

Nem sempre é uma correlação de 1:1, já que você pode ter várias tabelas representando uma classe, por exemplo. Mas é uma regra geral.

1
1 38
Artigo Heloisa Paiva · Set. 4, 2025 2m read

Rubrica InterSystems FAQ

No InterSystems IRIS, você pode criar tabelas vinculadas usando comandos, ao invés de usar o caminho System Explorer > SQL > Wizard > Linked Tables do Portal de Administração:

Para criar uma tabela vinculada, use o método CreateLinkedTable da classe  %SYSTEM.SQL.Schema. Veja a documentação da classe para detalhes.

Para executar, siga os passos:

0
0 19
Anúncio Danusa Calixto · Set. 2, 2025

Tenho o prazer de anunciar o lançamento de tree-sitter-objectscript, uma nova gramática de código aberto para tree-sitters que oferece suporte de primeira classe a ObjectScript para editores modernos. Se você viu a prévia na READY '25, ficará feliz em saber que ela já está disponível no Github:

https://github.com/intersystems/tree-sitter-objectscript

O que ela Fornece?

  • Análise Rápida & Precisa: Uma gramática poderosa para ObjectScript, permitindo análise de sintaxe em tempo real, destaque inteligente e edição estrutural em editores de código modernos.
  • Reconhecimento Poliglota: Arquivos .cls do ObjectScript frequentemente incorporam SQL, HTML, Python, JavaScript, JSON, CSS, XML e Markdown. A gramática foi projetada para se integrar perfeitamente a eles.
  • Suporte a Multi-Editores: Funciona em vários editores atualmente, com outros surgindo conforme a adoção do tree-sitter cresce.

Editores Suportados

Estamos trabalhando com tree-sitter-objectscript e os seguintes editores:

Captura de tela (Zed)

Captura de tela de destaque da sintaxe no Zed

(este é o Zed em Windows com o tema Tokyo Night Storm).


Estamos ansiosos para ver como a comunidade usa isso — feedback e ideias são sempre bem-vindos!

Obrigado!

0
0 22
Artigo Larissa Prussak · Ago. 29, 2025 1m read

InterSystems FAQ rubric

Existem dados, como registros de log de execução, que você pode não querer que voltem ao estado anterior mesmo se ocorrer um rollback durante uma transação.
Esse requisito pode ser atendido colocando esses dados no banco de dados IRISTEMP, que não sofre rollback.

Temporary Globals and the IRISTEMP Database

Ao mapear para esse banco as entidades de tabela que você não deseja que sofram rollback, é possível manter as informações após a reversão.

0
0 16
Artigo Larissa Prussak · Ago. 29, 2025 1m read

Como parte de um projeto técnico recente de documentação para otimizar a busca, precisei usar Embedded Python no meu código ObjectScript.
O principal obstáculo foi passar uma lista do Python, criada em um método de classe Python, para um método ObjectScript.

Enviar a lista por referência para o método Python, preenchê-la com o método Insert(), e retornar a referência para o método ObjectScript resultava em uma lista do tipo %SYS.Python. Esse processo era simples, mas pouco eficiente.

0
0 21