Comment profiter des plugins open source ? Développer rapidement et efficacement des interfaces de données pour connecter différents systèmes d'application

teneur

Introduction:

Plug-in open source Tapdata PDK

Accès rapide à la base de données cible

Préparer l'environnement

Télécharger le code source et compiler

Créer un projet de connecteur pour la base de données cible

Tester et vérifier via TDD une fois le développement terminé

Comment soumettre au projet open source PDK

œufs de Pâques


Introduction:

Il n'est pas exagéré de dire qu'il n'y a pas de développeur qui n'ait pas encore frappé la plaque de fer de la "non-interopérabilité des données d'application" - dans le cas de plates-formes différentes, de technologies différentes, de méthodes de stockage et de déploiement différentes, et du manque de ressources nécessaires interfaces, les systèmes d'application sont différents Difficile de communiquer. Avec l'expansion continue des besoins des entreprises, les applications évoluent constamment vers la diversification et la personnalisation.La contradiction entre les entreprises futures et les piles technologiques obsolètes devient également de plus en plus importante, et le nombre d'interfaces requises augmente également.

Comment rendre le développement de l'interface simple et rapide est devenu un problème que nous devons considérer. Récemment, j'ai déniché un plug-in open source très parfumé. Après avoir étudié attentivement la documentation technique, j'ai décidé de vous donner Amway :

Plug-in open source Tapdata PDK

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

L'éditeur de ce projet est Tapdata, une équipe entrepreneuriale nationale spécialisée dans les plates-formes de services de données en temps réel. Selon les responsables, ce composant open source est également le tremplin vers l'open source de ses produits de base. Il est soutenu par le réel de l'équipe synchronisation des données temporelles Une force assez mature.

PDK est un cadre de développement de plug-in open source abstrait de sa technologie d'interface de données. Grâce à l'interface Source Plugin ou à l'interface Target Plugin, l'adaptation et la compatibilité de la nouvelle base de données en tant que source ou cible de Tapdata peuvent être rapidement réalisées, de sorte que le  produit Tapdata  Cloud et l'open source à venir peuvent être rapidement réalisés Tapdata diverses sources de données hétérogènes vers des bases de données ou des plates-formes cibles.

Selon la spécification de développement du connecteur PDK, le développement de la source et de la cible de données peut simplifier le processus de développement de la liaison de données.Grâce à une planification de développement détaillée et à un test TDD intégré, le développement d'une nouvelle source de données et d'une nouvelle cible peut être complété simplement et rapidement .

Les types de soutien comprennent :

  • Base de données d' accès :  MySQL, Oracle, PostgreSQL, etc.
  • Accédez aux produits  SaaS  :  Salesforce, vika table, gold data form, Zoho CRM, etc.
  • Accès aux sources de données personnalisées :  peut se connecter à des sources de données de protocole privé

Accès rapide à la base de données cible

À l'heure actuelle, l'équipe PDK a rendu publics les documents techniques et vous pouvez vous rendre sur GitHub ( https://github.com/tapdata/idaas-pdk)  pour plus de détails.

Préparer l'environnement

  • Java 8
  • Maven
  • Gite
  • IDÉE IntelliJ

Télécharger le code source et compiler

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

cd idaas-pdk

mvn clean install

Créer un projet de connecteur pour la base de données cible

Par exemple, le groupe est io.tapdata, le nom de la base de données est XDB et la version est 0.0.1. Créez un projet de connecteur avec la commande suivante

  • Lorsque la base de données cible n'a pas besoin de créer une table

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

Ouvrez idaas-pdk avec ItelliJ IDEA, et vous pouvez voir le projet xdb-connector sous idaas-pdk/connectors.

  • Remplissez configOptions dans spec.json

Une fois que configOptions est intégré au site Tapdata, il configure les éléments d'entrée pour l'utilisateur lors de l'utilisation du connecteur, tels que l'adresse de connexion à la base de données, le nom d'utilisateur, le mot de passe, 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"

            }

            

         }

      }

   }

}
  • Écrivez le code pour accéder à la base de données cible
