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

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

There is a newer version: 3.0.3
Show newest version
package com.envision.energy.eos.sdk;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.envision.energy.connective.common.protobuf.generated.Common.KVPair;
import com.envision.energy.connective.common.protobuf.generated.Common.KVPairRecord;
import com.envision.energy.connective.common.protobuf.generated.Common.PointAttr;
import com.envision.energy.connective.protobuf.generated.Sdk.PointDetail;
import com.envision.energy.connective.protobuf.generated.Sdk.PointInfoReq;
import com.envision.energy.connective.protobuf.generated.Sdk.SubAllData;
import com.envision.energy.connective.protobuf.generated.Sdk.SubDevData;
import com.envision.energy.connective.protobuf.generated.Sdk.SubDomainData;
import com.envision.energy.connective.protobuf.generated.Sdk.SubType;
import com.envision.energy.eos.exception.SubscribeException;
import com.envision.energy.sdk.eos.calculate.data.PointCal;
import com.envision.energy.sdk.eos.core.Point;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class DataProcessProxy {
	private static Logger logger = LoggerFactory.getLogger(DataProcessProxy.class);
	private static final String ALL = "__CLOUD*ALL*DEVICE__";
	private static final String DEFAULTDOMAIN = "__DEFAULT*DOMAIN__";

	//  > >
	private Map>>> handler2devPtSetMap = new ConcurrentHashMap<>();
	
	private Map>>> ptHandler2devPtSetMap = new ConcurrentHashMap<>();

	private Transport transport = null;
	
	public void setTransport(Transport transport) {
		this.transport = transport;
	}
	
	
	private void init(IDataHandler handler) throws NullPointerException {
		if (handler == null) {
			throw new NullPointerException("handler null");
		}
		if(transport == null) {
			throw new NullPointerException("transport null");
		}
	}
	
	private void getPtMap(Map>> dev2PtMap, 
			Map> domainPtMap, 
			Map> devPtMap) {
		for(String dev : dev2PtMap.keySet()) {
			if(dev.equals(ALL)) { //domain
				Map> domainPt = dev2PtMap.get(ALL);
				for(String domain : domainPt.keySet()) {
					Set points = domainPtMap.get(domain);
					if(points == null) {
						domainPtMap.put(domain, points = new HashSet<>());
					}
					points.addAll(domainPt.get(domain));
				}
			} else { //device
				Map> defaultDomainPt = dev2PtMap.get(dev);
				Set points = devPtMap.get(dev);
				if(points == null) {
					devPtMap.put(dev, points = new HashSet<>());
				}
				
				points.addAll(defaultDomainPt.get(DEFAULTDOMAIN));
			}
		}
	}
	
	private void sendDomainInfo(SubType subType, Map> domainPtMap) {
		if(domainPtMap.isEmpty() == false && transport.isStarted()) {
			for(String domain : domainPtMap.keySet()) {
				Set points = domainPtMap.get(domain);
				if(points.isEmpty()) {
					continue;
				}
				transport.write(SubDomainData.newBuilder()
								.setDomain(domain)
								.addAllPoints(points)
								.setSubType(subType)
								.build());
			}
		}
	}
	
	private void sendDevInfo(SubType subType, Map> devPtMap) {
		if(devPtMap.isEmpty() == false && transport.isStarted()) {
			SubDevData.Builder devBuilder = SubDevData.newBuilder();
			devBuilder.setSubType(SubType.sub);
			for(Entry> entry : devPtMap.entrySet()) {
				for(String point : entry.getValue()) {
					devBuilder.addDevPts(PointInfoReq.newBuilder()
							.setDevice(entry.getKey())
							.setPoint(point)
							.build());
				}
				
			}
			transport.write(devBuilder.build());
		}
	}
	
	public void sendSubMsg() {
		if(transport == null) {
			return;
		}
		
		SubAllData.Builder allBuilder = null;
		
		Map> domainPtMap = new HashMap<>();
		Map> ptDomainPtMap = new HashMap<>();
		Map> devPtMap = new HashMap<>(); 
		
		for(IDataHandler handler : handler2devPtSetMap.keySet()) {
			Map>> dev2Pt = handler2devPtSetMap.get(handler);
			if(dev2Pt.isEmpty()) {
				if(allBuilder == null) {
					allBuilder = SubAllData.newBuilder();
				}
			} else{
				getPtMap(dev2Pt, domainPtMap, devPtMap);
			}
		}
		
		for(Entry>>> entry : ptHandler2devPtSetMap.entrySet()) {
			if(entry.getValue().isEmpty() == false) {
				getPtMap(entry.getValue(), ptDomainPtMap, devPtMap);
			}
		}
		
		if(allBuilder != null) {
			transport.write(allBuilder.setSubType(SubType.sub).build());
			logger.info("subscribe all" + transport.isStarted());
		} else {
			sendDomainInfo(SubType.sub, domainPtMap);
			logger.info("subscribe domain: " + domainPtMap + ": " + transport.isStarted());
			
			sendDomainInfo(SubType.ptsub, ptDomainPtMap);
			logger.info("subscribe domain: " + ptDomainPtMap + ": " + transport.isStarted());
			
			sendDevInfo(SubType.sub, devPtMap);
			logger.info("subscribe dev: " + devPtMap+ ": " + transport.isStarted());
		}
	}
	
	public void msgToHandler(KVPairRecord msg) {
		try{
			for(IDataHandler handler : handler2devPtSetMap.keySet()) {
				List points = getPoint(handler2devPtSetMap.get(handler), msg);
				for(Point point : points) {
					handler.dataRead(point);
				}
			} 
		} catch(Exception e) {
			logger.error("callback err: " + e);
		}
	}
	
	public void msgToHandler(PointDetail msg) {
		try{
			Map attrs = new Gson().fromJson(
					msg.getA(), new TypeToken>(){}.getType());
			PointCal point = new PointCal(
					msg.getP(), 
					msg.getD(), 
					msg.getS(), 
					msg.getM(), 
					msg.getV(), 
					msg.getT(), 
					attrs);
			
			point.setLastValue(msg.getLv());
			point.setLastTimestamp(msg.getLt());
			point.setLastChangedValue(msg.getLcv());
			point.setLastChangedTimestamp(msg.getLct());
			
			for(Entry>>> entry : ptHandler2devPtSetMap.entrySet()) {
				
				if(validPoint(msg.getP(), msg.getD(), msg.getM(), entry.getValue())) {
					entry.getKey().pointRead(point);
				}
				
			} 
		} catch(Exception e) {
			logger.error("callback err: " + e);
		}
	}

	public void subscribe(IDataHandler handler) throws NullPointerException,
			SubscribeException {
		init(handler);

		Map>> devPtMap = getDevPtMap(handler);
		devPtMap.clear();
		
		logger.info("sub all: " + transport.isStarted());
		if(transport.isStarted()) {
			transport.write(SubAllData.newBuilder().setSubType(SubType.sub).build());
		}
	}

	public void subscribe(IDataHandler handler, Collection points)
			throws NullPointerException, SubscribeException {
		init(handler);
		if(points == null ) {
			throw new NullPointerException("points is null");
		}
		if(points.isEmpty()) {
			return;
		}

		Map>> devPtMap = getDevPtMap(handler);

		for (PointInfo pointInfo : points) {
			String devId = pointInfo.getDeviceId();
			Map> pMap = devPtMap.get(devId);
			if (pMap == null) {
				devPtMap.put(devId, pMap = new HashMap>());
			}

			Set pSet = pMap.get(DEFAULTDOMAIN);
			if (pSet == null) {
				pMap.put(DEFAULTDOMAIN, pSet = new HashSet<>());
			}

			pSet.add(pointInfo.getPointId());

		}
		SubDevData.Builder builder = SubDevData.newBuilder();
		builder.setSubType(SubType.sub);
		for(PointInfo pointInfo : points) {
			builder.addDevPts(PointInfoReq.newBuilder()
								.setDevice(pointInfo.getDeviceId())
								.setPoint(pointInfo.getPointId()));
		}
		logger.info("sub points: " + points.size() + ": " + transport.isStarted());
		if(transport.isStarted()) {
			transport.write(builder.build());
		}
	}

	public void subscribe(IDataHandler handler, Collection pointIds,
			String... domainIds) throws NullPointerException, SubscribeException {
		init(handler);

		Map>> devPtMap = getDevPtMap(handler);

		Map> pMap = devPtMap.get(ALL);
		if (pMap == null) {
			devPtMap.put(ALL, pMap = new HashMap>());
		}
		
		List domainList = null;
		if(domainIds == null || domainIds.length == 0) {
			domainList = new ArrayList<>();
			domainList.add(DEFAULTDOMAIN);
		} else {
			domainList = Arrays.asList(domainIds);
		}
		

		for(String domainId : domainList) {
			Set pSet = pMap.get(domainId);
			if (pSet == null) {
				pMap.put(domainId, pSet = new HashSet<>());
			}
	
			pSet.addAll(pointIds);
			SubDomainData.Builder builder = SubDomainData.newBuilder();
			builder.setDomain(domainId)
			.setSubType(SubType.sub)
			.addAllPoints(pointIds);
			
			logger.info("sub domain: " + domainId + ": " + transport.isStarted());
			if(transport.isStarted()) {
				transport.write(builder.build());
			}
		}
	}
	
	public void subscribe(IPointCalHandler handler,
			Collection pointIds, String... domainIds) {
		if (handler == null) {
			throw new NullPointerException("handler null");
		}
		if(transport == null) {
			throw new NullPointerException("transport null");
		}

		Map>> devPtMap = ptHandler2devPtSetMap
				.get(handler);
		if (devPtMap == null) {
			ptHandler2devPtSetMap
					.put(handler,devPtMap = new ConcurrentHashMap>>());
		}

		Map> pMap = devPtMap.get(ALL);
		if (pMap == null) {
			devPtMap.put(ALL, pMap = new HashMap>());
		}
		
		List domainList = null;
		if(domainIds == null || domainIds.length == 0) {
			domainList = new ArrayList<>();
			domainList.add(DEFAULTDOMAIN);
		} else {
			domainList = Arrays.asList(domainIds);
		}
		

		for(String domainId : domainList) {
			Set pSet = pMap.get(domainId);
			if (pSet == null) {
				pMap.put(domainId, pSet = new HashSet<>());
			}
	
			pSet.addAll(pointIds);
			SubDomainData.Builder builder = SubDomainData.newBuilder();
			builder.setDomain(domainId)
			.setSubType(SubType.ptsub)
			.addAllPoints(pointIds);
			
			logger.info("sub domain: " + domainId + ": " + transport.isStarted());
			if(transport.isStarted()) {
				transport.write(builder.build());
			}
		}
	}

	private Map>> getDevPtMap(
			IDataHandler handler) {
		Map>> devPtMap = handler2devPtSetMap
				.get(handler);
		if (devPtMap == null) {
			handler2devPtSetMap
					.put(handler,devPtMap = new ConcurrentHashMap>>());
		}

		return devPtMap;
	}

	synchronized public void unsubscribe(IDataHandler handler)
			throws NullPointerException, SubscribeException {
		if (handler == null) {
			throw new NullPointerException("handler null");
		}
		if(transport == null) {
			throw new NullPointerException("transport null");
		}
		
		try {
			//unsubscribe.
			sendUnSubInfo(handler);
			
		} catch (Exception e) {
			logger.error("exception: " + e);
			throw new SubscribeException("unsubscribe failed.");
		}
	}
	
	private void sendUnSubInfo(IDataHandler handler) {
		Map>> dev2PtMap = handler2devPtSetMap.get(handler);
		if(dev2PtMap == null) {
			return;
		}
		
		
		Map>> unsubInfo = new HashMap<>(dev2PtMap);
		handler2devPtSetMap.remove(handler);
		//unsubscribe all
		if(dev2PtMap.isEmpty()) {
			boolean unsubAll = true;
			for(IDataHandler h : handler2devPtSetMap.keySet()) {
				if(handler2devPtSetMap.get(h).isEmpty()) {
					unsubAll = false;
					break;
				}
			}
			
			if(unsubAll) {
				if(transport.isStarted()) {
					transport.write(SubAllData.newBuilder()
							.setSubType(SubType.unsub)
							.build());
				}
				return;
			}
		}
		//end unsuball 
		////////////////
		
		for(IDataHandler h : handler2devPtSetMap.keySet()) {
			if(unsubInfo.isEmpty()) {
				return;
			}
			Map>> devPts = handler2devPtSetMap.get(h);
			for(String dev : devPts.keySet()) {
				Map> domainPtMap = unsubInfo.get(dev);
				Map> domainPts = devPts.get(dev);
				if(domainPts == null || domainPtMap == null) {
					continue;
				}
				
				for(String domain : domainPts.keySet()) {
					Set unsubPoints = domainPtMap.get(domain);
					Set points = domainPts.get(domain);
					if(unsubPoints == null || points == null) {
						continue;
					}
					
					unsubPoints.removeAll(points);
					
					if(unsubPoints.isEmpty()) {
						domainPtMap.remove(domain);
					}
					
					if(domainPtMap.isEmpty()) {
						unsubInfo.remove(dev);
					}
					
				}
			}
			
		}
		
		Map> domainPtMap = new HashMap<>();
		Map> devPtMap = new HashMap<>(); 
		getPtMap(unsubInfo, domainPtMap, devPtMap);
		sendDomainInfo(SubType.unsub, domainPtMap);
		sendDevInfo(SubType.unsub, devPtMap);
	}

	public void unsubscribe(IDataHandler handler, Collection pointIds,
			String domainId) throws NullPointerException, SubscribeException {
		init(handler);

		Map>> devPtSetMap = handler2devPtSetMap.get(handler);
		if (devPtSetMap == null) {
			return;
		}
		Map> pMap = devPtSetMap.get(ALL);
		Set ptSet = pMap.get(domainId);
		if (ptSet == null) {
			return;
		}
		
		ptSet.removeAll(pointIds);
		if (ptSet.isEmpty()) {
			pMap.remove(domainId);
		}

		if (pMap.isEmpty()) {
			devPtSetMap.remove(ALL);
		}

		if (devPtSetMap.isEmpty()) {
			unsubscribe(handler);
		} else {
			Map> unsubDomainPtMap = new HashMap<>();
			unsubDomainPtMap.put(domainId, new HashSet<>(pointIds));
			
			for(IDataHandler h : handler2devPtSetMap.keySet()) {
				Set unsubPts = unsubDomainPtMap.get(domainId);
				if(unsubPts.isEmpty()) {
					break;
				}
				if(h == handler) {
					continue;
				}
				Map> domainPtMap = handler2devPtSetMap.get(h).get(ALL);
				if(domainPtMap == null) {
					continue;
				}
				Set points = domainPtMap.get(domainId);
				if(points == null) {
					continue;
				}
				
				unsubPts.removeAll(points);
 			}
			
			sendDomainInfo(SubType.unsub, unsubDomainPtMap);
		}

	}

	private List getPoint(Map>> devPtMap,
			KVPairRecord msg) {

		List points = new ArrayList();
		for(KVPair kvPair : msg.getDatasList()) {
			if(validPoint(kvPair.getPoint(), kvPair.getDeviceId(), kvPair.getDomain(), devPtMap) == false) {
				continue;
			}
			// String pointID, String deviceID, String value, long timestamp,
			// Map attributes, String domainID
			
			Map attrs = new HashMap<>();
			for(PointAttr attr : kvPair.getAttrsList()) {
				attrs.put(attr.getKey(), attr.getValue());
			}
			points.add(new Point(kvPair.getPoint(), kvPair.getDeviceId(), kvPair.getValue(), msg.getUtc(),
					attrs, kvPair.getDomain()));
		}
		
		return points;
	}

	private boolean validPoint(String pointId, String deviceId,
			String domainId, Map>> devPtMap) {
		if (devPtMap.isEmpty()) {
			return true;
		}

		if (devPtMap.containsKey(ALL)) {
			if(devPtMap.get(ALL).containsKey(DEFAULTDOMAIN)
					&& devPtMap.get(ALL).get(DEFAULTDOMAIN).contains(pointId)) {
				return true;
			}
			
			if (devPtMap.get(ALL).containsKey(domainId) == false) {
				return false;
			}

			if (devPtMap.get(ALL).get(domainId).contains(pointId) == false) {
				return false;
			}
		} else {
			if (devPtMap.containsKey(deviceId) == false) {
				// filter
				return false;
			}

			if (devPtMap.get(deviceId).get(DEFAULTDOMAIN).contains(pointId) == false) {
				// filter
				return false;
			}
		}

		return true;
	}
	
	public void shutdown() {
		transport = null;
		handler2devPtSetMap.clear();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy