Saltar al contenido

Despliegue del Conector

Introducción

Aunque cada conector creado con Harmony Connector SDK será diferente tanto en diseño como en despliegue, hay algunos conceptos básicos que incluyen todos los conectores, cubiertos en Conceptos de SDK de conector en Harmony Connector SDK.

Esta página amplía esos conceptos básicos y cubre los detalles de despliegue de los conectores desarrollados con el Conector SDK.

Si está implementando un conector con la intención de enviarlo para que Jitterbit lo certifique, el código fuente enviado para la certificación debe seguir el estilo de código Java de Jitterbit. Ver los comentarios sobre estilo de código en la sección Ejemplo completo a continuación para ver el archivo de configuración de estilo de verificación que debe usarse.

Conector

Denominación

Al nombrar un conector, no incluya caracteres especiales ni barras diagonales (/) en el nombre. Estos pueden causar problemas cuando el conector se carga en el Agente.

Ver Adaptador JSON para obtener detalles sobre cómo especificar los diferentes nombres utilizados en un conector.

Despliegue

Un conector debe extender el BaseJitterbitConnector interfaz y proporcionar una fábrica que Harmony puede llamada para crear instancias de la misma. La despliegue base incluye los métodos comunes que un conector debe desplegar. (Una alternativa es desplegar el JitterbitConnector interfaz directamente.)

Para indicar que la clase que implementa esta interfaz requerida es la que debe ser considerada como la JitterbitConnector, anótelo con un @Connector anotación y proporcione la clase que implementa su factoría.

(Una alternativa al uso de una anotación es especificar la clase de fábrica en el manifiesto del archivo JAR como el valor delJitterbit-Connector-Factory-Classatributo. Ver Registro del conector para detalles.)

Estas interfaces y sus métodos deben desplegarse:

  • Connection interfaz y su open() y close() métodos
  • ConnectionFactory interfaz y su createConnection(Map<String,String> properties) método

Advertencia

Las variables estáticas no deben usarse en un ambiente de subprocesos múltiples, como un conector. Esto puede llevar a muchos problemas, incluida la corrupción de datos. Por ejemplo, usar y acceder a variables estáticas públicas en una clase de utilidad puede causar problemas:

public class MyConnectorUtils {
  public static String accessToken;
  public static String host;
  ...
}
En su lugar, reemplace estas variables estáticas públicas con variables de instancia privadas y use los métodos get y set para acceder a ellos:

public class MyConnectorUtils {
  private String accessToken;

  public String getAccessToken() {
    return accessToken;
  }

  public String setAccessToken(String accessToken) {
    this.accessToken = accessToken;
  }
  ...
}

Conector de ejemplo

Un ejemplo simple de un conector:

/**
 * Example Connector.
 */
@Connector(factory = ExampleConnector.ExampleConnectorFactory.class)
public class ExampleConnector extends BaseJitterbitConnector {

  public static final ExampleConnector INSTANCE = new ExampleConnector();

  static {
    connectionFactory = ExampleConnectionFactory.INSTANCE;
  }

  @Override
  public ConnectionFactory getConnectionFactory() {
    return connectionFactory;
  }

  @Override
  public String getName() {
    return "ExampleConnector";
  }

  private static ConnectionFactory connectionFactory;

  /**
   * ExampleConnectorFactory.
   */
  public static class ExampleConnectorFactory implements
    JitterbitConnector.Factory {
      @Override
      public JitterbitConnector create() {
        return ExampleConnector.INSTANCE;
      }
  }
}

Fábrica de conexiones

Los conectores se utilizan normalmente para establecer una conexión con un extremo. Para crear esa conexión, para facilitar su configuración, y para probar la conexión, proporcionar una despliegue de un ConnectionFactory. El La conexión estará disponible para las actividades del conector a través del contexto pasado a cada actividad.

Ejemplo de fábrica de conexiones

Un ejemplo simple de una fábrica de conexiones:

/**
* Factory that creates an ExampleConnection instance.
*/
public class ExampleConnectionFactory implements ConnectionFactory {

  public static final ExampleConnectionFactory INSTANCE =
    new ExampleConnectionFactory();

  private ExampleConnectionFactory () {}

  /**
   * Returns a connection to an Example endpoint,
   * created from the specified properties.
   *
   * @param props properties for configuring and
   *              creating an Example connection
   * @return the configured connection
   * @throws RuntimeException if the name or password
   *                          of the specified properties
   *                          are empty or null
   */
  @Override
  public Connection createConnection(Map<String, String> props) {
    String name = props.get("name");
    String password = props.get("password");
    String locale = !props.containsKey("locale") ?
      Locale.getDefault().toString() : "EN_US";
    if (name == null || name.length() == 0) {
      throw new RuntimeException("Name property cannot be empty. " +
        "Specify the name associated with the Example connection.");
    }
    if (password == null || password.length() == 0) {
      throw new RuntimeException("Password cannot be empty. " +
        "Specify the password associated with the Example connection.");
    }
    return new ExampleConnection(name, password, locale);
  }

  /**
   * Returns the pool size configuration.
   *
   * @return the pool size configuration
   */
  @Override
  public PoolSizeConfiguration getPoolSizeConfiguration() {
    return new PoolSizeConfiguration();
  }
}

Conexión

En el ejemplo anterior, la clase ExampleConnection (no se muestra) en realidad crearía la conexión. Es Los requisitos están determinados por el extremo o el servicio particular al que se conecta, cualquier biblioteca que se utilice para esa conexión (como a una base de datos o servicio web), y los detalles de la conexión.

En la interfaz de usuario de Integration Studio, el open() método de la clase que implementa el Connection se llama a la interfaz cuando un el usuario hace clic en el botón Probar de la configuración de la conexión. Esto le da al conector la oportunidad no solo de crear la conexión, sino también para comprobar que la conexión funciona. Por lo general, esto se puede hacer llamando al extremo o servicio y devolver una pequeña carga útil o usar el valor devuelto para validar la conexión.

Como este método se llama cada vez que se abre una conexión a un extremo si no está abierto actualmente, es una buena idea que cualquier prueba sea rápida y pequeña para no retrasar ningún procesamiento posterior.

Un ejemplo de esto se muestra en el DropboxConnection.java del Conector de Dropbox:

  /**
   * Opens a Dropbox version 2 connection.
   */
  public void open() throws ConnectionException {
    if (client != null) {
      return;
    }
    try {
      DbxRequestConfig dbxConfig = new DbxRequestConfig(appKey, locale);
      client = new DbxClientV2(dbxConfig, accessToken);
      ListFolderResult results = client.files().listFolder("");
      System.out.println("Dropbox Connection successful -> app-key: "
        + appKey + ", access-token: " + accessToken);
    } catch (Exception x) {
      x.printStackTrace();
      throw new ConnectionException(Messages.DROPBOX_CODE07,
          Messages.getMessage(Messages.DROPBOX_CODE07_MSG,
            new Object[]{x.getLocalizedMessage()}), x);
    }
  }

Si hay una conexión existente, el método regresa inmediatamente. De lo contrario, se crea una nueva conexión de cliente. dentro de un bloque try-catch. Una vez creado el cliente, se prueba solicitando la lista de objetos en la raíz ("") carpeta. Los resultados devueltos no se verifican realmente, ya que una llamada exitosa es suficiente. si hay un problema con la clave de acceso que proporciona un usuario para crear la conexión, el API de Dropbox. Esto se detectará y luego se volverá a generar con un mensaje de error apropiado para el usuario.

Se pueden usar variaciones de este patrón de diseño según el extremo o el servicio en el que esté funcionando el conector. con.

Actividades

Las actividades que un conector expone e implementa son creadas por clases que implementan JitterbitActivity. A La actividad Jitterbit es una unidad de trabajo con dos funciones:

  • Descubrimiento/configuración: El descubrimiento de metadatos asociados a una actividad y la configuración de su parámetros.
  • Ejecución: Unidad de ejecución que forma parte de una cadena de operaciones.

Aunque el proceso de descubrimiento ocurre primero en la práctica, discutiremos primero el proceso de ejecución aquí, ya que es lo que determina los requisitos del proceso de descubrimiento.

Las actividades se declaran en el archivo de manifiesto como Jitterbit-Activity-* atributos, con ID que se asignan en función sobre el registro del conector con Harmony. (Ver Registro del conector para detalles.)

Cada clase de actividad recibe un @Activity anotación para registrarlo como parte del conector, y debe desplegar un execute() método que se pasa un JitterbitActivity.ExecutionContext.