@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.

    }

}
  • Lorsque la base de données cible doit créer une table

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

Ouvrez idaas-pdk avec ItelliJ IDEA, et vous pouvez voir le projet xdb-connector sous idaas-pdk/connectors.

  • Remplissez configOptions dans spec.json

Une fois configOptions intégré au site Tapdata, configurez les éléments d'entrée pour l'utilisateur lors de l'utilisation du connecteur, tels que l'adresse de connexion à la base de données, le nom d'utilisateur, le mot de passe, 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"

            }     
         }
      }
   }
}
  • Remplissez dataTypes (expression de type) dans spec.json

dataTypes est utilisé pour décrire la plage de tous les champs auxquels ce connecteur accède à la base de données et les convertit en TapType correspondant. La base de données source fournira également la même description des types de données, donc lorsque les données source afflueront dans Tapdata, elle combinera les informations de description de champ des types de données source avec les informations de champ de la table de base de données source, et entrera Tapdata via la structure de données neutre de Tapdata. Dans le flux de données, avant que les données n'arrivent dans la base de données cible, Tapdata trouvera le meilleur champ de stockage dans les dataTypes de la bibliothèque cible en fonction de ces informations, et informera le développeur PDK via le originType du TapField pour construire la table .

{

   ...

   "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}

   }

}
  • Écrivez le code pour accéder à la base de données cible
 @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.

 }

 }

 }

Tester et vérifier via TDD une fois le développement terminé

Fournissez un fichier json qui doit être rempli par l'utilisateur dans configOptions. Par exemple, dans les configOptions ci-dessus, l'utilisateur doit renseigner l'hôte et le port de la base de données, puis le contenu du fichier xdb_tdd.json de tdd est comme suit:

{
    "connection": {

      "host": "192.168.153.132",

      "port": 9030,

    }
}

Exécutez la commande de test TDD :

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

Lorsque le test TDD échoue, veuillez modifier les erreurs correspondantes en fonction des invites d'erreur jusqu'à ce que le test TDD soit réussi ;

Lorsque le test TDD réussit, le connecteur PDK est dans un état où une demande d'extraction peut être soumise.

Comment soumettre au projet open source PDK

① fork idaas-pdk, créer une branche locale basée sur la branche principale distante

② Selon le nom de la base de données à accéder, créez un nouveau module dans le répertoire idaas-pdk/connectors, et la convention de nommage est {database lowercase name}-connector, par exemple, le nom de la base de données d'accès est XDB, et le nom du module est xdb-connector

③ Le développeur termine le développement et la mise en œuvre de la base de données d'accès conformément au document officiel de l'API

④ Après avoir réussi le test TDD, soumettez PR à idaas-pdk

⑤ Fusionner le code après le PR soumis par l'équipe officielle Review

œufs de Pâques

Les étudiants intéressés ne se précipitent pas pour le développer. Il est entendu que la version gratuite officielle a successivement réalisé une connexion de données en temps réel entre 30 sources/cibles de données communes. Si elle contient déjà la base de données à laquelle vous souhaitez accéder, vous pouvez utiliser Tapdata Cloud directement ( Tapdata Cloud | Free Heterogeneous Database Real-time Sync Cloud Platform - Tapdata ) pour une synchronisation gratuite des données en temps réel. Bien sûr, si vos besoins ne sont pas pris en charge à ce stade, vous pouvez utiliser Tapdata PDK pour un développement en libre-service et un accès rapide.

Types de connexion de données actuellement pris en charge par Tapdata Cloud

À l'heure actuelle, Tapdata a ouvert un groupe de co-construction écologique de plug-ins pour les développeurs. Il peut fournir des échanges techniques et un soutien pendant le processus de développement. Les étudiants intéressés peuvent scanner le code à suivre et vous inviter à rejoindre le groupe :

Je suppose que tu aimes

Origine blog.csdn.net/weixin_39709134/article/details/124140732
conseillé
Classement