Como aproveitar os plugins de código aberto? Desenvolva interfaces de dados de forma rápida e eficiente para conectar diferentes sistemas de aplicativos

contente

Introdução:

Plugin de código aberto Tapdata PDK

Acesso rápido ao banco de dados de destino

Prepare o ambiente

Baixe o código fonte e compile

Crie um projeto do Connector para o banco de dados de destino

Teste e verifique através do TDD após a conclusão do desenvolvimento

Como enviar para o projeto de código aberto PDK

ovos de Páscoa


Introdução:

Não é exagero dizer que não há desenvolvedor que ainda não tenha chutado a placa de ferro da "não interoperabilidade de dados de aplicativos" - no caso de diferentes plataformas, diferentes tecnologias, diferentes métodos de armazenamento e implantação e a falta de interfaces, os sistemas de aplicação são diferentes, de difícil comunicação. Com a contínua expansão dos requisitos de negócios, os aplicativos estão em constante desenvolvimento para diversificação e personalização.A contradição entre negócios futuros e pilhas de tecnologia desatualizadas também está se tornando cada vez mais proeminente, e o número de interfaces necessárias também está aumentando.

Como tornar o desenvolvimento da interface simples e rápido tornou-se um problema que precisamos considerar. Recentemente, desenterrei um plug-in de código aberto muito perfumado. Depois de estudar cuidadosamente a documentação técnica, decidi dar a você a Amway:

Plugin de código aberto Tapdata PDK

Link do GitHub: https://github.com/tapdata/idaas-pdk

A editora deste projeto é a Tapdata, uma equipe empresarial nacional especializada em plataformas de serviços de dados em tempo real. Segundo os funcionários, esse componente de código aberto também é o trampolim para o código aberto de seus principais produtos. sincronização de dados de tempo.Uma força bastante madura.

PDK é uma estrutura de desenvolvimento de plug-in de código aberto abstraída de sua tecnologia de interface de dados. Através da interface Source Plugin ou da interface Target Plugin, a adaptação e compatibilidade do novo banco de dados como origem ou destino do Tapdata podem ser realizadas rapidamente, de modo que o  produto Tapdata  Cloud e o próximo código aberto podem ser realizados rapidamente Tapdata várias fontes de dados heterogêneas para bancos de dados ou plataformas de destino.

De acordo com a especificação de desenvolvimento do conector PDK, o desenvolvimento de fonte e destino de dados pode simplificar o processo de desenvolvimento de link de dados. .

Os tipos de suporte incluem:

  • Banco de dados de acesso:  MySQL, Oracle, PostgreSQL, etc.
  • Acesse produtos  SaaS  :  Salesforce, vika table, gold data form, Zoho CRM, etc.
  • Acesso a fontes de dados personalizadas:  pode se conectar a fontes de dados de protocolo privado

Acesso rápido ao banco de dados de destino

Atualmente, a equipe do PDK tornou públicos os documentos técnicos e você pode acessar o GitHub ( https://github.com/tapdata/idaas-pdk )  para obter detalhes.

Prepare o ambiente

  • Java8
  • Especialista
  • Git
  • INtelliJ IDEA

Baixe o código fonte e compile

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

cd idaas-pdk

mvn clean install

Crie um projeto do Connector para o banco de dados de destino

Por exemplo, o grupo é io.tapdata, o nome do banco de dados é XDB e a versão da versão é 0.0.1. Crie um projeto Connector com o seguinte comando

  • Quando o banco de dados de destino não precisa criar uma tabela

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

Abra o idaas-pdk com o ItelliJ IDEA e você poderá ver o projeto xdb-connector em idaas-pdk/connectors.

  • Preencha configOptions em spec.json

Após o configOptions ser integrado ao site Tapdata, ele configura os itens de entrada para o usuário ao utilizar o Conector, como endereço de conexão do banco de dados, nome de usuário, senha, 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"

            }

            

         }

      }

   }

}
  • Escreva o código para acessar o banco de dados 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.

    }

}
  • Quando o banco de dados de destino precisa criar uma tabela

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

