Nifi开发之自动生成DataFolw

1.官方文档,封装Api

官方文档: Apache NiFi Documentation.

在这里插入图片描述

<!-- https://mvnrepository.com/artifact/org.apache.nifi/nifi-api -->
<dependency>
    <groupId>org.apache.nifi</groupId>
    <artifactId>nifi-api</artifactId>
    <version>1.15.0</version>
    <scope>provided</scope>
</dependency>

1.1封装taken

首先,F12找到请求的方法
在这里插入图片描述
在官方文档中找到对应的部分
在这里插入图片描述
封装部分

OkHttp3的封装,下面创建OkHttpClient需要用到:OkHttp3封装.


import java.io.IOException;
import java.util.Objects;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.FormBody.Builder;
import org.apache.commons.lang3.StringUtils;

public class AccessAPI {
    private static final String API_ACCESS_TOKEN = "/access/token";

    public AccessAPI() {
    }

    public String accessToken(String url, String username, String password) throws IOException {
        if (!StringUtils.isBlank(url) && !StringUtils.isBlank(username) && !StringUtils.isBlank(password)) {
            OkHttpClient okHttpClient = OKHttpConfiguration.getOkHttpClient();
            RequestBody formBody = (new Builder()).add("username", username).add("password", password).build();
            Request request = (new okhttp3.Request.Builder()).url(url + "/access/token").header("Content-Type", "application/x-www-form-urlencoded").post(formBody).build();
            Response response = okHttpClient.newCall(request).execute();
            Throwable var8 = null;

            String var9;
            try {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response + "Reason is: " + (response.body() != null ? response.body().string() : null));
                }

                var9 = ((ResponseBody)Objects.requireNonNull(response.body())).string();
            } catch (Throwable var18) {
                var8 = var18;
                throw var18;
            } finally {
                if (response != null) {
                    if (var8 != null) {
                        try {
                            response.close();
                        } catch (Throwable var17) {
                            var8.addSuppressed(var17);
                        }
                    } else {
                        response.close();
                    }
                }

            }

            return var9;
        } else {
            throw new RuntimeException("url or username or password must not be null");
        }
    }
}
每一个方法执行,都要用到token,从配置文件拿到url,username,password
@Component
public class ETLServer {

    @Value("${nifi.url}")
    private String url;
    @Value("${nifi.user}")
    private String username;
    @Value("${nifi.password}")
    private String password;

    @Autowired
    private AccessAPI accessAPI;

    private static final Logger LOGGER = LoggerFactory.getLogger(ETLServer.class);

    public CommonEntity getCommonEntity() {

        LOGGER.info("begin login server URL:{},username:{}", url, username);

        String token = null;
        try {
            token = accessAPI.accessToken(url, username, password);
        } catch (IOException e) {
            e.printStackTrace();
        }
        CommonEntity commonEntity = new CommonEntity();
        commonEntity.setUrl(url);
        commonEntity.setAccessToken(token);
        return commonEntity;
    }

}
@Data
public class CommonEntity {
    @NotEmpty(message = "url must not be empty")
    private String url;
    @NotEmpty(message = "accessToken must not be empty")
    private String accessToken;

1.2拉取模板

找到对应的官方Api,或者去画布上操作,F12可以找到每个动作调用的方法
在这里插入图片描述没想到里面又引入了另一个类

在这里插入图片描述

查看apach提供的代码,只需要四个属性,
originX,originY,templateId,disconnectedNodeAcknowledged。
package org.apache.nifi.web.api.entity;

import io.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;

@XmlRootElement(
    name = "instantiateTemplateRequestEntity"
)
public class InstantiateTemplateRequestEntity extends Entity {
    private Double originX;
    private Double originY;
    private String templateId;
    private String encodingVersion;
    private FlowSnippetDTO snippet;
    private Boolean disconnectedNodeAcknowledged;

    public InstantiateTemplateRequestEntity() {
    }

    @ApiModelProperty("The identifier of the template.")
    public String getTemplateId() {
        return this.templateId;
    }

    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }

    @ApiModelProperty("The x coordinate of the origin of the bounding box where the new components will be placed.")
    public Double getOriginX() {
        return this.originX;
    }

    public void setOriginX(Double originX) {
        this.originX = originX;
    }

    @ApiModelProperty("The y coordinate of the origin of the bounding box where the new components will be placed.")
    public Double getOriginY() {
        return this.originY;
    }

    public void setOriginY(Double originY) {
        this.originY = originY;
    }

    @ApiModelProperty("The encoding version of the flow snippet. If not specified, this is automatically populated by the node receiving the user request. If the snippet is specified, the version will be the latest. If the snippet is not specified, the version will come from the underlying template. These details need to be replicated throughout the cluster to ensure consistency.")
    public String getEncodingVersion() {
        return this.encodingVersion;
    }

    public void setEncodingVersion(String encodingVersion) {
        this.encodingVersion = encodingVersion;
    }

