¿Cómo aprovechar los complementos de código abierto? Desarrolle interfaces de datos de manera rápida y eficiente para conectar diferentes sistemas de aplicaciones

contenido

Introducción:

Complemento de código abierto Tapdata PDK

Acceso rápido a la base de datos de destino

Preparar el ambiente

Descarga el código fuente y compila

Crear un proyecto de conector para la base de datos de destino

Pruebe y verifique a través de TDD después de que se complete el desarrollo

Cómo enviar al proyecto de código abierto PDK

huevos de Pascua


Introducción:

No es exagerado decir que no hay ningún desarrollador que aún no haya golpeado la placa de hierro de la "no interoperabilidad de los datos de la aplicación" - en el caso de diferentes plataformas, diferentes tecnologías, diferentes métodos de almacenamiento e implementación, y la falta de los necesarios interfaces, los sistemas de aplicación son diferentes Difícil de comunicar. Con la expansión continua de los requisitos comerciales, las aplicaciones se desarrollan constantemente hacia la diversificación y la personalización. La contradicción entre los negocios futuros y las pilas de tecnología obsoleta también se está volviendo cada vez más prominente, y la cantidad de interfaces requeridas también está aumentando.

Cómo hacer que el desarrollo de la interfaz sea simple y rápido se ha convertido en un problema que debemos considerar. Recientemente, desenterré un complemento de código abierto muy fragante. Después de estudiar detenidamente la documentación técnica, decidí ofrecerte Amway:

Complemento de código abierto Tapdata PDK

Enlace GitHub: https://github.com/tapdata/idaas-pdk

El editor de este proyecto es Tapdata, un equipo empresarial nacional que se especializa en plataformas de servicios de datos en tiempo real. Según los funcionarios, este componente de código abierto es también el trampolín para el código abierto de sus productos principales. Está respaldado por el equipo real -Sincronización de datos de tiempo Una fortaleza bastante madura.

PDK es un marco de desarrollo de complementos de código abierto abstraído de su tecnología de interfaz de datos.A través de la interfaz del complemento de origen o la interfaz del complemento de destino, la adaptación y compatibilidad de la nueva base de datos como fuente o destino de Tapdata se puede realizar rápidamente, de modo que el  producto Tapdata  Cloud y el próximo código abierto se pueden realizar rápidamente Tapdata varias fuentes de datos heterogéneas a bases de datos o plataformas de destino.

De acuerdo con la especificación de desarrollo del conector PDK, el desarrollo de la fuente y el destino de los datos puede simplificar el proceso de desarrollo del enlace de datos. A través de una planificación de desarrollo detallada y una prueba TDD incorporada, el desarrollo de una nueva fuente y destino de datos se puede completar de manera simple y rápida. .

Los tipos de apoyo incluyen:

  • Base de datos de acceso:  MySQL, Oracle, PostgreSQL, etc.
  • Acceda a productos  SaaS  :  Salesforce, vika table, gold data form, Zoho CRM, etc.
  • Acceso a fuentes de datos personalizadas:  puede conectarse a fuentes de datos de protocolos privados

Acceso rápido a la base de datos de destino

