Cristiano Silva · Set. 5, 2022 ir ao artigo

Parabéns pelo artigo Emily.

Uma correção no item 3 o parâmetro CONTENTTYPE está com um erro de digitação: aSpplication quando deveria ser application.

No item 4, por questão de segurança, (em ambiente produtivo ao menos) não é recomendado adicionar o %ALL como função do aplicativo, e sim uma função específica ao que necessário se acessar para que a aplicação funcione.

Cristiano Silva · Out. 24, 2022 ir ao artigo

Olá Rafaela,

Isso você consegue checar no log de auditoria, desde que habilitada e o evento de sistema "Routine Change" esteja ativado:

 

Estando ativo você pode consultar pelo próprio portal na página de do Log de Auditoria:

Se quiser pode também consultar a tabela diretamente um exemplo:

SELECT
  Namespace,
  UserName,
  UTCTimeStamp,
  Description
FROM
  %SYS.Audit
WHEREEvent = 'RoutineChange'

Mais informações acesse a documentação: https://docs.intersystems.com/iris20221/csp/docbook/Doc.View.cls?KEY=AAUDIT

Lembrando: a consulta deve ser executada no namespace %SYS e que a data retornada está no formato UTC como o próprio nome já diz. Para converter a data use o método ConvertUTCtoLocal da classe %UTC

Cristiano Silva · Dez. 6, 2022 ir ao artigo

Olá @Luiz Henrique Carvalho Martarelli 

Você pode sobrescrever o método OnPreDispatch da sua classe que herda de %CSP.REST

O Método OnPréDispatch é executado antes de que o método que conste na regra de roteamento seja executada.

Abaixo um exemplo onde faço o controle de CORS se o método da requisição for OPTION, e checo token de acesso para todos os endpoint exceto para o endpoints ping. 

O parâmetro pContinue quando verdadeiro sinaliza que o método que está na configuração de roteamento deverá ser executado, se falso responde para quem fez a chamada geralmente com algum HTTPStatus que indique o erro.