    @ApiModelProperty("A flow snippet of the template contents. If not specified, this is automatically populated by the node receiving the user request. These details need to be replicated throughout the cluster to ensure consistency.")
    public FlowSnippetDTO getSnippet() {
        return this.snippet;
    }

    public void setSnippet(FlowSnippetDTO snippet) {
        this.snippet = snippet;
    }

    @ApiModelProperty("Acknowledges that this node is disconnected to allow for mutable requests to proceed.")
    public Boolean isDisconnectedNodeAcknowledged() {
        return this.disconnectedNodeAcknowledged;
    }

    public void setDisconnectedNodeAcknowledged(Boolean disconnectedNodeAcknowledged) {
        this.disconnectedNodeAcknowledged = disconnectedNodeAcknowledged;
    }
}

开始干活啦

public class BuildParamUtil {

    public static InstantiateTemplateRequestEntity buildInstantiateTemplateRequestEntity(String templateId, Double originX, Double originY, Boolean disconnectedNodeAcknowledged) {
        InstantiateTemplateRequestEntity instantiateTemplateRequestEntity = new InstantiateTemplateRequestEntity();
        instantiateTemplateRequestEntity.setTemplateId(templateId);
        instantiateTemplateRequestEntity.setOriginX(originX);
        instantiateTemplateRequestEntity.setOriginY(originY);
        instantiateTemplateRequestEntity.setDisconnectedNodeAcknowledged(disconnectedNodeAcknowledged);
        return instantiateTemplateRequestEntity;
    }
}

然后封装instance Template这个方法

@Component
public class AtomicStrategy implements TemplateStrategy {
    @Autowired
    private ProcessGroupAPI processGroupAPI;
    @Autowired
    private ETLServer etlServer;

    public TemplateDTO getTemplateDto(String templateId,String templateGroupId) {
        TemplateDTO templateDTO = new TemplateDTO();
        templateDTO.setId(templateId);
        templateDTO.setGroupId(templateGroupId);
        return templateDTO;
    }

    @Override
    public FlowEntity generateTemplate(TemplateDTO templateDTO, PositionDTO positionDTO, String parentGroupId) throws IOException {

        CommonEntity commonEntity = etlServer.getCommonEntity();
        InstantiateTemplateRequestEntity instantiateTemplateRequestEntity = BuildParamUtil.buildInstantiateTemplateRequestEntity(templateDTO.getId(), positionDTO.getX(), positionDTO.getY(), false);
        FlowEntity flowEntity = processGroupAPI.instanceTemplate(commonEntity, parentGroupId, instantiateTemplateRequestEntity);
        return flowEntity;
    }
}

加载制作好的template


    @Value("${nifi.dbTemplate.template-id}")
    private String dbTemplateId;
    @Value("${nifi.dbTemplate.template-group-id}")
    @Autowired
    private AtomicStrategy atomicStrategy;
    
    private String dbTemplateGroupId;
    
    public void downloadTemplate(String tableName, int i, TemplateDTO templateDto, String parentGroupId, Double random, String category, TableInfo tableInfo) {
        CommonEntity commonEntity = etlServer.getCommonEntity();
        TemplateDTO templateDto = atomicStrategy.getTemplateDto(dbTemplateId, dbTemplateGroupId);

        PositionDTO positionDTO = new PositionDTO();
        positionDTO.setX(550 * i + 0.00);
        positionDTO.setY(random);

        try {
            FlowEntity flowEntity = atomicStrategy.generateTemplate(templateDto, positionDTO, parentGroupId);
            //下面的部分,海阔凭鱼跃,天高任鸟飞啦
            /*
            *1.修改每一个dataflow的全局变量
            *2.根据不同的需求,动态的添加,减少processor,connection
            *3.根据不同的需求,配置不同的script template
            *4.根据不同的需求,匹配相应的controller service(这个不是spring的,是nifi的)
            */
        }
}

1.3 随便封装一个方法

在这里插入图片描述
在这里插入图片描述

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorRunStatusEntity;

public class ProcessorsAPI {
    private static final String API_PROCESSOR_INFO = "/processors/%s";
    private static final String API_PROCESSOR_UPDATE = "/processors/%s";
    private static final String API_PROCESSOR_DELETE = "/processors/%s";
    private static final String API_PROCESSOR_RUN_STATUS = "/processors/%s/run-status";

    public ProcessorsAPI() {
    }

    public ProcessorEntity getProcessor(CommonEntity commonEntity, String id) throws IOException {
        ValidateUtil.validateObject(commonEntity);
        if (StringUtils.isBlank(id)) {
            throw new RuntimeException("processor's id must not be null");
        } else {
            Map<String, String> headParams = new HashMap();
            headParams.put("Authorization", " Bearer " + commonEntity.getAccessToken());
            Call call = OKHttpConfiguration.buildGetCall(String.format(commonEntity.getUrl() + "/processors/%s", id), Collections.emptyList(), headParams);
            Response response = call.execute();
            Throwable var6 = null;

            ProcessorEntity var7;
            try {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response + "Reason is: " + (response.body() != null ? response.body().string() : null));
                }

                var7 = (ProcessorEntity)JsonUtils.toObject(response.body().string(), ProcessorEntity.class);
            } catch (Throwable var16) {
                var6 = var16;
                throw var16;
            } finally {
                if (response != null) {
                    if (var6 != null) {
                        try {
                            response.close();
                        } catch (Throwable var15) {
                            var6.addSuppressed(var15);
                        }
                    } else {
                        response.close();
                    }
                }

            }

            return var7;
        }
    }
    public ProcessorEntity updateProcessor(CommonEntity commonEntity, String id, ProcessorEntity processorEntity) throws IOException {
        ValidateUtil.validateObject(commonEntity);
        if (!StringUtils.isBlank(id) && !Objects.isNull(processorEntity)) {
            String jsonString = JsonUtils.toJson(processorEntity);
            RequestBody requestBody = RequestBody.create(OKHttpConfiguration.JSON, jsonString);
            Map<String, String> headParams = new HashMap();
            headParams.put("Content-Type", "application/json");
            headParams.put("Authorization", " Bearer " + commonEntity.getAccessToken());
            Call call = OKHttpConfiguration.buildPutCall(String.format(commonEntity.getUrl() + "/processors/%s", id), headParams, requestBody);
            Response response = call.execute();
            Throwable var9 = null;

            ProcessorEntity var10;
            try {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response + "Reason is: " + (response.body() != null ? response.body().string() : null));
                }

                var10 = (ProcessorEntity)JsonUtils.toObject(((ResponseBody)Objects.requireNonNull(response.body())).string(), ProcessorEntity.class);
            } catch (Throwable var19) {
                var9 = var19;
                throw var19;
            } finally {
                if (response != null) {
                    if (var9 != null) {
                        try {
                            response.close();
                        } catch (Throwable var18) {
                            var9.addSuppressed(var18);
                        }
                    } else {
                        response.close();
                    }
                }

            }

            return var10;
        } else {
            throw new RuntimeException("processor's id or ProcessorEntity must not be null");
        }
    }
}

2.根据小帮手创建DataFlow

前面说了,我们下载完通用性,扩展性很OK的Template以后,通过读取Excel调整对应Table的DataFLow,将数据迁移到目标表。

-----------use EasyExcel---------

      <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.6</version>
        </dependency>
@RestController
@RequestMapping(value = "/dbTemplate")
public class DBController {

    @Autowired
    private DBService dbService;

    @Value("${nifi.parent-group-id}")
    private String parentGroupId;

    @RequestMapping(value = "/create")
    public void createDBTemplate(){

        dbService.simpleRead(parentGroupId);
    }

}

将excel中每一栏都映射到实体类中,DBMappingTableInfo.class

@Component
public class DBService {

    @Value("${nifi.templateFilesPath.db-template-file}")
    private String dbTemplateUrl;
    @Autowired
    private NifiService nifiService;
    @Autowired
    private AtomicStrategy atomicStrategy;

    private static final Logger LOGGER = LoggerFactory.getLogger(DBService.class);

    public void simpleRead(String parentGroupId) {

        String url = dbTemplateUrl;
        int startRow = 3;

        ExcelReader excelReader = null;
        try {
            excelReader = EasyExcel.read(url).build();

            ReadSheet readSheet1 =
                    EasyExcel.readSheet(0).headRowNumber(startRow).head(DBMappingTableInfo.class).registerReadListener(new DBMappingTableInfoListener()).build();
            ReadSheet readSheet2 =
                    EasyExcel.readSheet(1).headRowNumber(startRow).head(DBMappingColumnInfo.class).registerReadListener(new DBMappingColumnInfoListener()).build();

            excelReader.read(readSheet1, readSheet2);
        } finally {
            if (excelReader != null) {

                excelReader.finish();
            }
        }
    }
}
public class DBMappingTableInfoListener extends AnalysisEventListener<DBMappingTableInfo> {

    private static final Logger logger = LoggerFactory.getLogger(DBMappingTableInfoListener.class);

    List<DBMappingTableInfo> dbMappingTableInfoList = new ArrayList<>();

    @Override
    public void invoke(DBMappingTableInfo dbMappingTableInfo, AnalysisContext analysisContext) {
        logger.info("解析到一条数据:{}", JSON.toJSONString(dbMappingTableInfo));
        dbMappingTableInfoList.add(dbMappingTableInfo);

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        Random random = new Random();
        Double number = random.nextInt(1000) + 0.00;
        for (int i = 0; i < dbMappingTableInfoList.size(); i++) {
            DBMappingTableInfo dbMappingTableInfo = dbMappingTableInfoList.get(i);
            String tableName = dbMappingTableInfo.getTableName();
            operationNifi(tableName, i, parentGroupId, number,dbMappingTableInfo);
        }
    }

    public void operationNifi(String tableName, int i, String parentGroupId, Double random, TableInfo tableInfo) {
        logger.info("dbTableInfo start work create template");
        nifiService.downloadTemplate(tableName, i, templateDto, parentGroupId, random,"table",tableInfo);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百世经纶『一页書』

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值