En la actualidad, el equipo de PDK ha hecho públicos los documentos técnicos y puede visitar GitHub ( https://github.com/tapdata/idaas-pdk)  para obtener más detalles.

Preparar el ambiente

  • Java 8
  • Experto
  • Git
  • IDEA IntelliJ

Descarga el código fuente y compila

git clone https://github.com/tapdata/idaas-pdk.git

cd idaas-pdk

mvn clean install

Crear un proyecto de conector para la base de datos de destino

Por ejemplo, el grupo es io.tapdata, el nombre de la base de datos es XDB y la versión de la versión es 0.0.1.Cree un proyecto Connector con el siguiente comando

  • Cuando la base de datos de destino no necesita crear una tabla

./bin/tap template --type target --group io.tapdata --name XDB --version 0.0.1 --output ./connectors

Abra idaas-pdk con ItelliJ IDEA y podrá ver el proyecto xdb-connector en idaas-pdk/connectors.

  • Complete configOptions en spec.json

Una vez que configOptions se integra en el sitio de Tapdata, configura los elementos de entrada para el usuario cuando usa el conector, como la dirección de conexión de la base de datos, el nombre de usuario, la contraseña, etc.

{

   ...

   "configOptions":{

      "connection":{

         "type":"object",

         "properties":{

            "host":{

               "type": "string",

               "title": "Host",

               "x-decorator": "FormItem",

               "x-component": "Input"

            }, 

            "port":{

               "type": "number",

               "title": "Port",

               "x-decorator": "FormItem",

               "x-component": "Input"

            }

            

         }

      }

   }

}
  • Escriba el código para acceder a la base de datos de destino
@TapConnectorClass("spec.json")

public class XDBConnector extends ConnectorBase implements TapConnector {

 @Override

    public void discoverSchema(TapConnectionContext connectionContext, Consumer<List<TapTable>> consumer) {

        //TODO Load tables from database, connection information in connectionContext#getConnectionConfig

        //Sample code shows how to define tables.

        consumer.accept(list(

                //Define first table

                table("empty-table1"),

                //Define second table

                table("empty-table2"))

        ));

    }


 @Override

    public void connectionTest(TapConnectionContext connectionContext, Consumer<TestItem> consumer) {

        //Assume below tests are successfully, below tests are recommended, but not required.

        //Connection test

        //TODO execute connection test here

        consumer.accept(testItem(TestItem.ITEM_CONNECTION, TestItem.RESULT_SUCCESSFULLY));

        //Login test

        //TODO execute login test here

        consumer.accept(testItem(TestItem.ITEM_LOGIN, TestItem.RESULT_SUCCESSFULLY));

        //Read test

        //TODO execute read test by checking role permission

        consumer.accept(testItem(TestItem.ITEM_READ, TestItem.RESULT_SUCCESSFULLY));

        //Write test

        //TODO execute write test by checking role permission

        consumer.accept(testItem(TestItem.ITEM_WRITE, TestItem.RESULT_SUCCESSFULLY));

    }


 private void writeRecord(TapConnectorContext connectorContext, List<TapRecordEvent> tapRecordEvents, Consumer<WriteListResult<TapRecordEvent>> writeListResultConsumer) {

        //TODO write records into database

        //Below is sample code to print received events which suppose to write to database.

        AtomicLong inserted = new AtomicLong(0); //insert count

        AtomicLong updated = new AtomicLong(0); //update count

        AtomicLong deleted = new AtomicLong(0); //delete count

        for(TapRecordEvent recordEvent : tapRecordEvents) {

            if(recordEvent instanceof TapInsertRecordEvent) {

                //TODO insert record

                inserted.incrementAndGet();

            } else if(recordEvent instanceof TapUpdateRecordEvent) {

                //TODO update record

                updated.incrementAndGet();

            } else if(recordEvent instanceof TapDeleteRecordEvent) {

                //TODO delete record

                deleted.incrementAndGet();

            }

        }

        //Need to tell incremental engine the write result

        writeListResultConsumer.accept(writeListResult()

                .insertedCount(inserted.get())

                .modifiedCount(updated.get())

                .removedCount(deleted.get()));

    }

 private void queryByFilter(TapConnectorContext connectorContext, List<TapFilter> filters, Consumer<List<FilterResult>> listConsumer){

        //Filter is exactly match.

        //If query by the filter, no value is in database, please still create a FitlerResult with null value in it. So that flow engine can understand the filter has no value.

    }

}
  • Cuando la base de datos de destino necesita crear una tabla

./bin/tap template --type targetNeedTable --group io.tapdata --name XDB --version 0.0.1 --output ./connectors

Abra idaas-pdk con ItelliJ IDEA y podrá ver el proyecto xdb-connector en idaas-pdk/connectors.

  • Complete configOptions en spec.json

Después de que configOptions esté integrado en el sitio de Tapdata, configure los elementos de entrada para el usuario cuando utilice el conector, como la dirección de conexión de la base de datos, el nombre de usuario, la contraseña, etc.

{
   ...

   "configOptions":{

      "connection":{

         "type":"object",

         "properties":{

            "host":{

               "type": "string",

               "title": "Host",

               "x-decorator": "FormItem",

               "x-component": "Input"

            }, 

            "port":{

               "type": "number",

               "title": "Port",

               "x-decorator": "FormItem",

               "x-component": "Input"

            }     
         }
      }
   }
}
  • Complete dataTypes (expresión de tipo) en spec.json

dataTypes se utiliza para describir el rango de todos los campos a los que este conector accede a la base de datos y los convierte al TapType correspondiente. La base de datos de origen también proporcionará la misma descripción de tipos de datos, por lo que cuando los datos de origen fluyan a Tapdata, combinará la información de descripción de campo de los tipos de datos de origen con la información de campo de la tabla de la base de datos de origen e ingresará a Tapdata a través de la estructura de datos neutral de Tapdata En el flujo de datos, antes de que los datos fluyan a la base de datos de destino, Tapdata encontrará el mejor campo de almacenamiento en los tipos de datos de la biblioteca de destino en función de esta información e informará al desarrollador de PDK a través del tipo de origen de TapField para construir la tabla. .