Abra o idaas-pdk com o ItelliJ IDEA e você poderá ver o projeto xdb-connector em idaas-pdk/connectors.

  • Preencha configOptions em spec.json

Depois que o configOptions estiver integrado ao site Tapdata, configure os itens de entrada para o usuário ao usar o Conector, como endereço de conexão do banco de dados, nome de usuário, senha, 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"

            }     
         }
      }
   }
}
  • Preencha dataTypes (expressão de tipo) em spec.json

dataTypes é usado para descrever o intervalo de todos os campos que este Conector acessa o banco de dados e converte no TapType correspondente. O banco de dados de origem também fornecerá a mesma descrição de dataTypes, portanto, quando os dados de origem fluirem para Tapdata, ele combinará as informações de descrição de campo dos dataTypes de origem com as informações de campo da tabela de banco de dados de origem e inserirá Tapdata por meio da estrutura de dados neutra de Tapdata. No fluxo de dados, antes que os dados fluam para o banco de dados de destino, o Tapdata encontrará o melhor campo de armazenamento nos dataTypes da biblioteca de destino com base nessas informações e informará o desenvolvedor do PDK por meio do originType do TapField para construir a tabela .

{

   ...

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

   }

}
  • Escreva o código para acessar o banco de dados 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.

 }

 }

 }

Teste e verifique através do TDD após a conclusão do desenvolvimento

Forneça um arquivo json que precisa ser preenchido pelo usuário em configOptions. Por exemplo, no configOptions acima, o usuário deve preencher o Host e a Porta do banco de dados, depois o conteúdo do arquivo xdb_tdd.json do tdd é o seguinte:

{
    "connection": {

      "host": "192.168.153.132",

      "port": 9030,

    }
}

Execute o comando de teste TDD:

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

Quando o teste TDD falhar, modifique os erros correspondentes de acordo com os prompts de erro até que o teste TDD seja aprovado;

Quando o teste TDD for aprovado, o PDK Connector estará em um estado em que uma solicitação de pull pode ser enviada.

Como enviar para o projeto de código aberto PDK

① fork idaas-pdk, crie um branch local baseado no branch principal remoto

② De acordo com o nome do banco de dados a ser acessado, crie um novo módulo no diretório idaas-pdk/connectors, e a convenção de nomenclatura é {database lowercase name}-connector, por exemplo, o nome do banco de dados de acesso é XDB, e o nome do módulo é conector xdb

③ O desenvolvedor conclui o desenvolvimento e implementação do banco de dados de acesso de acordo com o documento oficial da API

④ Depois de passar no teste TDD, envie PR para idaas-pdk

⑤ Mesclar o código após o PR enviado pela equipe oficial Revisão

ovos de Páscoa

Os alunos interessados ​​não se apressam em desenvolvê-lo. Entende-se que a versão oficial gratuita realizou sucessivamente conexão de dados em tempo real entre 30 fontes/destinos de dados comuns. Se já contém o banco de dados que você deseja acessar, você pode usar Tapdata Cloud diretamente ( Tapdata Cloud | Free Heterogeneneous Database Real-time Sync Cloud Platform - Tapdata ) para sincronização gratuita de dados em tempo real. Obviamente, se suas necessidades não forem atendidas neste estágio, você poderá usar o Tapdata PDK para desenvolvimento de autoatendimento e acesso rápido.

Tipos de conexão de dados atualmente suportados pelo Tapdata Cloud

Atualmente, a Tapdata abriu um grupo de co-construção ecológica de plug-ins para desenvolvedores. Ele pode fornecer trocas técnicas e suporte durante o processo de desenvolvimento. Os alunos interessados ​​podem digitalizar o código a seguir e convidá-lo a participar do grupo:

Acho que você gosta

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