All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bdware.doip.cluster.callback.DDOClusterDoipInvocationCallback Maven / Gradle / Ivy

The newest version!
package org.bdware.doip.cluster.callback;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.cluster.entity.DoipInvocation;
import org.bdware.doip.codec.JsonDoipMessage;
import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.codec.doipMessage.DoipMessageFactory;
import org.bdware.doip.codec.doipMessage.DoipResponseCode;
import org.bdware.doip.endpoint.client.DoipClientImpl;
import org.bdware.doip.endpoint.client.DoipMessageCallback;
import org.bdware.sc.bean.JoinInfo;
import org.bdware.sc.util.JsonUtil;
import wrp.jdk.nashorn.api.scripting.NashornScriptEngineUtil;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class DDOClusterDoipInvocationCallback {
    static Logger LOGGER = LogManager.getLogger(DDOClusterDoipInvocationCallback.class);
    private final DoipMessage request;
    private final Map cookie;
    // joinCount记录开始Merge的上限
    int joinCount;
    AtomicInteger count = new AtomicInteger(0);
    DoipMessageCallback originalCallback;
    List successResult = new ArrayList<>();
    List problemResult = new ArrayList<>();
    NashornScriptEngineUtil engineUtil;
    JoinInfo joinInfo;
    String[] targetDOIDs;
    DoipClientImpl doipClientImpl;
    JsonObject appendixes;


    public DDOClusterDoipInvocationCallback(Map cookie, DoipClientImpl doipClientImpl, String[] targetDOIDs, DoipMessage msg, DoipMessageCallback cb, int count, NashornScriptEngineUtil engineUtil, JoinInfo joinInfo, JsonObject appendixes) {
        this.cookie = cookie;
        this.request = msg;
        this.originalCallback = cb;
        this.joinCount = count;
        this.engineUtil = engineUtil;
        this.joinInfo = joinInfo;
        this.targetDOIDs = targetDOIDs;
        this.doipClientImpl = doipClientImpl;
        this.appendixes = appendixes;
    }

    public void onResult(DoipInvocation msg) {
        // logDoipMsgInfo(msg);
        // 如果nodeID不存在,或者该节点的返回值已经被处理过了,不需要再次调用onResult了
        if (msg.isSuccess()) {
            successResult.add(msg);
        } else
            problemResult.add(msg);
        int curCount = count.incrementAndGet();
        if (curCount == joinCount) {
            // 完成聚合 & 结果统计
            executeJoinFunc(originalCallback);
        }
    }

    public String getNodeID(DoipMessage msg) {
        String nodeID = null;
        if (msg != null && msg.header != null && msg.header.parameters != null && msg.header.parameters.attributes != null) {
            if (msg.header.parameters.attributes.get("nodeID") != null) {
                nodeID = msg.header.parameters.attributes.get("nodeID").getAsString();
            }
        }
        return nodeID;
    }

    public void executeJoinFunc(DoipMessageCallback originalCallback) {
        if (joinInfo != null) {
            handleJoinInfo(joinInfo, originalCallback);
            return;
        }
        if (successResult.size() + problemResult.size() == 1) {
            successResult.addAll(problemResult);
            originalCallback.onResult(successResult.get(0).response);
            return;
        }
        originalCallback.onResult(mergeInvocation());
    }

    private DoipMessage mergeInvocation() {
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        if (problemResult.size() > 0)
            builder.createResponse(DoipResponseCode.UnKnownError, request);
        else
            builder.createResponse(DoipResponseCode.Success, request);
        try {
            JsonArray successResponses = new JsonArray();
            for (DoipInvocation msg : successResult) {
                successResponses.add(JsonUtil.parseObject(JsonDoipMessage.fromDoipMessage(msg.response)));
            }
            JsonArray problemResponses = new JsonArray();
            for (DoipInvocation msg : problemResult) {
                problemResponses.add(JsonUtil.parseObject(JsonDoipMessage.fromDoipMessage(msg.response)));
            }
            builder.addAttributes("successResponses", successResponses);
            builder.addAttributes("problemResponses", problemResponses);
        } catch (Exception e) {
            builder.createResponse(DoipResponseCode.UnKnownError, request);
            e.printStackTrace();
        }
        return builder.create();
    }

    private void handleJoinInfo(JoinInfo joinInfo, DoipMessageCallback originalCallback) {
        try {
            if (joinInfo.useDefault == null) {
                if (joinInfo.joinFuncName != null) {
                    engineUtil.invokeFunctionWithObjectAsync(joinInfo.joinFuncName,
                            new CookieJSResultCallback(cookie) {
                                @Override
                                public void onResult(DoipMessage result) {
                                    originalCallback.onResult(result);
                                }
                            }
                            , successResult, problemResult);
                    return;
                } else throw new IllegalArgumentException("missing joinFuncName");
            }
            DoipMessage returnedMsg = null;
            switch (joinInfo.useDefault) {
                case add:
                    double val = 0;
                    for (DoipInvocation doipInvocation : successResult) {
                        val += Double.parseDouble(doipInvocation.response.body.getDataAsJsonString());
                        returnedMsg = doipInvocation.response;
                    }
                    returnedMsg.body.encodedData = (val + "").getBytes();
                    originalCallback.onResult(returnedMsg);
                    return;
                case multiply:
                    val = 1;
                    for (DoipInvocation doipInvocation : successResult) {
                        val *= Double.parseDouble(doipInvocation.response.body.getDataAsJsonString());
                        returnedMsg = doipInvocation.response;
                    }
                    returnedMsg.body.encodedData = (val + "").getBytes();
                    originalCallback.onResult(returnedMsg);
                    return;
                default:
                    throw new IllegalArgumentException("missing default merge rule");
            }
        } catch (Exception e) {
            DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
            builder.createResponse(DoipResponseCode.Declined, request);
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(bo));
            builder.setBody(bo.toByteArray());
            e.printStackTrace();
            originalCallback.onResult(builder.create());
            return;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy