From dfa2003250aef488dfc29694b47da481122fa8be Mon Sep 17 00:00:00 2001 From: yang_shj <1069818635@QQ.com> Date: Thu, 14 Sep 2023 11:08:08 +0800 Subject: [PATCH] =?UTF-8?q?#=E5=91=8A=E8=AD=A6=E4=BB=A3=E7=A0=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hnac/hzims/alarm/constants/AlarmConstants.java | 3 - .../com/hnac/hzims/alarm/entity/AlarmEntity.java | 2 +- .../com/hnac/hzims/alarm/vo/LevelMessageVo.java | 20 ++++ .../main/java/com/hnac/hzims/alarm/vo/LevelVo.java | 38 +++++++ .../hzims/equipment/vo/EminfoAndEmParamVo.java | 6 + .../alarm/show/service/LevelAlarmService.java | 12 ++ .../hzims/alarm/show/service/MessageService.java | 15 +++ .../show/service/impl/LevelAlarmServiceImpl.java | 117 +++++++++++++++++++ .../show/service/impl/MessageServiceImpl.java | 44 ++++++++ .../hzims/alarm/ws/hz3000/SystemAlarmRegular.java | 2 +- .../alarm/ws/hz3000/SystemAlarmWebSocket.java | 2 +- .../hzims/alarm/ws/level/LevelAlarmRegular.java | 59 ++++++++++ .../hzims/alarm/ws/level/LevelAlarmWebSocket.java | 125 +++++++++++++++++++++ .../operation/home/impl/RealTargetServiceImpl.java | 10 ++ 14 files changed, 449 insertions(+), 6 deletions(-) create mode 100644 hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelMessageVo.java create mode 100644 hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelVo.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/LevelAlarmService.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/MessageService.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/LevelAlarmServiceImpl.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/MessageServiceImpl.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmRegular.java create mode 100644 hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmWebSocket.java diff --git a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/constants/AlarmConstants.java b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/constants/AlarmConstants.java index 209a88d..7be1a2c 100644 --- a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/constants/AlarmConstants.java +++ b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/constants/AlarmConstants.java @@ -1,8 +1,5 @@ package com.hnac.hzims.alarm.constants; -import com.sun.org.apache.bcel.internal.generic.NEW; - -import java.util.ArrayList; import java.util.Arrays; import java.util.List; diff --git a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/entity/AlarmEntity.java b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/entity/AlarmEntity.java index 2e008d1..1021c07 100644 --- a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/entity/AlarmEntity.java +++ b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/entity/AlarmEntity.java @@ -64,5 +64,5 @@ public class AlarmEntity extends TenantEntity { private Date alarmTime; @ApiModelProperty(value = "监测点") - private Date realId; + private String realId; } \ No newline at end of file diff --git a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelMessageVo.java b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelMessageVo.java new file mode 100644 index 0000000..6099f55 --- /dev/null +++ b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelMessageVo.java @@ -0,0 +1,20 @@ +package com.hnac.hzims.alarm.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author ysj + */ +@Data +public class LevelMessageVo { + + @ApiModelProperty(value = "站点编码:用逗号分隔") + private String projectIds; + + @ApiModelProperty(value = "类型") + private String type; + + @ApiModelProperty(value = "开始时间") + private String startTime; +} \ No newline at end of file diff --git a/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelVo.java b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelVo.java new file mode 100644 index 0000000..8170951 --- /dev/null +++ b/hzims-service-api/alarm-api/src/main/java/com/hnac/hzims/alarm/vo/LevelVo.java @@ -0,0 +1,38 @@ +package com.hnac.hzims.alarm.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author ysj + */ +@Data +public class LevelVo { + + @ApiModelProperty(value = "告警Id") + private String id; + + @ApiModelProperty(value = "告警时间") + private String ts; + + @ApiModelProperty(value = "设备编码") + private String devicecode; + + @ApiModelProperty(value = "设备名称") + private String devicename; + + @ApiModelProperty(value = "告警内容") + private String name; + + @ApiModelProperty(value = "告警类型") + private Integer type; + + @ApiModelProperty(value = "告警等级") + private Integer level; + + @ApiModelProperty(value = "告警发生时,设备实时数据") + private String context; + + @ApiModelProperty(value = "事件标识") + private String signage; +} \ No newline at end of file diff --git a/hzims-service-api/equipment-api/src/main/java/com/hnac/hzims/equipment/vo/EminfoAndEmParamVo.java b/hzims-service-api/equipment-api/src/main/java/com/hnac/hzims/equipment/vo/EminfoAndEmParamVo.java index c7c4fe5..6117636 100644 --- a/hzims-service-api/equipment-api/src/main/java/com/hnac/hzims/equipment/vo/EminfoAndEmParamVo.java +++ b/hzims-service-api/equipment-api/src/main/java/com/hnac/hzims/equipment/vo/EminfoAndEmParamVo.java @@ -42,4 +42,10 @@ public class EminfoAndEmParamVo extends EmInfoExtendVo { @ApiModelProperty(value = "机组运行状态") private Integer ord; + + @ApiModelProperty(value = "站点编码") + private String stationCode; + + @ApiModelProperty(value = "站点名称") + private String stationName; } diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/LevelAlarmService.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/LevelAlarmService.java new file mode 100644 index 0000000..01696b8 --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/LevelAlarmService.java @@ -0,0 +1,12 @@ +package com.hnac.hzims.alarm.show.service; + +/** + * 等级处理接口 + * @author ysj + */ +public interface LevelAlarmService { + + String message(); + + void receive(String message); +} \ No newline at end of file diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/MessageService.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/MessageService.java new file mode 100644 index 0000000..1e27dc0 --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/MessageService.java @@ -0,0 +1,15 @@ +package com.hnac.hzims.alarm.show.service; + +import com.hnac.hzims.alarm.entity.AlarmEntity; + +/** + * @author ysj + */ +public interface MessageService { + + void message(AlarmEntity entity); + + void webAppMessage(AlarmEntity entity); + + void weChatMessage(AlarmEntity entity); +} \ No newline at end of file diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/LevelAlarmServiceImpl.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/LevelAlarmServiceImpl.java new file mode 100644 index 0000000..663332c --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/LevelAlarmServiceImpl.java @@ -0,0 +1,117 @@ +package com.hnac.hzims.alarm.show.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.hnac.hzims.alarm.constants.AlarmConstants; +import com.hnac.hzims.alarm.entity.AlarmEntity; +import com.hnac.hzims.alarm.show.service.AlarmService; +import com.hnac.hzims.alarm.show.service.LevelAlarmService; +import com.hnac.hzims.alarm.show.service.MessageService; +import com.hnac.hzims.alarm.vo.LevelMessageVo; +import com.hnac.hzims.alarm.vo.LevelVo; +import com.hnac.hzims.equipment.feign.IEmInfoClient; +import com.hnac.hzims.equipment.vo.EminfoAndEmParamVo; +import com.hnac.hzims.operational.station.entity.StationEntity; +import com.hnac.hzims.operational.station.feign.IStationClient; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tool.api.R; +import org.springblade.core.tool.utils.CollectionUtil; +import org.springblade.core.tool.utils.DateUtil; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +/** + * 等级告警实现类 + * @author ysj + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class LevelAlarmServiceImpl implements LevelAlarmService { + + private final AlarmService alarmService; + + private final MessageService messageService; + + private final RedisTemplate redisTemplate; + + private final IEmInfoClient deviceClient; + + private final IStationClient stationClient; + + public final static String device_cache_cofig_final = "hzims:equipment:emInfo:deviceCode.emInfoList"; + + /** + * 发生websocket消息 + * @return + */ + @Override + public String message() { + StationEntity station = new StationEntity(); + station.setDataOrigin("0"); + // 站点 + R> result = stationClient.list(station); + if(!result.isSuccess() || CollectionUtil.isEmpty(result.getData())){ + log.error("level alarm send message station is null"); + return ""; + } + LevelMessageVo message = new LevelMessageVo(); + message.setProjectIds(result.getData().stream().map(StationEntity::getCode).collect(Collectors.joining(","))); + message.setType(AlarmConstants.HZ3000_ALARAM.stream().map(String::valueOf).collect(Collectors.joining(","))); + message.setStartTime(DateUtil.format(new Date(),DateUtil.PATTERN_DATE) + " 00:00:00"); + return JSONObject.toJSONString(message); + } + + /** + * 处理websocket消息 + * @param message + */ + @Override + public void receive(String message) { + // 对象转换 + List levels = JSONObject.parseArray(message,LevelVo.class); + if(CollectionUtil.isEmpty(levels)){ + return; + } + // 设备 + List devices = JSONObject.parseObject(redisTemplate.opsForValue().get(device_cache_cofig_final).toString(),new TypeReference>() {}); + // 查询已经保存等级告警数据 + List records = alarmService.list(Wrappers.lambdaQuery() + .ge(AlarmEntity::getAlarmSource,AlarmConstants.LEVEL_ALARM) + .in(AlarmEntity::getAlarmId,levels.stream().map(LevelVo::getId).collect(Collectors.toList())) + ); + // 遍历等级告警数据 + levels.stream().filter(o-> CollectionUtil.isEmpty(records) || !records.stream().map(AlarmEntity::getAlarmId).collect(Collectors.toList()).contains(o.getId())). + forEach(level->{ + AlarmEntity entity = new AlarmEntity(); + entity.setAlarmSource(AlarmConstants.LEVEL_ALARM); + entity.setAlarmId(level.getId()); + entity.setAlarmTime(DateUtil.parse(level.getTs(), "yyyy-MM-dd HH:mm:ss.s")); + entity.setAlarmType(level.getType()); + entity.setRealId(level.getSignage()); + entity.setAlarmContext(level.getName()); + entity.setDeviceCode(level.getDevicecode()); + entity.setDeviceName(level.getDevicename()); + entity.setAlarmLevel(level.getLevel()); + List ems = devices.stream().filter(o->level.getDevicecode().equals(o.getEmCode())).collect(Collectors.toList()); + if(CollectionUtil.isNotEmpty(ems)){ + entity.setStationId(ems.get(0).getStationCode()); + entity.setDeviceName(ems.get(0).getStationName()); + } + this.alarmService.save(entity); + // 短信 + CompletableFuture.runAsync(() -> this.messageService.message(entity)); + // web/app消息推送 + CompletableFuture.runAsync(() -> this.messageService.webAppMessage(entity)); + // 微信公众号推送 + CompletableFuture.runAsync(() -> this.messageService.weChatMessage(entity)); + }); + } +} \ No newline at end of file diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/MessageServiceImpl.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/MessageServiceImpl.java new file mode 100644 index 0000000..02440d8 --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/show/service/impl/MessageServiceImpl.java @@ -0,0 +1,44 @@ +package com.hnac.hzims.alarm.show.service.impl; + +import com.hnac.hzims.alarm.entity.AlarmEntity; +import com.hnac.hzims.alarm.show.service.MessageService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 消息推送实现类 + * @author ysj + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class MessageServiceImpl implements MessageService { + + /** + * 短信推送 + * @param entity : 告警对象 + */ + @Override + public void message(AlarmEntity entity) { + + } + + /** + * web/app消息推送 + * @param entity : 告警对象 + */ + @Override + public void webAppMessage(AlarmEntity entity) { + + } + + /** + * 微信公众号消息推送 + * @param entity + */ + @Override + public void weChatMessage(AlarmEntity entity) { + + } +} \ No newline at end of file diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmRegular.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmRegular.java index 72008ad..4534401 100644 --- a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmRegular.java +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmRegular.java @@ -13,7 +13,7 @@ import java.net.URI; /** * 等级告警获取数据长链接 - * @author ysj + * @author ty */ @Slf4j @Component diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmWebSocket.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmWebSocket.java index f937f50..83da5d4 100644 --- a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmWebSocket.java +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/hz3000/SystemAlarmWebSocket.java @@ -18,7 +18,7 @@ import java.util.Optional; /** * 等级告警获取数据长链接 - * @author ysj + * @author ty */ @Slf4j public class SystemAlarmWebSocket extends WebSocketClient { diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmRegular.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmRegular.java new file mode 100644 index 0000000..fe347d3 --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmRegular.java @@ -0,0 +1,59 @@ +package com.hnac.hzims.alarm.ws.level; + +import com.hnac.hzims.alarm.show.service.LevelAlarmService; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.tool.utils.ObjectUtil; +import org.springblade.core.tool.utils.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.net.URI; + +/** + * @author ysj + */ +@Slf4j +@Component +@EnableScheduling +public class LevelAlarmRegular { + + @Autowired + private LevelAlarmService levelService; + + private LevelAlarmWebSocket socket; + + @Value("${hzims.level.ws-url}") + private String level_wss_url; + + // 两分钟进行一次检查链接是否存活,不存活了重新建立链接 + @Scheduled(cron = "0 0/2 * * * ?") + private void regular(){ + // 检查链接存活状态 + if(ObjectUtil.isEmpty(socket) || !socket.isOpen()){ + log.error("level websocket survival check : {}","死亡"); + this.createSocket(); + if(ObjectUtil.isNotEmpty(socket) && socket.isOpen()){ + String message = levelService.message(); + if(!StringUtil.isEmpty(message)){ + socket.send(message); + } + } + log.error("level websocket survival check : {}","重新建立链接"); + }else{ + log.error("level websocket survival check : {}","存活"); + } + } + + // 创建websocket链接 + private void createSocket() { + try{ + socket = new LevelAlarmWebSocket(new URI(level_wss_url)); + socket.connectBlocking(); + }catch (Exception e){ + log.error("level create error : {}",e.getMessage()); + } + } +} \ No newline at end of file diff --git a/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmWebSocket.java b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmWebSocket.java new file mode 100644 index 0000000..c9008a8 --- /dev/null +++ b/hzims-service/hzims-alarm/src/main/java/com/hnac/hzims/alarm/ws/level/LevelAlarmWebSocket.java @@ -0,0 +1,125 @@ +package com.hnac.hzims.alarm.ws.level; + +import com.hnac.hzims.alarm.show.service.LevelAlarmService; +import lombok.extern.slf4j.Slf4j; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.springblade.core.tool.utils.SpringUtil; +import org.springblade.core.tool.utils.StringUtil; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.net.Socket; +import java.net.URI; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.Optional; + +/** + * @author ysj + */ +@Slf4j +public class LevelAlarmWebSocket extends WebSocketClient { + + + private final LevelAlarmService levelService; + + /** + * 构造等级告警websocket + * @param uri + */ + public LevelAlarmWebSocket(URI uri) { + super(uri); + levelService = SpringUtil.getBean(LevelAlarmService.class); + connection(this); + } + + // 链接到服务器回调接口 + @Override + public void onOpen(ServerHandshake handshakedata) { + log.error("systemAlarm websocket open"); + } + + // 接收到服务器消息回调接口 + @Override + public void onMessage(String message) { + if(StringUtil.isEmpty(message)){ + log.error("level alarm on message is null"); + }else{ + // 等级告警数据处理 + levelService.receive(message); + } + } + + // 与服务器链接中断回调接口 + @Override + public void onClose(int code, String reason, boolean remote) { + log.error("level alarm websocket close"); + } + + // 与服务器通讯异常触发 + @Override + public void onError(Exception e) { + log.error("level alarm websocket error : {}",e.getMessage()); + } + + /** + * 建立链接 + * @param webSocket + */ + private void connection(LevelAlarmWebSocket webSocket) { + SSLContext context = init(); + if(Optional.ofNullable(context).isPresent()){ + Socket socket = create(context); + if(Optional.ofNullable(socket).isPresent()){ + webSocket.setSocket(socket); + } + } + } + + /** + * 创建Socket + * @param context + * @return + */ + private Socket create(SSLContext context) { + Socket socket = null; + try{ + socket = context.getSocketFactory().createSocket(); + }catch (Exception e){ + log.error("level alarm socket create error : {}",e.getMessage()); + } + return socket; + } + + /** + * 协议初始化 + * @return SSLContext + */ + private SSLContext init() { + SSLContext SSL = null; + try{ + SSL = SSLContext.getInstance("TLS"); + SSL.init(null, new TrustManager[]{new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, + String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }}, new SecureRandom()); + }catch (Exception e){ + log.error("level alarm SSL init error : {}",e.getMessage()); + } + return SSL; + } + +} \ No newline at end of file diff --git a/hzims-service/hzims-scheduled/src/main/java/com/hnac/hzims/scheduled/service/operation/home/impl/RealTargetServiceImpl.java b/hzims-service/hzims-scheduled/src/main/java/com/hnac/hzims/scheduled/service/operation/home/impl/RealTargetServiceImpl.java index 72f3c2f..f06496d 100644 --- a/hzims-service/hzims-scheduled/src/main/java/com/hnac/hzims/scheduled/service/operation/home/impl/RealTargetServiceImpl.java +++ b/hzims-service/hzims-scheduled/src/main/java/com/hnac/hzims/scheduled/service/operation/home/impl/RealTargetServiceImpl.java @@ -103,6 +103,8 @@ public class RealTargetServiceImpl implements RealTargetService { @Override public void loadEmInfo() { + List stations = stationService.list(Wrappers.lambdaQuery() + .eq(StationEntity::getDataOrigin,"0")); // 查询所有首页展示/状态非删除设备 List devices = deviceService.device(); // 查询所有设备(ct、pt、installedCapacity)配置参数 @@ -130,6 +132,14 @@ public class RealTargetServiceImpl implements RealTargetService { devices.forEach(item->{ item.setRideCount(1); item.setInstalledCapacity(0.0); + // 站点设置 + if(CollectionUtil.isNotEmpty(stations)){ + List list = stations.stream().filter(o->item.getCreateDept().equals(o.getRefDept())).collect(Collectors.toList()); + if(CollectionUtil.isEmpty(list)){ + item.setStationCode(list.get(0).getCode()); + item.setStationName(list.get(0).getName()); + } + } List signages = analys.stream().filter(o-> item.getEmCode().equals(o.getDeviceCode()) && !StringUtil.isEmpty(o.getSignage()) && !StringUtil.isEmpty(o.getRealId())).collect(Collectors.toList()); if(CollectionUtil.isNotEmpty(signages)){ // list -> map