オープンソースプラグインを利用するにはどうすればよいですか?さまざまなアプリケーションシステムを接続するためのデータインターフェイスを迅速かつ効率的に開発する

コンテンツ

序章:

オープンソースプラグインTapdataPDK

クイックスタートターゲットデータベースアクセス

環境を整える

ソースコードをダウンロードしてコンパイルする

ターゲットデータベースのコネクタプロジェクトを作成します

開発が完了した後、TDDを介してテストおよび検証します

PDKオープンソースプロジェクトに提出する方法

イースターエッグ


序章:

さまざまなプラットフォーム、さまざまなテクノロジー、さまざまなストレージと展開方法、および必要性の欠如の場合、「アプリケーションデータの非相互運用性」の鉄板をまだ蹴っていない開発者はいないと言っても過言ではありません。インターフェイス、アプリケーションシステムが異なります。通信が困難です。ビジネス要件の継続的な拡大に伴い、アプリケーションは多様化とパーソナライズに向けて絶えず開発されています。将来のビジネスと古いテクノロジースタックとの矛盾もますます顕著になり、必要なインターフェイスの数も増えています。

インターフェイス開発をシンプルかつ迅速に行う方法は、私たちが検討する必要のある問題になっています。最近、私は非常に香りのよいオープンソースプラグインを掘り起こしました。技術文書を注意深く検討した後、アムウェイに提供することにしました。

オープンソースプラグインTapdataPDK

GitHubリンク:https ://github.com/tapdata/idaas-pdk

このプロジェクトの発行元は、リアルタイムデータサービスプラットフォームを専門とする国内の起業家チームであるTapdataです。関係者によると、このオープンソースコンポーネントは、コア製品のオープンソースの足がかりでもあります。チームの本物に支えられています。 -時間データの同期。かなり成熟した強み。

PDKは、データインターフェイステクノロジーから抽象化されたオープンソースプラグイン開発フレームワークです。ソースプラグインインターフェイスまたはターゲットプラグインインターフェイスを介して、Tapdataのソースまたはターゲットとしての新しいデータベースの適応と互換性を迅速に実現できるため、Tapdata  Cloud製品と今後の オープンソースを迅速に実現できます。Tapdata、さまざまな異種データソースからターゲットデータベースまたはプラットフォームのリアルタイムデータドッキング機能への無料アクセス 。

PDKコネクタの開発仕様によると、データソースとターゲットの開発により、データリンクの開発プロセスを簡素化できます。詳細な開発計画と組み込みのTDDテストにより、新しいデータソースとターゲットの開発を簡単かつ迅速に完了できます。 。

サポートの種類は次のとおりです。

  • アクセスデータベース:  MySQL、Oracle、PostgreSQLなど。
  •  SaaS 製品へのアクセス:  Salesforce、vikaテーブル、ゴールドデータフォーム、ZohoCRMなど。
  • カスタムデータソースへのアクセス: プライベートプロトコルデータソースに接続できます

クイックスタートターゲットデータベースアクセス

現在、PDKチームは技術文書を公開しています。詳細については、GitHub(https://github.com/tapdata/idaas-pdk) にアクセスしてください。

環境を整える

  • Java 8
  • Maven
  • ギット
  • IntelliJ IDEA

ソースコードをダウンロードしてコンパイルする

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

cd idaas-pdk

mvn clean install

ターゲットデータベースのコネクタプロジェクトを作成します

たとえば、グループはio.tapdata、データベース名はXDB、バージョンバージョンは0.0.1です。次のコマンドを使用してコネクタプロジェクトを作成します。

  • ターゲットデータベースがテーブルを作成する必要がない場合

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

ItelliJ IDEAでidaas-pdkを開くと、idaas-pdk/connectorsの下にxdb-connectorプロジェクトが表示されます。

  • spec.jsonにconfigOptionsを入力します

configOptionsがTapdataサイトに統合された後、データベース接続アドレス、ユーザー名、パスワードなど、コネクターを使用する際のユーザーの入力項目を構成します。

{

   ...

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

            }

            

         }

      }

   }

}
  • ターゲットデータベースにアクセスするためのコードを記述します
