Find

Announcement
· Jul 4, 2024

[Vídeo] Presentación de InterSystems Supply Chain Orchestrator

Hola Comunidad, 

Tenéis disponible un nuevo vídeo (en inglés) en el Canal de YouTube de InterSystems:

⏯ Presentación de InterSystems Supply Chain Orchestrator @ Global Summit 2023

Aprended qué contiene InterSystems Supply Chain Orchestrator. Descubrid cómo se puede utilizar para optimizar las cadenas de suministro y proporcionar información prescriptiva procesable. A través de presentaciones y una demostración en vivo de las capacidades clave del producto, aprenderéis por qué acelera el tiempo de creación de valor para la transformación digital de la cadena de suministro.

Ponentes:
🗣 @Ming Zhou, Head of Supply Chain Strategy, InterSystems
🗣 @Annie Tong, Supply Chain Sales Engineer, InterSystems

¡Disfrutadlo y estad atentos a más vídeos! 👍

Discussion (0)1
Log in or sign up to continue
Question
· Jul 3, 2024

Testing XML input to Router Management Portal or via XML document viewer

Trying to test a router that takes an XML input and performs a transform on it.

First attempt I tried to test the transform using the XML Document Viewer via the Ensemble -> Interoperate -> XML Document Viewer menu. The transform itself is working however I can not get the output to save to a file. I've made sure permissions are set correctly on the file. It simply doesn't output anything and I'm at a loss as to why.

As another method I also tried testing via Ensemble -> Test -> Business Hosts. Putting the file path/name as the source does not send any data. Again, I've made sure read permissions are set for the file.

I've been able to test using other methods, so I'm not concerned with actually being able to validate my transform so much as I'm now at a loss as to why the two above methods do not seem to work.

Has anyone else experienced similar issues, particularly with the XML Document Viewer method?

Thanks.

Discussion (0)1
Log in or sign up to continue
Announcement
· Jul 3, 2024

[Video] Introducing InterSystems Supply Chain Orchestrator

Hey Community,

Play the new video on InterSystems Developers YouTube:

⏯ Introducing InterSystems Supply Chain Orchestrator @ Global Summit 2023

Learn what’s inside InterSystems Supply Chain Orchestrator. Discover how it can be used to optimize supply chains and provide prescriptive actionable insights. Via presentations and a live demo of key product capabilities, you'll learn why it accelerates time-to-value for supply chain digital transformation.

Presenters:
🗣 @Ming Zhou, Head of Supply Chain Strategy, InterSystems
🗣 @Annie Tong, Supply Chain Sales Engineer, InterSystems

Enjoy watching and look out for more video content! 👍

Discussion (0)1
Log in or sign up to continue
Question
· Jul 3, 2024

Why does the Rule Editor display a sad face?

Hello,

I have a slight issue that's causing me some inconvenience when using the rule editor within Microsoft Edge (Version 126.0.2592.81).

Whenever I try to load up any ruleset, the ruleset displays an unhappy face like this:

This has only recently started, when opening up the rule editor in another browser e.g. Chrome, the problem disappears.

I've tried to remedy the situation by resetting Edge, Updating Edge Version, Clearing Cache/Cookies etc. but nothing seems to fix it.

I have other colleagues opening the same rule sets in the same version as Edge without any issue, so I do not believe it's an issue with the ruleset itself.

Has anyone else encountered this issue and fixed it?

Thanks.

5 Comments
Discussion (5)3
Log in or sign up to continue
Article
· Jul 3, 2024 10m read

Um portal para administrar armazenamento feito com Django - Parte 1

Nosso objetivo

No último artigo, falamos sobre alguns fatores iniciais do Django. Aprendemos como começar um projeto, garantir que temos todos os requisitos e fazer um CRUD. No entanto, hoje vamos um pouco mais além.

Às vezes precisamos acessar métodos mais complexos, então hoje vamos conectar o IRIS a um ambiente Python, construir algumas funções e exibir seus resultados numa página web. Será similar à última discussão, mas mais adiante para que você possa fazer algo novo, mas não demais para que você se sinta perdido. Nesse projeto, vamos buscar informações sobre as globais em IRIS para rastrear seus tamanhos e entender o custo de cada namespace e tabela em MBs.

 

O Projeto

Cada passo percorrido aqui está disponível no meu Repositório GitHub, no histórico de commits;

Passos iniciais