Durante el tiempo de ejecución, el proceso de operación invocará la actividad llamando a la actividad

execute(ExecutionContext) método.

El contexto de ejecución contiene información sobre la solicitud (si está presente) y la carga útil. la actividad es responsable de establecer la carga útil de respuesta (implementando el JitterbitActivity.ExecutionContext.getResponsePayload() método), que luego será entregado a la siguiente actividad dentro de la cadena de operaciones por el motor de operación del proceso.

Desde el contexto pasado, la actividad tiene su conexión con Harmony. Puede obtener:

  • Los parámetros, si los hubiere, con los que el usuario final configuró la actividad. Por ejemplo, llamando al context.getFunctionParameters().get("folder") método.
  • Las conexiones establecidas en la configuración inicial de la conexión, si el desarrollador las pone a disposición. Por ejemplo, llamando al context.getConnection() método.
  • Parámetros del propio conector, si el desarrollador los pone a disposición.
  • La carga útil de solicitud o respuesta, escrita u obtenida de la conexión.

Los parámetros configurables los establece el usuario final en la interfaz de usuario de Integration Studio y se realizan en la configuración del conector y sus actividades. Se declaran en el adapter.json archivo incluido en el archivo JAR del conector

Las cargas útiles de solicitud o respuesta de una actividad son los datos escritos u obtenidos de la conexión; ellos están determinados por los archivos de esquema XML que definen esas cargas útiles, como se describe en el Siguiente sección.

Solicitud de actividad y respuesta

La solicitud y la respuesta de las actividades de un conector se manejan mediante la API de Java para enlace XML (JAXB, versión 2+) para generar clases Java a partir de esquemas XML. Un archivo de esquema XML independiente (.xsd) se utiliza para cada solicitud o respuesta. El mapeo entre los archivos generados y estas fuentes se da en el sun-jaxb.episode archivo de salida.

Las clases Java generadas pueden luego ser importadas por las clases que implementan la actividad. execute() método.

Por ejemplo, en el conector de Dropbox FetchFileActivity, los datos se transfieren de Dropbox a Harmony. Eso execute() método utiliza un DropboxConnection y la API de Dropbox para recuperar datos y metadatos; luego se establece esos valores en un objeto de respuesta (una instancia de FetchFileResponse), y luego ordena la respuesta a la flujo de salida de carga útil de respuesta.

Por el contrario, en el conector de Dropbox PutFileActivity, los datos se transfieren de Harmony a Dropbox. El

execute() El método en esa clase funciona en la dirección opuesta. Desorganiza un flujo de entrada, utiliza Dropbox API para subir a Dropbox y luego crea un objeto de respuesta (en este caso, una instancia de PutFileResponse) completado con los valores obtenidos de la respuesta de Dropbox.

Cada actividad es responsable de desplegar el getActivityRequestResponseMetadata() método y regreso un ActivityRequestResponseMetaData. Los archivos de esquema XML se utilizan para crear el ActivityRequestResponseMetaData.

Para ayudar a crear ese objeto, una utilidad auxiliar (como se muestra en el conector de Dropbox) DropboxUtils.setRequestResponseSchemas de DropboxUtils.java) está disponible para cargar los archivos de esquema XML y establecer ellos como la solicitud o respuesta.

Luego aparecerán en la interfaz de usuario de Integration Studio en el esquema de datos que se muestra durante el paso final de una actividad. configuración. Si no se desea o no se requiere una respuesta o solicitud, se puede descartar y no hay un árbol de estructura de datos. se integrará en la interfaz de usuario de Integration Studio para ese componente. La actividad Obtener archivo del conector de Dropbox es un ejemplo de esta; solo tiene una estructura de datos de respuesta y no de solicitud.

Si se requiere una solicitud, se puede especificar en el archivo JSON que define la interfaz de usuario de Integration Studio para el conector. al declarar inputRequired para una actividad en el adapter.json para el conector forzará la interfaz de usuario de Integration Studio para generar un error de validación para la operación principal si no hay una transformación de origen antes del uso de la actividad. Por ejemplo, este fragmento de un archivo JSON muestra la definición de la actividad de SAP BAPI como que requiere entrada:

"activities": {
    "bapi": {
        "displayName": "BAPI",
        "inputRequired": true,
        "properties": [
            " . . . "
        ]
    }
}

Consulte Componentes de la interfaz de usuario del SDK del conector para obtener detalles sobre cómo definir el archivo JSON que especifica la nube Interfaz de usuario de estudio.

Descubrimiento y metadatos

Como parte del ciclo de vida de la configuración de una actividad de conector, puede utilizar un proceso de descubrimiento para obtener información necesaria para completar la configuración.

Un ejemplo de esto es obtener un nombre de tabla y de esta selección obtener nombres de campo. Para facilitar esto, una interfaz en el Connector SDK (org.jitterbit.connector.sdk.Discoverable) está disponible para su despliegue.

Cuando se llama a la configuración de una actividad en la interfaz de usuario de Integration Studio, la interfaz getObjectList() se llama al método, lo que permite que conector para crear y devolver una lista de objetos descubiertos que se pueden mostrar en la interfaz de usuario. Después de una selección es realizada por el usuario, esa selección está disponible en la interfaz getActivityRequestResponseMetadata() método a través de la activityFunctionParams parámetro que se pasa.

Ver el ProcessFileActivity del conector de Dropbox para ver un ejemplo de cómo se puede usar el descubrimiento en la creación de metadatos.

Se incluyen más ejemplos en las descripciones de los componentes de la interfaz de usuario de Integration Studio que utilizan metadatos, como se describe en la siguiente sección.

Interfaz de usuario de Integration Studio

El conector y sus actividades se configuran a través de la interfaz de usuario de Integration Studio. La interfaz de usuario de esos configuraciones se especifica en el adapter.json archivo. El nombre de archivo real del archivo JSON se puede cambiar de ese valor predeterminado; se especifica en el manifiesto del archivo JAR.

El archivo especifica la interfaz de usuario para el conector y todas sus actividades. Los detalles del archivo JSON están cubiertos en Componentes de la interfaz de usuario del SDK del conector.

Los componentes se clasifican como componentes básicos o complejos.

  • Componentes básicos no interactúan con el conector. Se utilizan simplemente para recibir un valor del usuario y devolverlo al conector.
  • Componentes complejos son más sofisticados e involucran múltiples métodos y código adicional en el conector para desplegar su proceso de descubrimiento y usarlo en la ejecución. Están destinados a resolver desafíos de interfaz de usuario de conector más difíciles.

Tenga en cuenta que el name utilizado en el archivo JSON debe ser el mismo nombre con el que está registrado el conector y que se define en el código Java. Consulte Registro del conector para detalles.

Manifiesto

Estos diversos componentes (información de registro para el conector y cada actividad, clases, externo classpath, nombre de archivo de la interfaz de usuario del conector) están vinculados en el MANIFEST.MF que se incluye en el archivo JAR que archiva el conector. Los detalles del registro y el manifiesto están cubiertos en Registro del conector.

Construcción del conector

Como es habitual en un proyecto Java de esta complejidad, un Maven pom.xml El archivo es esencial para vincular correctamente todos Dependencias importadas y todos los componentes juntos. Al ejecutar la compilación, primero deberá compilar el Archivos XML Schema antes de la compilación y empaquetado de Java. El comando Maven apropiado es:

$ mvn jaxb2:xjc compile install

Instalando

A diferencia de los complementos de Harmony (que se instalan cargándolos en Harmony y permitiendo que plataforma para instalarlos asociando los complementos con un Grupo de Agentes), conectores Harmony creados con el SDK se instala colocando manualmente sus archivos JAR en el directorio apropiado de un Agente Privado. Si el conector se va a utilizar en un Grupo de Agentes con más de un agente, los archivos JAR deben copiarse en cada privado Agente Si el conector depende de bibliotecas específicas que no están incluidas en sus archivos JAR, deben ser instalado en el classpath de cada Agente Privado para que se pueda acceder a ellos en el momento que el conector es cargada por el agente.

Al desarrollar un conector, si se ejecuta en Linux o macOS, recomendamos usar un Docker Agente Privado, ya que puede ser configurado para montar como un volumen local para el agente el directorio de compilación del conector. Para Windows, un Windows Se puede utilizar un Agente Privado.