@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.

    }

}
  • ターゲットデータベースがテーブルを作成する必要がある場合

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

ItelliJ IDEAでidaas-pdkを開くと、idaas-pdk/connectorsの下にxdb-connectorプロジェクトが表示されます。

  • spec.jsonにconfigOptionsを入力します

configOptionsがTapdataサイトに統合された後、データベース接続アドレス、ユーザー名、パスワードなど、コネクターを使用する際のユーザーの入力項目を構成します。

{
   ...

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

            }     
         }
      }
   }
}
  • spec.jsonにdataTypes(型式)を入力します

dataTypesは、このコネクタがデータベースにアクセスし、対応するTapTypeに変換するすべてのフィールドの範囲を記述するために使用されます。ソースデータベースも同じdataTypes記述を提供するため、ソースデータがTapdataに流入すると、ソースdataTypesのフィールド記述情報とソースデータベーステーブルのフィールド情報が結合され、のニュートラルデータ構造を介してTapdataが入力されます。 Tapdata。データフローでは、データがターゲットデータベースに流れる前に、Tapdataはこの情報に基づいてターゲットライブラリのdataTypesで最適なストレージフィールドを見つけ、TapFieldのoriginTypeを介してPDK開発者にテーブルを作成するよう通知します。 。

{

   ...

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

   }

}
  • ターゲットデータベースにアクセスするためのコードを記述します
 @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.

 }

 }

 }

開発が完了した後、TDDを介してテストおよび検証します

configOptionsにユーザーが入力する必要のあるjsonファイルを提供します。たとえば、上記のconfigOptionsでは、ユーザーはデータベースのホストとポートを入力してから、tddのxdb_tdd.jsonファイルの内容を入力する必要があります。以下のとおりであります:

{
    "connection": {

      "host": "192.168.153.132",

      "port": 9030,

    }
}

TDDテストコマンドを実行します。

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

TDDテストが失敗した場合は、TDDテストに合格するまで、エラープロンプトに従って対応するエラーを変更してください。

TDDテストに合格すると、PDKコネクタはプルリクエストを送信できる状態になります。

PDKオープンソースプロジェクトに提出する方法

①forkidaas-pdk、リモートメインブランチに基づいてローカルブランチを作成します

②アクセスするデータベースの名前に応じて、idaas-pdk / connectedorsディレクトリに新しいモジュールを作成します。命名規則は{データベース小文字名}-コネクタです。たとえば、アクセスデータベースの名前はXDBです。モジュール名はxdb-connectorです。

③開発者は、公式APIドキュメントに従ってアクセスデータベースの開発と実装を完了します

④TDDテストに合格したら、PRをidaas-pdkに提出してください

⑤公式チームレビューで提出されたPR後にコードをマージする

イースターエッグ

興味のある学生は急いで開発する必要はありません。公式の無料バージョンでは、30の一般的なデータソース/ターゲット間のリアルタイムデータ接続が連続して実現されていることがわかります。アクセスしたいデータベースがすでに含まれている場合は、TapdataCloudを使用できます。直接(Tapdata Cloud |無料の異種データベースリアルタイム同期クラウドプラットフォーム-Tapdata)、無料のリアルタイムデータ同期を実現します。もちろん、この段階でニーズがサポートされていない場合は、TapdataPDKを使用してセルフサービス開発と迅速なアクセスを行うことができます。

TapdataCloudで現在サポートされているデータ接続タイプ

現在、Tapdataは、開発者向けのプラグインエコロジカル共同構築グループを開設しました。開発プロセス中に技術的な交換とサポートを提供できます。興味のある学生は、コードをスキャンしてフォローし、グループに参加するよう招待できます。

おすすめ

転載: blog.csdn.net/weixin_39709134/article/details/124140732