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

com.envision.energy.eos.sdk.AssetProcessProxy Maven / Gradle / Ivy

package com.envision.energy.eos.sdk;

import com.envision.energy.connective.protobuf.generated.Sdk;
import com.envision.energy.eos.exception.SubscribeException;
import com.envision.energy.eos.sdk.data.AssetChangeDetail;
import com.envision.energy.eos.sdk.data.AssetChangeResponse;
import com.envision.energy.util.AssetChangeEventUtil;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhensheng.cai
 */
public class AssetProcessProxy {

    private Logger logger = LoggerFactory.getLogger(AssetProcessProxy.class);

    private static final Gson gson = new Gson();

    private Transport transport = null;

    /**
     * 如果用同一个回调注册在不同的订阅中,只有最后一个订阅会生效
     * 这里是一个bug,但是其他订阅中目前也是这么做的,我不会修复它 :)
     */
    private Map assetHandlerMap  = new HashMap<>();

    public void setTransport(Transport transport) {
        this.transport = transport;
    }

    public void sendSubMsg() {
        if(transport !=null ){
            for (Map.Entry entry : assetHandlerMap.entrySet()) {
                Sdk.SubAssetData subAssetData = entry.getValue();
                if(subAssetData!=null) {
                    sendSubMsg(subAssetData);
                }
            }
        }
    }

    public void sendSubMsg(Sdk.SubAssetData subAssetData) {
        if (transport != null && transport.isStarted() && subAssetData != null) {
            transport.write(subAssetData);
        }
    }



    //分发时,用户会不会根本不知道自己是通过那个匹配到的? 这个response是匹配所有的 ,还需要过滤?
    public void msgToHandler(Sdk.AssetChangeRsp msg) {
        AssetChangeResponse response = AssetChangeResponse.create(msg);
        logger.info("local receive {}" , response);

        for (Map.Entry handlerEntry : assetHandlerMap.entrySet()) {
            AssetChangeResponse filtered = filter(response, handlerEntry.getValue());
            if(filtered !=null ){
                logger.info("after filter", response);
                IAssetHandler handler = handlerEntry.getKey();

                if(handler!=null){
                    try{
                        handler.assetChangeRead(filtered);
                    }
                    catch (Exception e ){
                        logger.error("callback asset handle err :", e);
                    }
                }
            }
        }
    }

    //有场站引发的时间变更,场站是订阅不到的。
    private boolean eventMatch(AssetChangeResponse reponse, int event) {
        switch (reponse.getEvent()){
            case AssetChangeEventUtil.DELETE_KEY:
                return AssetChangeEventUtil.hasDelete(event);
            case AssetChangeEventUtil.INSERT_KEY:
                return AssetChangeEventUtil.hasInsert(event);
            case AssetChangeEventUtil.UPDATE_KEY:
                return AssetChangeEventUtil.hasUpdate(event);
            default:
                return false;
        }
    }

    /**
     * return new filtered AssetChangeResponse
     * @param response
     * @param subAssetData
     * @return
     */
    private AssetChangeResponse filter(AssetChangeResponse response , Sdk.SubAssetData subAssetData){
        //subscribe empty is not allowed
        if (subAssetData.getAncestorsList().isEmpty() && subAssetData.getTypesList().isEmpty()) {
            return null;
        }
        if(!eventMatch(response, subAssetData.getEvent())){
            return null;
        }
        List details = Lists.newArrayList();
        for (AssetChangeDetail detail : response.getData()) {
            if (matchType(detail.getTypeId(), subAssetData) && matchAncestorOrSelf(detail.getMdmId(), detail.getAncestors(), subAssetData)) {
                details.add(detail);
            }
        }
        if(details.isEmpty()) {
            return null;
        }
        return new AssetChangeResponse(response.getEvent(), details);
    }

    private boolean matchType(int typeId , Sdk.SubAssetData subAssetData){
        if(subAssetData.getTypesList().isEmpty()){
            return true;
        }
        return subAssetData.getTypesList().contains(typeId);
    }

    private boolean matchAncestorOrSelf(String mdmId, List ancestors, Sdk.SubAssetData subAssetData){
        if(subAssetData.getAncestorsList().isEmpty()){
            return true;
        }

        if(subAssetData.getAncestorsList().contains(mdmId)){
            return true;
        }

        for (String ancestor : ancestors ) {
            if(subAssetData.getAncestorsList().contains(ancestor)) {
                return true;
            }
        }
        return false;
    }




    public void subscribe(IAssetHandler handler, int event, Collection ancestors ,  Collection cimTypes)
        throws NullPointerException, SubscribeException
    {
        Sdk.SubAssetData subAssetData = Sdk.SubAssetData.newBuilder()
                .setSubType(Sdk.SubType.sub)
                .addAllAncestors(ancestors)
                .addAllTypes(cimTypes)
                .setEvent(event)
                .build();
        assetHandlerMap.put(handler, subAssetData);
        sendSubMsg(subAssetData);
    }

    /**
     * 目前只开放unsubAll,我们定义当
     * subType= unsub event = all cusomerIds/siteids/cimtypes = empty
     * 即为退订所有
     */
    public void unsubscribe() {
        sendUnsubMsg();
    }

    /**
     * send unsubAllMsg
     */
    private void sendUnsubMsg() {
        if (transport != null) {
            Sdk.SubAssetData subAssetData = Sdk.SubAssetData.newBuilder()
                    .setSubType(Sdk.SubType.unsub)
                    .setEvent(AssetChangeEventUtil.subscribe(Lists.newArrayList(AssetChangeEventUtil.INSERT, AssetChangeEventUtil.UPDATE, AssetChangeEventUtil.DELETE) ))
                    .addAllAncestors(Lists.newArrayList())
                    .addAllTypes(Lists.newArrayList())
                    .build();
            sendSubMsg(subAssetData);
        }
    }

    /**
     * 只退订指定的handler
     * @param handler
     */
    public void unsubscribe(IAssetHandler handler) {
        if(assetHandlerMap !=null){
            assetHandlerMap.remove(handler);
        }
        if(assetHandlerMap ==null || assetHandlerMap.isEmpty()){
            unsubscribe();
        }
    }

    public void shutdown() {
        transport = null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy