O objetivo desta API é auxiliar o desenvolvedor na construção de plugins externos.
Para obter mais exemplos de como construir usando a Intellector API, favor contactar a equipe TOTVS Financial.
Nem preciso explicar que esse framework nasceu da necessidade de padronizar o desenvolvimento dos primeiros plugins de acessos e execuções de políticas, embora essa característica fosse evidente desde o princípio. Na realidade, queríamos "forçar" qualquer desenvolvedor de plugins de acesso para o TOTVS Intellector a seguir o pattern que fosse operacional na chamada da política ao acesso desenvolvido, como exceções lançadas, etc., e tivesse uma luz no fim do túnel, com algumas artifícios que ajudassem, pois quanto problemas e dúvidas melhor. Ele é um framework de abstração para operações como chamadas HTTPS com certificados, as vezes bem complexas, e, acreditem, não é tão trivial lidar com sopa de letrinhas esquisitas. Mas nada de ficar assustado, abaixo veremos cada característica desse framework.
public interface PluginInterface {
/**
* Executa um plugin externo; interface
* <p>
* @param hashIn
* @throws InfraException
* @throws LayoutException
* @throws ConfigException
*/
public HashMap<String, Object> execute( HashMap<String, Object> hashIn)
throws InfraException, LayoutException, ConfigException;
} |
Exceptions throwable - O intellector-api disponibiliza algumas exceções para serem utilizadas pelos plugins de acessos, interpretados e tratados por qualquer política compilada pelo TOTVS Intellector Server, são elas:
Todas as exceções tem overload como no exemplo abaixo, permitindo lançar o throwable da causa junto.
public class CipheringException extends Exception {
/**
* Excecao relativa a problemas de criptografia
* <p>
* @param msg mensagem para ser mostrada pela excecao
*/
public CipheringException(String msg) {
super(msg);
}
/**
* Constrói uma nova exceção especificando a mensagem detalhada e a causa.
* Note que a mensagem detalhada associada a causa não são incorporadas
* automaticamente na mensagem desta exceção.
* <p>
* @param message
* Mensagem detalhada (que é armazenada para posterior obtenção
* pelo método {@link #getMessage()})
* @param cause
* Causa (que é guardada para posterior recuperação pelo método
* {@link #getCause()}) (Um valor nulo é permitida, e indica que
* a causa é inexistente ou desconhecida.)
*/
public CipheringException(String message, Throwable cause) {
super(message, cause);
}
} |
Criar manualmente os arquivos com o layout do plugin externo e outras informações. Um template para a criação desse arquivo se encontra no dummyplugin para facilitar a vida do desenvolvedor e, tenha em mente, ele será validado pelo Intellector IW-Editor.
São dois os arquivos que deverão ser criados para a configuração e geração do plugin (os arquivos de exemplo estão no projeto Eclipse com fontes que são disponibilizados mais abaixo):
JSON
{
"class_name": "br.com.totvs.plugins.dummyplugin.DummyPlugin" ,
"plugin_name": "dummyplugin",
"description":"Descrição do Plugin",
"layout": {
"editable": true,
"in": [
{
"description": "cpf requerente",
"type": "String",
"name": "CPF",
"format": ""
},
{
"description": "Data de Nascimento",
"type": "Date",
"name": "DT_NASC",
"format": "ddMMyyyy"
},
{
"description": "Tem seguro",
"type": "Boolean",
"name": "TEM_SEGURO",
"format": ""
},
{
"description": "Valor do salario",
"type": "Double",
"name": "VAL_SALARIO",
"format": ""
},
{
"description": "Idade do requerente",
"type": "Integer",
"name": "IDADE",
"format": ""
}
],
"out": [
{
"id": "DUMMY",
"counter": 0,
"counter_max": 0,
"register": [
{
"description": "Teste de boolean",
"type": "Boolean",
"name": "BOOLEAN_VALUE",
"format": ""
},
{
"description": "Teste pra tipo Data",
"type": "Date",
"name": "DATE_VALUE",
"format": "ddMMyyyy"
},
{
"description": "Teste pra tipo Double",
"type": "Double",
"name": "DOUBLE_VALUE",
"format": ""
},
{
"description": "Teste pra tipo Integer",
"type": "Integer",
"name": "INTEGER_VALUE",
"format": ""
},
{
"description": "Teste pra tipo String",
"type": "String",
"name": "STRING_VALUE",
"format": ""
}
]
},
{
"id": "D100",
"counter": 0,
"counter_max": 0,
"register": [
{
"description": "Um Nome qualquer",
"type": "String",
"name": "D100_NOME",
"format": ""
},
{
"description": "Uma data de Nascimento",
"type": "Date",
"name": "D100_DTNASCIMENTO",
"format": "ddMMyyyy"
},
{
"description": "Mostra o diretorio",
"type": "String",
"name": "D100_MYDIR",
"format": ""
},
{
"description": "Qualquer string",
"type": "String",
"name": "D100_OUTRO",
"format": ""
}
]
},
{
"id": "D200",
"counter": 2,
"counter_max": 3,
"register": [
{
"description": "Simula String com contador",
"type": "String",
"name": "D200_TIPO_",
"format": ""
},
{
"description": "Simula Date com contador",
"type": "Date",
"name": "D200_DATA_",
"format": "yyyyddMM"
},
{
"description": "Simula String com contador",
"type": "String",
"name": "D200_HORA_",
"format": ""
},
{
"description": "Simula String com contador",
"type": "String",
"name": "D200_MOEDA_",
"format": ""
},
{
"description": "Simula Double com contador",
"type": "Double",
"name": "D200_VALOR_",
"format": ""
}
]
}
]
},
"properties": {
"database": "mango_d",
"usuario": "claudio",
"senha": "mariposa",
"audita": true
}
}
|
POM.XML
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>grouo-id</groupId>
<artifactId>dummyplugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>Dummy para exemplificar plugins externos</description>
<properties>
<!-- nome da package e classe - FQN -->
<main-class>br.com.totvs.plugins.dummyplugin.DummyPlugin</main-class>
<!-- Nome do Plugin de acesso -->
<pluginname>dummyplugin</pluginname>
<description>Dummy para exemplificar plugins externos</description>
<!-- chave de acesso ao dado na persistencia -->
<primarykey>CPF</primarykey>
<pkdescription>CPF do adquirente</pkdescription>
<!-- Caminho para o Layout do Acesso -->
<layoutpath>resources/dummyplugin.json</layoutpath>
<!-- P - plugin / L - lib para plugin -->
<pluginlib>P</pluginlib>
</properties>
<distributionManagement>
<repository>
<id>releases</id>
<url>http://repo.com:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://repo.com:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<targetPath>resources</targetPath>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>false</addClasspath>
<mainClass>${main-class}</mainClass>
</manifest>
<manifestSections>
<manifestSection>
<name>Intellector Entries</name>
<manifestEntries>
<Implementation-Plugin>${pluginname}</Implementation-Plugin>
<Implementation-Layout>${layoutpath}</Implementation-Layout>
<Implementation-Description>${description}</Implementation-Description>
<primarykey>${primarykey}</primarykey>
<pkdescription>${pkdescription}</pkdescription>
<Plugin-Lib>${pluginlib}</Plugin-Lib>
</manifestEntries>
</manifestSection>
</manifestSections>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<!-- Aqui estou forçando um clean toda vez que o maven install for
executado. -->
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<versionRange>[2.5,)</versionRange>
<goals>
<goal>clean</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>iw-server</groupId>
<artifactId>iw-server-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>iw-server</groupId>
<artifactId>iw-server-beans</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project> |
O acesso dummy estará sempre sendo submetido a melhorias, por isso, procure sempre por uma versão atualizada, pois ele terá várias versões, que ao longo do nosso desenvolvimento são taggeds. Talvez exista uma que seja mais adequado a sua necessidade.
Importar o acesso dummy (dummyaccess) como um template para desenvolvimento de um acesso externo. A ideia é que ele oriente o desenvolvimento de toda a estrutura necessária para a criação de um plugin de acesso, mantendo uma padronização na construção destes, evitando que o fonte de cada acesso externo tenha uma forma de implementação completamente diferente dos outros. O objetivo é facilitar desenvolvimento de novos acessos de forma fácil e rápida. Os artefatos que comporão o projeto vazio de um plugin serão:
Exemplo do MANIFEST.MF (nesse caso, um do SERASA):
Manifest-Version: 1.0 Main-Class: br.com.tools.acessos.serasa.SerasaPF Class-Path: . Version-Info: teste-10 Implementation-Vendor: Tools Servicos Implementation-Plugin: serasapf Implementation-Layout: serasapf Implementation-Datadir: serasapf.datadir Implementation-FileList: resources/https.properties, resources/layout_p002.xml, resources/layout_p006.xml, resources/layoutPF_b49c.xml, resources/layoutPJ_b49c.xml, resources/serasa.properties, resources/serasapf.xml, resources/serasapj.xml primarykey: CPF, DTNASCIMENTO, pkdescription: CPF, Data de Nascimento, |
Baixe aqui o template do accessdummy;