{

   ...

   "dataTypes":{

      "boolean":{"bit":8, "unsigned":"", "to":"TapNumber"},

      "tinyint":{"bit":8, "to":"TapNumber"},

      "smallint":{"bit":16, "to":"TapNumber"},

      "int":{"bit":32, "to":"TapNumber"},

      "bigint":{"bit":64, "to":"TapNumber"},

      "largeint":{"bit":128, "to":"TapNumber"},

      "float":{"bit":32, "to":"TapNumber"},

      "double":{"bit":64, "to":"TapNumber"},

      "decimal[($precision,$scale)]":{"bit": 128, "precision": [1, 27], "defaultPrecision": 10, "scale": [0, 9], "defaultScale": 0, "to": "TapNumber"},

      "date":{"byte":3, "range":["0000-01-01", "9999-12-31"], "to":"TapDate"},

      "datetime":{"byte":8, "range":["0000-01-01 00:00:00","9999-12-31 23:59:59"],"to":"TapDateTime"},

      "char[($byte)]":{"byte":255, "to": "TapString", "defaultByte": 1},

      "varchar[($byte)]":{"byte":"65535", "to":"TapString"},

      "string":{"byte":"2147483643", "to":"TapString"},

      "HLL":{"byte":"16385", "to":"TapNumber", "queryOnly":true}

   }

}
  • Escriba el código para acceder a la base de datos de destino
 @TapConnectorClass("spec.json")

public class XDBConnector extends ConnectorBase implements TapConnector {
 @Override

 public void discoverSchema(TapConnectionContext connectionContext, Consumer<List<TapTable>> consumer) {
 //TODO Load schema from database, connection information in connectionContext#getConnectionConfig
 //Sample code shows how to define tables with specified fields
 consumer.accept(list(
 //Define first table
 table("empty-table1")
 //Define a field named "id", origin field type, whether is primary key and primary key position

 .add(field("id", "varchar").isPrimaryKey(true).partitionKeyPos(1))

 .add(field("description", "string"))

 .add(field("name", "varchar"))

 .add(field("age", "int")))

 ));

 }

 @Override

 public void connectionTest(TapConnectionContext connectionContext, Consumer<TestItem> consumer) {

 //Assume below tests are successfully, below tests are recommended, but not required.
 //Connection test
 //TODO execute connection test here
 consumer.accept(testItem(TestItem.ITEM_CONNECTION, TestItem.RESULT_SUCCESSFULLY));
 //Login test

 //TODO execute login test here

 consumer.accept(testItem(TestItem.ITEM_LOGIN, TestItem.RESULT_SUCCESSFULLY));

 //Read test

 //TODO execute read test by checking role permission
 consumer.accept(testItem(TestItem.ITEM_READ, TestItem.RESULT_SUCCESSFULLY));

 //Write test
 //TODO execute write test by checking role permission
 consumer.accept(testItem(TestItem.ITEM_WRITE, TestItem.RESULT_SUCCESSFULLY));

 }

 @Override

 public void registerCapabilities(ConnectorFunctions connectorFunctions, TapCodecRegistry codecRegistry) {

 connectorFunctions.supportWriteRecord(this::writeRecord);
 connectorFunctions.supportQueryByFilter(this::queryByFilter);

 //If database need insert record before table created, then please implement the below two methods.
 connectorFunctions.supportCreateTable(this::createTable);
 connectorFunctions.supportDropTable(this::dropTable);

 //If database need insert record before table created, please implement the custom codec for the TapValue that data types in spec.json didn't cover.

 //TapTimeValue, TapMapValue, TapDateValue, TapArrayValue, TapYearValue, TapNumberValue, TapBooleanValue, TapDateTimeValue, TapBinaryValue, TapRawValue, TapStringValue

 codecRegistry.registerFromTapValue(TapRawValue.class, "text", tapRawValue -> {

 if (tapRawValue != null && tapRawValue.getValue() != null)

 return toJson(tapRawValue.getValue());

 return "null";

 });

 }


 private void writeRecord(TapConnectorContext connectorContext, List<TapRecordEvent> tapRecordEvents, Consumer<WriteListResult<TapRecordEvent>> writeListResultConsumer) {

 //TODO write records into database

 //Below is sample code to print received events which suppose to write to database.

 AtomicLong inserted = new AtomicLong(0); //insert count

 AtomicLong updated = new AtomicLong(0); //update count

 AtomicLong deleted = new AtomicLong(0); //delete count

 for(TapRecordEvent recordEvent : tapRecordEvents) {

 if(recordEvent instanceof TapInsertRecordEvent) {

 //TODO insert record

 inserted.incrementAndGet();

 PDKLogger.info(TAG, "Record Write TapInsertRecordEvent {}", toJson(recordEvent));

 } else if(recordEvent instanceof TapUpdateRecordEvent) {

 //TODO update record

 updated.incrementAndGet();

 PDKLogger.info(TAG, "Record Write TapUpdateRecordEvent {}", toJson(recordEvent));

 } else if(recordEvent instanceof TapDeleteRecordEvent) {

 //TODO delete record

 deleted.incrementAndGet();

 PDKLogger.info(TAG, "Record Write TapDeleteRecordEvent {}", toJson(recordEvent));

 }

 }

 //Need to tell incremental engine the write result

 writeListResultConsumer.accept(writeListResult()

 .insertedCount(inserted.get())

 .modifiedCount(updated.get())

 .removedCount(deleted.get()));

 }

 private void queryByFilter(TapConnectorContext connectorContext, List<TapFilter> filters, Consumer<List<FilterResult>> listConsumer){

 //Filter is exactly match.

 //If query by the filter, no value is in database, please still create a FitlerResult with null value in it. So that flow engine can understand the filter has no value.

 }

 private void dropTable(TapConnectorContext connectorContext, TapDropTableEvent dropTableEvent) {

 TapTable table = connectorContext.getTable();

 //TODO implement drop table

 }

 private void createTable(TapConnectorContext connectorContext, TapCreateTableEvent createTableEvent) {

 //TODO implement create table.

 TapTable table = connectorContext.getTable();

 LinkedHashMap<String, TapField> nameFieldMap = table.getNameFieldMap();

 for(Map.Entry<String, TapField> entry : nameFieldMap.entrySet()) {

 TapField field = entry.getValue();

 String originType = field.getOriginType();

 //originType is the data types defined in spec.json

 //TODO use the generated originType to create table.

 }

 }

 }

