Conector IrisSAP
Olá, comunidade!
Vocês já precisaram conectar o IRIS a um sistema SAP?
Tive que enfrentar o desafio de conectar o InterSystems IRIS ao SAP e, novamente, verifiquei o trabalho de concessão feito pela InterSystems relacionado à possibilidade de executar código nativo em Python dentro do IRIS.
Esse recurso facilitou muito a integração graças à biblioteca pyrfc.
Com essa biblioteca, consegui fazer chamadas a uma RFC (Chamada de Função Remota) do SAP a partir de uma classe do IRIS, além de receber dados do banco de dados do SAP.
Mas o que é uma RFC?
A RFC é um protocolo de comunicação usado pelo SAP. Ele permite a interação entre diferentes sistemas, SAP ou não. Ele também permite que aplicativos externos se comuniquem com o sistema SAP e acessem as funções e os dados disponíveis nesse sistema.
Quando uma RFC é realizada, um aplicativo externo envia uma solicitação pela rede ao sistema SAP. O sistema SAP recebe e processa a solicitação, retornando os resultados ou dados solicitados ao aplicativo externo.
A RFC é usada para várias tarefas, como integração de sistema, transferência de dados, execução de programa e recuperação de informações do SAP.
Resumindo, uma RFC no SAP é uma chamada remota a uma função ou um serviço disponível em um sistema SAP que permite a comunicação e a troca de dados entre esse sistema e aplicativos ou sistemas externos.
Objetivo do artigo:
Decidi escrever este artigo para descrever as etapas que segui e o resultado que obtive caso isso possa ajudar alguém a evitar o esforço.
Também decidi publicar um aplicativo no OpenExchange (link) com quase tudo o que é necessário para iniciar o Docker e conectar.
Por que eu disse quase tudo? Para conectar ao servidor SAP, precisamos baixar o SDK SAP NetWeaver RFC. Infelizmente, ele é protegido por direitos autorais, então não posso compartilhar os arquivos com você. Por isso, se você quiser baixar esse software da página do SAP, precisa ter um usuário do tipo "S".
O aplicativo do OpenExchange está pronto para baixar o SDK, adicionar alguns arquivos a ele, configurar os arquivos de conexão do SAP e executar.
Você tem interesse? Bom, vamos lá!
Etapas para baixar o SDK SAP NetWeaver RFC:
Depois de conseguir o usuário "S" (caso não tenha um usuário "S", peça para o Administrador do seu sistema SAP fornecer um a você), é preciso seguir este link.
Clique no link com as instruções para baixar:
Depois, clique no link para baixar os arquivos:
Por fim, clique em "SAP NW RFC SDK 7.50"
Selecione a versão Linux X86_64 Bit (se você planeja usar meu aplicativo do OpenExchange no Docker) e clique no botão de download:
Adicionando os arquivos do SDK SAP NetWeaver RFC ao projeto:
Depois de baixar e descompactar o arquivo, é necessário copiar o conteúdo da pasta "nwrfcsdk" para a pasta "nwrfcsdk" do projeto:
Explicação dos arquivos auxiliares e Dockerfile:
O arquivo "nwrfcsdk.conf" precisa conter o caminho em que os arquivos do SDK serão copiados. Se você não pretende mudar o caminho no Dockerfile, não é preciso modificar esse arquivo.
O Dockerfile já inclui a instalação das bibliotecas necessárias para fazer a conexão:
O que ele faz é copiar o arquivo "nwrfcsdk.conf", o conteúdo da pasta "nwrfcsdk" e o arquivo sapnwrfc.cfg (vou explicar esse arquivo depois) dentro do Docker.
Agora, é hora de instalar as bibliotecas do Python:
Configurando a conexão do servidor SAP:
Para conectá-lo ao servidor SAP, você precisa adicionar as informações necessárias ao arquivo "sapnwrfc.cfg".
Se você não tiver essas informações, mas conseguir entrar no servidor SAP, basta seguir as etapas mencionadas abaixo para descobrir. Se você não tem acesso a um servidor SAP, peça para o Administrador do servidor SAP compartilhar essas informações com você.
Obtendo os dados de conexão do servidor SAP:
As capturas de tela podem variar um pouco dependendo se você estiver usando a SAP GUI (usuários do Windows) ou a SAP GUI para JAVA (usuários do macOS e Linux). No meu caso, é a SAP GUI para JAVA
1 - Insira a SAP GUI e selecione seu Servidor. Depois, clique no botão Connect:
2 - Insira seu nome de usuário e senha do SAP e pressione Enter ou clique no botão para aceitar:
3 - Depois de entrar, acesse a barra de menu e selecione "System". Em seguida, selecione a opção "Status" no menu suspenso:
Nessa janela, você pode obter o seguinte:
Se você tiver problemas com a conexão, verifique com o Administrador do sistema SAP se o usuário que você definiu no arquivo de configuração tem as permissões para executar a RFC.
Depois de seguir essas etapas, estamos prontos para começar!
Verificando a conexão com o SAP
Para verificar a conexão do SAP, você pode executar o método TestConnection localizado na classe RFC.RFCUtil.cls
ClassMethod TestConnection() [ Language = python ]
{
try:
# Import python libraries
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
from configparser import ConfigParser
# Connect to the SAP Server
config = ConfigParser()
config.read('/opt/irisapp/sapnwrfc.cfg')
params_connection = config._sections['connection']
conn = Connection(**params_connection)
# Launch RFC call to STFC_CONNECTION
result = conn.call('STFC_CONNECTION', REQUTEXT=u'Hello SAP!')
# Close the connection
conn.close()
# Print the result
print(result)
except Exception as e:
print(e)
}
Se tudo der certo, você verá algo assim no console de depuração:
(Se você receber um erro, verifique se a configuração que você escreveu no arquivo de configuração "sapnwrfc.cfg" está correta. )
Como você pode ver, é fácil chamar uma RFC:
1 - Conecte-se ao servidor SAP
2 - Execute o método conn.call(‘name_RFC_to_execute’, RFC_parameters)
3 - Encerre a conexão
4 - Processe o resultado.
Nesse exemplo, o único parâmetro admitido é uma String, e a enviamos como um parâmetro REQUTEXT.
Consulte os dados em uma tabela SAP
Agora vamos chamar "RFC_READ_TABLE", que permite a leitura de uma tabela SAP.
Neste exemplo, vamos ler todos os dados de uma tabela:
ClassMethod GetDataTableSFLIGHT() [ Language = python ]
{
try:
# Import python libraries
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
from configparser import ConfigParser
# Connect to the SAP Server
config = ConfigParser()
config.read('/opt/irisapp/sapnwrfc.cfg')
params_connection = config._sections['connection']
conn = Connection(**params_connection)
# Define query parameters
params = {
'QUERY_TABLE': 'SFLIGHT',
'DELIMITER': ',',
'FIELDS': [
{'FIELDNAME': 'CARRID'},
{'FIELDNAME': 'CONNID'},
{'FIELDNAME': 'FLDATE'},
{'FIELDNAME': 'PRICE'}
],
'OPTIONS': [],
}
# Call to función RFC 'RFC_READ_TABLE'
result = conn.call('RFC_READ_TABLE', **params)
# Process results
if 'DATA' in result:
data = result['DATA']
fields = result['FIELDS']
# Imprime los nombres de campo
for field in fields:
print(field['FIELDNAME'], end='\t')
print()
# Imprime los datos
for entry in data:
values = entry['WA'].split(',')
for value in values:
print(value, end='\t')
print()
else:
print('No data found.')
# Close SAP connection
conn.close()
except CommunicationError:
print("Could not connect to server.")
raise
except LogonError:
print("Could not log in. Wrong credentials?")
raise
except (ABAPApplicationError, ABAPRuntimeError):
print("An error occurred.")
raise
except Exception as e:
print(e)
}
Para esse exemplo, estamos transmitindo um tipo de estrutura como parâmetro com os seguintes dados:
QUERY_TABLE:é o nome da tabela que queremos consultar (SFLIGHT, uma tabela padrão de voos)
DELIMITER: permite selecionar o separador.
FIELDS: são as colunas da tabela que queremos obter. Nesse caso, estou solicitando CARRID (ID da empresa), CONNID (ID do voo de conexão), FLDATE (data do voo) e PRICE (preço do voo).
Depois de executado, podemos processar a resposta e a imprimir na tela ou fazer o que quisermos com as informações... xD.
Por fim, encerramos a conexão.
Se tudo der certo, você verá algo assim no console de depuração:
Consultando dados de uma tabela ao filtrar por um campo:
Um exemplo um pouco mais complexo seria consultar a tabela de clientes para obter os dados de um cliente.
ClassMethod GetDataCustomer(clientSapID As%String) [ Language = python ]
{
try:
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
from configparser import ConfigParser
config = ConfigParser()
config.read('/opt/irisapp/sapnwrfc.cfg')
params_connection = config._sections['connection']
conn = Connection(**params_connection)
# Define the parameters
params = {
'QUERY_TABLE': 'KNA1',
'DELIMITER': ',',
'FIELDS': [{'FIELDNAME': 'KUNNR'}, {'FIELDNAME': 'SORTL'}, {'FIELDNAME': 'TELF1'}],
'OPTIONS': [{'TEXT': "KUNNR = '" + clientSapID + "'"}],
}
# Call the RFC 'RFC_READ_TABLE' to obtain the data
result = conn.call('RFC_READ_TABLE', **params)
# Process the result
if 'DATA' in result:
data = result['DATA']
fields = result['FIELDS']
# Print the fields names
for field in fields:
print(field['FIELDNAME'], end='\t')
print()
# Print the data fields.
for entry in data:
values = entry['WA'].split(',')
for value in values:
print(value, end='\t')
print()
else:
print('No data found.')
# Close the connection
conn.close()
except CommunicationError:
print("Could not connect to server.")
raise
except LogonError:
print("Could not log in. Wrong credentials?")
raise
except (ABAPApplicationError, ABAPRuntimeError):
print("An error occurred.")
raise
except Exception as e:
print(e)
}
Parâmetros:
QUERY_TABLE: é o nome da tabela que queremos consultar (KNA1 é a tabela de clientes no SAP)
DELIMITER: permite selecione o separador.
FIELDS: são as colunas da tabela que queremos obter. Nesse caso, estou solicitando KUNNR (ID do cliente SAP), SORTL (nome curto do cliente) e TELF1 (número de telefone do cliente).
OPTIONS: é um filtro que queremos aplicar à consulta. Nesse caso, estamos filtrando pelo ID do cliente que é recebido no método pelo parâmetro.
Depois de executado, podemos processar a resposta e a imprimir na tela ou fazer o que quisermos com isso... xD
Por fim, encerre a conexão.
Se tudo der certo, você verá algo assim:
Esse é só o começo, porque, com as chamadas RFC, podemos realizar as operações Create, Read, Update e Delete, além de executar qualquer código SAP (personalizado ou padrão) exposto por uma RFC, programas, funções de módulo etc. A RFC é usada para ler e escrever dados, além de iniciar programas ou funções.
Espero que, se você precisar lidar algum dia com qualquer integração entre a InterSystems e o SAP, este artigo seja útil.
Se você tiver quaisquer dúvidas, escreva um comentário e tentarei ajudar.
Muito obrigada por ler!
Link para o aplicativo no OpenExchange: https://openexchange.intersystems.com/package/IrisSapConnector
Link para o repositório: https://github.com/daniel-aguilar-garcia/IrisSapConnector/blob/main/sapnwrfc.cfg
Link para a biblioteca pyrfc: https://sap.github.io/PyRFC/