分布式项目(四)Mapping Server 数据映射

上回说道CoAp client和server的实现,数据也按照既定格式发送到了kafka中,接下来就是Mapping server的实现,物理设备数据映射到抽象设备上,并赋予数据业务含义。

iot-mapping

构建iot-mapping模块,引入kafka公共模块

SourceListener

SourceListener监听Coap server 发送的原始数据,并从redis中取出web manage缓存的产品物模型和设备数据,由于redis公用的比较多,所以这也构建一个iot-redis模块,用与redis操作。

逻辑说明

  • 获取kafka中的数据转成KafkaSourceVO
  • 根据imei获取redis中的RedisDeviceVO
  • 根据productId获取RedisProductVO
  • 根据RedisProductVO中的format,确定是byte处理还是json处理
@Autowired
    private BaseRedisUtil redisUtil;
    @KafkaListener(topics = SOURCE_TOPIC)
    public void iotListener(String msg){
        System.out.println("-----------"+msg);
        KafkaSourceVO sourceVO = JSONObject.parseObject(msg,
		KafkaSourceVO.class);
        //设备信息
        RedisDeviceVO deviceVO = redisUtil.get(sourceVO.getImei());
        //产品信息
        RedisProductVO productVO = redisUtil.get(deviceVO.getProductId());
        if (EDataFormat.BYTE.getFormat().equals(productVO.getFormat())){
            analysisByte(sourceVO,productVO,deviceVO);
        }else if (EDataFormat.JSON.getFormat().equals(
		productVO.getFormat())){
            analysisJson(sourceVO,productVO,deviceVO);
        }
    }

byte 解析

  • 获取KafkaSourceVO中的原始数据data,并转成char[]
  • 获取产品物模型中的属性模型RedisPropertyVO
  • 获取属性模型,按照属性模型中定义的ofset,在原始数据char[]中获取对应的值
  • 把解析出来的数据封装为KafkaDownVO
  public void analysisByte(KafkaSourceVO sourceVO,
  RedisProductVO productVO,RedisDeviceVO deviceVO){
        char[] chars = sourceVO.getData().toCharArray();
        List<RedisPropertyVO> propertys = productVO.getPropertys();

        KafkaDownVO downVO = new KafkaDownVO();
        downVO.setDeviceId(deviceVO.getId());
        downVO.setCollTime(sourceVO.getCollTime());

        List<KafkaDownVO.PropertyData> propertyDatas = 
		new ArrayList<>(propertys.size());

        propertys.forEach(property->{
            String[] str = property.getOfset().split("-");
            int begin = Integer.valueOf(str[0]);
            int end = Integer.valueOf(str[1]);

            KafkaDownVO.PropertyData data = new KafkaDownVO.PropertyData();
            data.setPropertyId(property.getId());
            StringBuilder sb = new StringBuilder();
            for (int i = begin;i <= end; i++){
                sb.append(chars[i]);
            }
            data.setData(sb.toString());
            propertyDatas.add(data);
        });
        downVO.setDataList(propertyDatas);
        System.out.println("byte---"+downVO);
    }

json 解析

  • json定义中,物理设备发送的key与属性模型中的identifier一一对应,而在封装RedisPropertyVO的时候,为了与byte保持统一把identifier赋值给了ofset,所以这里获取属性模型,并转成Map<ofset,id> 格式。
  • KafkaSourceVO中的原始数据也序列化成map<key,value>
  • 便利属性模型对应的map(propertyMap),并从原始数据map(dataMap)取出对应的数据
  • 为了数据的统一格式,这里也把数据封装成KafkaDownVO
public void analysisJson(KafkaSourceVO sourceVO,
RedisProductVO productVO,RedisDeviceVO deviceVO){
        Map<String,Long> propertyMap = productVO.getPropertys().
		stream().collect(Collectors.toMap(RedisPropertyVO ::
		getOfset,RedisPropertyVO::getId));
        Map<String,String> dataMap = JSONObject.parseObject(
		sourceVO.getData(), HashMap.class);

        KafkaDownVO downVO = new KafkaDownVO();
        downVO.setDeviceId(deviceVO.getId());
        downVO.setCollTime(sourceVO.getCollTime());

        List<KafkaDownVO.PropertyData> propertyDatas = 
		new ArrayList<>(dataMap.size());

        dataMap.forEach((key,val)->{
            KafkaDownVO.PropertyData data = new KafkaDownVO.PropertyData();
            data.setPropertyId(propertyMap.get(key));
            data.setData(val);
            propertyDatas.add(data);
        });
        downVO.setDataList(propertyDatas);
        System.out.println("json---"+downVO);
    }

启动项目,检验一下数据是否封装正确

按iot-pt架构设计,现在需要把映射好的数据,再次写入kakfa中,供订阅费服务使用

kafka 写入

在iot-kafka模块中添加对Mapping 数据的写入

[@Component](https://my.oschina.net/u/3907912)
public class KafkaMapping {

    @Autowired
    private KafkaTemplate kafkaTemplate;

    public void send(KafkaDownVO downVO){
        String json = JSONObject.toJSONString(downVO);
        kafkaTemplate.send(DOWN_TOPIC,json);
    }

}

修改analysisByte()和analysisJson()

public void analysisByte(KafkaSourceVO sourceVO,
  RedisProductVO productVO,RedisDeviceVO deviceVO){
        char[] chars = sourceVO.getData().toCharArray();
        List<RedisPropertyVO> propertys = productVO.getPropertys();

        KafkaDownVO downVO = new KafkaDownVO();
        downVO.setDeviceId(deviceVO.getId());
        downVO.setCollTime(sourceVO.getCollTime());

        List<KafkaDownVO.PropertyData> propertyDatas = 
		new ArrayList<>(propertys.size());

        propertys.forEach(property->{
            String[] str = property.getOfset().split("-");
            int begin = Integer.valueOf(str[0]);
            int end = Integer.valueOf(str[1]);

            KafkaDownVO.PropertyData data = new KafkaDownVO.PropertyData();
            data.setPropertyId(property.getId());
            StringBuilder sb = new StringBuilder();
            for (int i = begin;i <= end; i++){
                sb.append(chars[i]);
            }
            data.setData(sb.toString());
            propertyDatas.add(data);
        });
        downVO.setDataList(propertyDatas);
       kafkaMapping.send(downVO);
    }
public void analysisJson(KafkaSourceVO sourceVO,
RedisProductVO productVO,RedisDeviceVO deviceVO){
        Map<String,Long> propertyMap = productVO.getPropertys().
		stream().collect(Collectors.toMap(RedisPropertyVO ::
		getOfset,RedisPropertyVO::getId));
        Map<String,String> dataMap = JSONObject.parseObject(
		sourceVO.getData(), HashMap.class);

        KafkaDownVO downVO = new KafkaDownVO();
        downVO.setDeviceId(deviceVO.getId());
        downVO.setCollTime(sourceVO.getCollTime());

        List<KafkaDownVO.PropertyData> propertyDatas = 
		new ArrayList<>(dataMap.size());

        dataMap.forEach((key,val)->{
            KafkaDownVO.PropertyData data = new KafkaDownVO.PropertyData();
            data.setPropertyId(propertyMap.get(key));
            data.setData(val);
            propertyDatas.add(data);
        });
        downVO.setDataList(propertyDatas);
        kafkaMapping.send(downVO);
    }

再次启动项目,教研Mapping数据是否成写入kakfa

结束语

接下来就是订阅服务的实现了,请听下回分解,具体的代码细节在git

https://gitee.com/distant/iot-pt.git

转载于:https://my.oschina.net/u/2258281/blog/3039749

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值