Pruebe y verifique a través de TDD después de que se complete el desarrollo

Proporcione un archivo json que el usuario debe completar en las opciones de configuración. Por ejemplo, en las opciones de configuración anteriores, el usuario debe completar el host y el puerto de la base de datos, luego el contenido del archivo xdb_tdd.json de tdd es como sigue:

{
    "connection": {

      "host": "192.168.153.132",

      "port": 9030,

    }
}

Ejecute el comando de prueba TDD:

./bin/tap tdd --testConfig xdb_tdd.json ./connectors/xdb-connector

Cuando la prueba TDD falla, modifique los errores correspondientes de acuerdo con las indicaciones de error hasta que pase la prueba TDD;

Cuando pasa la prueba TDD, el conector PDK está en un estado en el que se puede enviar una solicitud de extracción.

Cómo enviar al proyecto de código abierto PDK

① bifurcación idaas-pdk, cree una sucursal local basada en la sucursal principal remota

② De acuerdo con el nombre de la base de datos a la que se accederá, cree un nuevo módulo en el directorio idaas-pdk/connectors, y la convención de nomenclatura es {nombre en minúsculas de la base de datos}-conector, por ejemplo, el nombre de la base de datos de acceso es XDB, y el nombre del módulo es xdb-conector

③ El desarrollador completa el desarrollo y la implementación de la base de datos de acceso de acuerdo con el documento oficial de API

④ Después de pasar la prueba TDD, envíe PR a idaas-pdk

⑤ Combinar el código después de la PR enviada por el equipo oficial Revisión

huevos de Pascua

Los estudiantes interesados ​​no se apresuren a desarrollarlo. Se entiende que la versión gratuita oficial ha realizado sucesivamente una conexión de datos en tiempo real entre 30 fuentes/objetivos de datos comunes. Si ya contiene la base de datos a la que desea acceder, puede usar Tapdata Cloud directamente ( Tapdata Cloud | Free Heterogeneous Database Real-time Sync Cloud Platform - Tapdata ) para la sincronización gratuita de datos en tiempo real. Por supuesto, si sus necesidades no son compatibles en esta etapa, puede usar Tapdata PDK para el desarrollo de autoservicio y el acceso rápido.

Tipos de conexión de datos compatibles actualmente con Tapdata Cloud

Actualmente, Tapdata ha abierto un grupo de co-construcción ecológica de complementos para desarrolladores. Puede proporcionar intercambios técnicos y apoyo durante el proceso de desarrollo. Los estudiantes interesados ​​pueden escanear el código a seguir e invitarlo a unirse al grupo:

Supongo que te gusta

Origin blog.csdn.net/weixin_39709134/article/details/124140732
Recomendado
Clasificación