El directorio del conector es escaneado automáticamente por el agente en busca de cambios, y cualquier conector modificado es se vuelve a cargar automáticamente, sin necesidad de que el agente se reinicie o solicite. Esto acelera y simplifica la proceso de desarrollo. Tenga en cuenta que no debe compilar directamente en este directorio, ya que los productos de compilación intermedios puede confundir al agente.

Ubicaciones de los conectores

Agente Ruta del directorio del conector (predeterminado)
Agente Privado de Windows C:\Program Files (x86)\Jitterbit Agent\Connectors\
Agente Privado de Linux /opt/jitterbit/Connectors/
Agente Privado de Docker /opt/jitterbit/Connectors/
Este directorio generalmente se asigna a un directorio externo en el comando que inicia la imagen de Docker

Sincronizando

Los conectores públicos (conectores publicados por Jitterbit) se sincronizan automáticamente con un agente de Harmony según sea necesario. Para prevenir la sincronización de conectores públicos, una variable de ambiente (SKIP_SYNC_CONNECTORS) está disponible que controla sincronizando Establezca esta variable de ambiente en el shell que ejecuta el agente y reinicie el agente.

Configuración SKIP_SYNC_CONNECTORS a un asterisco detendrá la sincronización de todos los conectores públicos:

SKIP_SYNC_CONNECTORS=*

Configuración SKIP_SYNC_CONNECTORS a una lista de conectores separados por comas detendrá la sincronización de todos los conectores excepto los enumerados:

SKIP_SYNC_CONNECTORS=Box,Magento

Este último ejemplo detendrá la sincronización de todos los conectores públicos excepto los conectores Box y Magento, que se sincronizará.

Ejemplo completo

El conector de Dropbox es un ejemplo de trabajo completo de estos conceptos. Consúltelo para obtener detalles adicionales.

Si desea personalizar el conector de Dropbox en su propio conector usando su propio paquete y dominio, debería necesita actualizar, además de los nombres de los paquetes, las rutas, el contenido del código Java y el registro de su conector: estos elementos:

  • pom.xml: Reemplace el uso de Jitterbit con su propio dominio según corresponda; actualizar el nombre del artefacto y versión
  • MANIFEST.MF: Reemplace el uso de Jitterbit con su propio nombre según corresponda; actualizar las claves y las identificaciones
  • DropboxConstants.java: Actualice el espacio de nombres junto con los archivos XML Schema XSD; actualizar el nombre del conector
  • Archivos XML Schema XSD: Actualice el espacio de nombres de destino, junto con el DropboxConstants.java
  • adapter.json y BaseJitterbitConnector: El campo de nombre del adapter.json y el nombre que anota el extensión de clase BaseJitterbitConnector se utilizan para nombrar el conector. Si se especifica en el adapter.json, el framework usará ese nombre; de lo contrario, se utilizará el nombre proporcionado en la anotación. Ver DropboxConstants.java y DropboxConnector.java para ver ejemplos de cómo sucede esto.

Estilo de Código

El conector de Dropbox ha sido formateado siguiendo el de Jitterbit Estilo de código Java. Este estilo debe seguirse para cualquier código que se envíe a Jitterbit como parte del certificación de un conector.

Para desplegar este estilo en su código fuente:

  • incluye en tu código fuente el Jitterbit checkstyle.xml archivo; y
  • incluir en su pom.xml presentar una referencia a la maven-checkstyle-plugin y eso checkstyle.xml archivo. Agregar a la <plugins> del <build> sección de la pom.xml:
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>2.17</version>
      <executions>
        <execution>
          <id>validate</id>
          <phase>process-test-classes</phase>
          <configuration>
            <configLocation>checkstyle.xml</configLocation>
            <suppressionsLocation>suppressions.xml</suppressionsLocation>
            <encoding>UTF-8</encoding>
            <consoleOutput>true</consoleOutput>
            <failsOnError>true</failsOnError>
            <includeTestSourceDirectory>true</includeTestSourceDirectory>
          </configuration>
          <goals>
            <goal>check</goal>
          </goals>
        </execution>
      </executions>
      <dependencies>
        <dependency>
          <groupId>com.puppycrawl.tools</groupId>
          <artifactId>checkstyle</artifactId>
          <version>6.19</version>
        </dependency>
      </dependencies>
    </plugin>
    

Referirse a Conector de Dropbox pom.xml para ver un ejemplo del uso de este estilo de verificación en un proyecto.