ClassMethod OnPreDispatch(pUrl As%String, pMethod As%String, ByRef pContinue As%Boolean) As%Status
{
  #Dim%requestAs%CSP.Request     = %request#Dim%responseAs%CSP.Response    = %responseIf (pMethod = "OPTIONS") // Controle de CORS
  {
    Set pContinue = 0//Do..HandleDefaultOptionsRequest(pUrl)
    Do..HandleDefaultCorsRequest(pUrl)
    //Return$System.Status.OK()
  }
  If (pUrl = "/ping")
  { 
    Set pContinue = 1//Return$System.Status.OK()
  }
  #Dim authorization  As%String          = $ZConvert(%request.GetCgiEnv("HTTP_AUTHORIZATION"), "L")
  #Dim token          As%String          = $Piece(authorization, " ", 2)
  #Dim erro           As%DynamicObject   = {"Erro:" : "Token de autorização é obrigatório"}
  If (token = "")
  {
    Set pContinue           = 0Set%response.Status    = ..#HTTP400BADREQUEST
    //Write erro.%ToJSON()
    //Return$System.Status.OK()
  }
  ElseIf (token '= "t0k3n_d3_v4lid@c@0")
  {
    Set erro                = {"Erro": "Token não autorizado!"}
    Set pContinue           = 0Set%response.Status    = ..#HTTP401UNAUTHORIZED
    //Write erro.%ToJSON()
    //Return$System.Status.OK()
  }
  Set pContinue = 1//Return$System.Status.OK()
}
Cristiano Silva · Mar. 22, 2023 ir ao artigo

Olá Juliano.

A forma mais rápida é  via exportação para arquivo CSV e utilizar um dos conectores existentes https://support.google.com/looker-studio/answer/7333350#zippy=%2Cneste-artigo

Desenvolver uma API JSON daí você pode usar um  conector de já existente como por exemplo https://windsor.ai/connect/json-google-data-studio-integration/.

Uma alterna total aderente às suas necessidades é desenvolver seu próprio conector. Não conheço a arquitetura, mas acredito que possa usar JDBC que pode facilitar um pouco. Segue documentação: https://developers.google.com/looker-studio/connector

Cristiano Silva · Jun. 28, 2023 ir ao artigo

Obigado à todos. Foi um grande prazer em participar do concurso. Vamos continuar publicando e fazer a comunidade em Português crescer cada vez mais. 

Cristiano Silva · Out. 3, 2023 ir ao artigo

@Igor Lampa, quando você faz o ALTER TABLE para renomear a tabela, em nível de classe ele vai alterar somente a definição do nome de tabela apontado pela @Danusa Calixto, porém por padrão é definido em "UPPERCASE", porém o SQL do IRIS é "case insensitive". Por ser "case insensitive" não vejo problema em o nome da tab ela estar em qualquer "case" seja.

Pode detalhar por quê da obrigatoriedade de estar em "lowercase"?
 

Cristiano Silva · Out. 11, 2023 ir ao artigo

Olá Igor,

Seu problema é falta de licença como descrito no log de erro:

Mensagem de erro: ERRO #5915: Não foi possível alocar uma licença

A licença da Community Edition permite apenas 5 conexões no máximo.

Faça um teste fechando Portal de Administração, Studio, VSCode ou qualquer outra ferramenta que possa esta conectada IRIS e depois teste seu programa java novamente.

Cristiano Silva · Nov. 4, 2023 ir ao artigo

Olá Flávio.

Conforme a resposta do post em inglês do @Danny Wijnschenk, você pode usar o arquivo .DAT como um backup mas a cópia para garantir a integridade da base deve se feita a frio. Desmontando a base e depois fazendo a cópia. Despois de copiar o arquivo para o local desejado é só criar uma nova base de dados e apontar o caminho para o diretório onde o arquivo está que ele será usado como arquivo de dados. Se for uma base existe, desmonte a base e depois substitua o arquivo .DAT e remonte.

Abraço.

Olá Edilson, você pode fazer o upload de arquivo através de um página CSP, utilizando um input do tipo file e fazendo o submit do arquivo e depois salva a stream no servidor utilizando a classe %File. Abaixo um exemplo, pode ter erro pois não executei.

Class cjs.UlpoadArquivo Extends%CSP.Page
{

ClassMethod OnPage() As%Status
{
  &HTML<
    <formmethod="post"enctype="multipart/form-data"><inputtype="file"name="file" /><inputtype="submit" /></form>
  >Return$System.Status.OK()
}

ClassMethod OnPreHTTP() As%Boolean [ ServerOnly = 1 ]
{
  #Dim%requestAs%CSP.Request = %requestIf (%request.Method = "POST" && %request.GetMimeData("file"))
  {
    #Dim arquivo As%File = ##Class(%File).%New("<caminho/nomeArquivo>")
    #Dim statusCode As%Status = arquivo.Open("NWS")
    If ($System.Status.IsError(statusCode))
    {
      #Dim mensagemErro As%String = $System.Status.GetErrorText(statusCode)
      &HTML<
        <span>Erro ao criar arqvuio #(mesnagemErro)# </span>
      >Return$System.Status.OK()
    }
    Set statuCode = arquivo.CopyForm(%request.GetMimeData("file"))
    If ($System.Status.IsError(statusCode))
    {
      Set mensagemErro = $System.Status.GetErrorText(statusCode)
      &HTML<
        <span>Erro ao salvar arqvuio #(mesnagemErro)# </span>
      >Return$System.Status.OK()
    }
    Do arquivo.Close()
    &HTML<
       <span>Arquivo carregado para o servidor com sucesso.</span>
    >
  }
  Return$System.Status.OK()
}

Olá @Guilherme Silva 

Você deve ter um servidor HTTP, (apache, iis, nginx) com https habilitado e com o webgateway configurado, dessa forma toda a comunicação com IRIS será segura mesmo antes de fornecer o token JWT.
Este artigo demonstra uma configuração https com IIS
HTTP and HTTPS with REST API | InterSystems Developer Community | Contest

Este outro link é um container com apache e letsencript que você pode usar como base
https://github.com/lscalese/isc-webgateway-letsencrypt
 

Olá @Marcelo Witt 

Existe mecanismo de localização no IRIS desde a época do Caché.
Usa-se o conceito de dicionário de mensagens e um conjunto de macros de auxílio no desenvolvimento.
Segue link da documentação:

String Localization and Message Dictionaries (Contents) | InterSystems IRIS Data Platform 2025.2
A respeito da localização da Instalação do IRIS, para controle de formato de datas, moeda, etc existe também a documentção:
Localization in InterSystems IRIS | Orientation Guide for Server-Side Programming | InterSystems IRIS Data Platform 2025.2