Vamos repetir alguns passos do último artigo, então essa parte deve soar familiar.

  • Vá ao diretório desejado e digite o comando abaixo.

django-admin startproject globalSize

  • Adicione o arquivo requirements.txt com o texto abaixo e use o comando

pip install -r requirements.txt

para assegurar que seu ambiente tem todos os requisitos.

# Django itself
django>=4.2.1
# InterSystems IRIS driver for Django
django-iris==0.2.2
  • Em globalSize/settings.py, adicione IRIS nas configurações de DATABASES:
DATABASES = {
	‘default’: {
		‘ENGINE’: ‘django_iris’,
		‘NAME’: ‘USER’,
		‘USER’: ‘_system’,
		‘PASSWORD’: ‘SYS’,
		‘HOST’: ‘localhost’,
		‘PORT’: 1972,
	}
}
  • Não se esqueça de adicionar um .girignore e um .editorconfig. Também é conveniente ter um linter de sua preferência, mas está além do escopo desse artigo discutir esse tópico.

 

Criando o app e o modelo

Nós criamos um app e um modelo no último artigo, então essa seção também deve ser familiar, mesmo se tratando de um app e modelo diferentes

  • Para criar o app, digite

python manage.py startapp globals

  • E, globals/models.py, crie um modelo com a informação que deseja exibir sobre suas globais:
class irisGlobal(models.Model):
	database = models.CharField(max_length=40)
	name = models.CharField(max_length=40)
	allocatedsize = models.FloatField()
	size = models.FloatField()


	def __str__(self):
		return self.name
  • Em settings.py, adicione o novo app a INSTALLED_APPS:
INSTALLED_APPS = [
	…,
	‘globals’,
]

 

Definindo URLs e a página de início

Novamente vamos fazer alguns passos muito similares aos do último artigo.

  • Em globalSize/urls.py, importe a função include de django.urls e adicione um novo caminho a globals.urls em urlpatterns.
from django.urls import path, include
urlpatterns = [
    …,
    path(‘globals/’, include(‘globals.urls’)),
]
  • Crie as URLs para o app, adicionando o arquivo globals/urls.py com o texto abaixo.
from django.urls import path
from .views import home
urlpatterns = [
	path(‘’, home),
]
  • Crie a view que importamos no último passo. Em view.py, adicione a função a seguir.
def home(request):
	return render(request, “index.html”)
  • Finalmente, adicione o arquivo globals/templates/index.py e crie a página de início como desejado. Observe o exemplo que segue:
<!DOCTYPE html>
<html>
  <body>
    hello world!
  </body>
</html>

Se você utilizar so comandos abaixo e em seguida entrar no link http://127.0.0.1:8000/globals/ você já deve ter uma página exibindo a frase "hello world".

python manage.py makemigrations
python manage.py migrate
python manage.py runserver


Exibindo as globais nas páginas de admin e inicial

  • Em admin.py, importe o modelo e o registre.
from .models import irisGlobal
admin.site.register(irisGlobal)
  • Importe o modelo em views.py e retorne-o na função.
from .models import irisGlobal
def home(request):
	globals = irisGlobal.objects.all()
	return render(request, “index.html”, {“globals”: globals})
  • Agora podemos acessar as globais no index.html conforme preferência. Veja o exemplo a seguir.
<h3>ID  -  DATABASE          /       GLOBAL       - Size / Allocated</h3>
<ul>
  {% for global in globals %}
  <li>
    {{ global.id }} - {{ global.database }}    {{ global.name  }}  -  {{ global.size  }}  /  {{ global.allocatedsize }}
  </li>
  {% endfor %}
</ul>

 

Recuperando dados

Nesse ponto já temos o projeto pronto para ser carregado com informações. Tem uma boa quantidade de maneiras que isso pode tomar forma, mas eu vou usar a abordagem de Python para aprendermos um nova solução possível para integrar Django e IRIS.
Precisamos de alguns métodos para recuperar todos os dados. Podemos usar o InterSystems IRIS Cloud SQL com o driver DB-API para conectar a instância que queremos analisar, que não precisa ser a mesma a que conectamos o Django.
É uma boa prática organizar essa parte numa nova pasta para podermos tratá-la como um módulo. Para assegurar isso, crie a pasta api em globals, adicione um arquivo vazio __init__.py para que o Python a reconheça como um módulo e comece a escrever o arquivo que contém os métodos. Podemos chamá-lo de methods.py.


 

Crie a conexão

Para conectar nosso ambiente Python ao InterSystems IRIS, devemos seguir alguns passos descritos na seção "ObjectScript em ambiente Python" do artigo anterior Python e IRIS na prática - com exemplos!.

Daqui em diante é simples; importamos iris, passamos o endereço da conexão (a instância IRIS que queremos analisar no seguinte formato: host:port/namespace), um usuário e uma senha ao método iris.connect e criamos um IRIS do Python. Dê uma olhada no código abaixo

import intersystems_iris as iris
from django.db import connection as djangoconnection

# connection by iris
conn_params = djangoconnection.get_connection_params()
conn_params[“namespace”] = “%SYS”
connection = iris.connect(**conn_params)
irisPy = iris.createIRIS(connection)

 

Buscando os diretórios das bases de dados

Já que queremos retornar as dimensões das globais, precisamos (é claro) de suas dimensões, seus nomes e seus endereços, conhecidos como bases de dados.
Vou mostrar uma versão simplificada da função, mas lembre-se que é uma boa prática verificar cada passo e a conexão, disparando uma Exception se algo não corre como esperado.
Exatamente como faríamos em ObjectScript, adicionamos uma declaração SQL para então prepará-la, executá-la e retornar uma lista contendo todos os diretórios das bases de dados no seu conjunto de resultados. Podemos fazer tudo isso de maneira simples com as funções "irisPy.classMethodAlgo()", onde o Algo significa o tipo de elemento que o método deve retornar, e a irisObject.invoke(), com a qual podemos acessar tudo que o irisObject referencia. Analise o exemplo que segue.

def getAllDatabaseDirectories():
    try:
	   # check the connection made in irisPy, and if it is set to %SYS namespace
	   databaseDirectoriesList = []
	   with connection.cursor() as cursor:
		cursor.execute(“SELECT DISTINCT %EXACT(Directory) FROM Config.Databases WHERE SectionHeader = ?”, [“Databases”,],)
		databaseDirectoriesList = [row[0] for row in cursor]

    except Exception as error:
        return str(error)

    return databaseDirectoriesList

A variável statement (declaração) é definida como um objeto gerado pelo método %New da classe %SQL.Statement do IRIS. Então, é possível invocar o método %Prepare do objeto instanciado, com uma string de consulta como um argumento. Em seguida, podemos invocar os métodos %Execute e %Next para fazer a consulta e iterar pelo conjunto de resultados, acrescentando a informação desejada numa lista Python para acessá-la facilmente.
É fácil achar cada diretório das bases de dados na tabela Config.Databases, localizada somente no namespace %SYS de toda instância IRIS. Se quiser dar uma olhada nela pelo Portal de Administração, vai encontrar algumas informações interessantes lá.

 

Buscando todas as globais de uma base de dados

Essa função é bastante similar à anterior. Entretanto, temos uma consulta de classe pronta para usar agora. Outra vez, precisamos de uma declaração SQÇ, para prepararmos a consulta DirectoryList (lista de diretórios) da classe %SYS.GlobalQuery. Então, executamos com um diretório como argumento e retornar uma lista contendo todas as globais daquela base de dados.

def getGlobalsList(databaseDirectory: str):
    try:
        statement = irisPy.classMethodObject("%SQL.Statement", "%New")
        status = statement.invoke("%PrepareClassQuery", "%SYS.GlobalQuery","DirectoryList")

        result = statement.invoke("%Execute", databaseDirectory)

        globalList = []
        while (result.invoke("%Next")!=0):
            globalList.append(result.invoke("%Get", "Name"))

    except Exception as error:
        return str(error)

    return globalList


Buscando as dimensões das globais e seus espaços alocados

Finalmente podemos acessar a informação que queremos. Por sorte, o IRIS tem um método pronto para retornar as dimensões e o espaço alocado se você fornecer os nomes da base de dados e da global.

def getGlobalSize(databaseDirectory: str, globalName: str):
    try:
        globalUsed = iris.IRISReference(0)
        globalAllocated = iris.IRISReference(0)
        status = irisPy.classMethodObject("%GlobalEdit", "GetGlobalSize", databaseDirectory, globalName, globalAllocated, globalUsed, 0)

    except Exception as error:
        return str(error)

    return (globalUsed.getValue(), globalAllocated.getValue())

Dessa vez, precisaremos da função IRISRference(0) do módulo iris para receber os tamanhos da função "GetGlobalSize" por referência. Então, podemos acessar o valor com o método getValue().

 

Mostrando tudo na página inicial

Finalmente podemos utilizar essas funções para exibir os dados na página de início. Já temos um caminho pela informação e a tabela, agora precisamos preenchê-la. Quero criar um botão de atualizar para isso.

Primeiro, adicionamos o link ao index.html.

<body>
  <a href = "{% url 'update' %}">update</a></body>

Adicionamos o link à lista urlpatterns, em urls.py.

Add the link to the urlpatterns list, in urls.py.
from .views import home, update
urlpatterns = [
    path('', home),
    path('update', update, name="update"),
]

Então criamos a view em views.py.

from django.shortcuts import render, redirect
from .api.methods import *
def update(request):
    irisGlobal.objects.all().delete()
    databaseList = getAllDatabaseDirectories()

    for database in databaseList:
        globalList = getGlobalsList(database)

        for glob in globalList:
            used, allocated = getGlobalSize(database, glob)
            irisGlobal.objects.create(database=database, name=glob, size=used, allocatedsize=allocated)

    return redirect(home)

Para essa view, primeiro devemos importar a função redirect do django.shortcuts e os métodos que acabamos de construir. É uma boa ideia deletar qualquer dado remanescente na tabela para que eventualmente as globais deletadas sejam limpas. Já que a contagem de globais provavelmente não é gigante, é melhor fazer dessa maneira do que checar cada registro para ver se a global referenciada foi deletada ou precisa de uma atualização.

Então, buscamos todos os diretórios das bases de dados para que possamos, para cada base, checar todas as globais que existem dentro e, para cda global, teremos seu espaço utilizado e alocado.

Nesse ponto, já temos o modelo Django populado e pronto para retornar dados, então redirecionamos para a view home.
Se você acessar http://127.0.0.1:8000/globals/ e clicar no link de atualização que adicionamos, a página deve recarregar e dentro de alguns segundos exibir a lista e todas as globais, com suas bases de dados, espaços usados e alocados, conforme a imagem que segue.


 

Adicionando agregação

Você ficaria surpreso em saber o quanto é simples adicionar algumas opções rápidas de análise, como soma ou contagem. Não é necessário ser um mestre em Django para criar alguns painéis nessa página e, depois dessa seção, você estará num bom lugar para começar.

Já sabemos que a view home é responsável por renderizar o index. Até agora, geramos a variável "globals", contendo todos os dados e passamos para o index.html. Faremos algo similar, mas com funções de agregação. Criaremos uma variável para cada soma, usaremos os métodos aggregate() e Sum() e os adicionaremos à lista de argumentos no contexto da função de renderização. E, é claro, não podemos esquecer de importar a Sum() do django.db.models. Observe a função abaixo.

def home(request):
	globals = irisGlobal.objects.all()
	sumSize = globals.aggregate(Sum("size"))
	sumAllocated = globals.aggregate(Sum("allocatedsize"))
	return render(request, "index.html", {"globals": globals, "sumSize": sumSize, "sumAllocated":sumAllocated})

Agora podemos adicioná-la ao arquivo index.html e adicionar alguns parágrafos abaixo da lista (elemento <ul>). Dentro desses parágrafos, podemos acessar a conta de todas as globais e as somas, como mostrado abaixo.

<p>showing results for {{globals.count}} globals</p>
  <p>total size: {{sumSize.size__sum}}</p>
  <p>total allocated size: {{sumAllocated.allocatedsize__sum}}</p>
 </body>
</html>

Recarregue a página e você deve ter o seguinte:


 

O fim... quase

Nesse artigo, aprendemos sobre o armazenamento de dados de armazenamento do InterSystems IRIS, como acessá-los pelo Python, construir uma API  e, usando IRIS como um sistema Cloud, rastreá-los e analisá-los facilmente. Podemos ver no horizonte consultas mais complexas, criação de painéis, automatização das atualizações e adicionar um sistema de notificação.

No próximo artigo, darei um passo mais perto desse horizonte, mostrando como filtrar e ordenar os dados antes de exibi-los, adicionar algumas opções de edição do lado do cliente e, por cima de tudo isso, uma pitada de CSS para deixar o projeto charmoso.

Você gostaria de ver algo que ainda não mostrei? Por favor, entre em contato se tiver alguma ideia ou necessidade que gostaria que eu escrevesse sobre.
 

Discussion (0)1
Log in or sign up to continue