1 package org.onap.msb.apiroute.wrapper.util;
3 import java.util.HashMap;
4 import java.util.HashSet;
8 import java.util.regex.Pattern;
10 import org.apache.commons.lang3.StringUtils;
11 import org.onap.msb.apiroute.api.MicroServiceFullInfo;
12 import org.onap.msb.apiroute.api.Node;
13 import org.onap.msb.apiroute.wrapper.consulextend.model.health.Service;
14 import org.onap.msb.apiroute.wrapper.consulextend.model.health.ServiceHealth;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
18 import com.orbitz.consul.model.health.HealthCheck;
22 public class ServiceFilter {
23 private static ServiceFilter instance = new ServiceFilter();
25 private ServiceFilter() {}
27 public static ServiceFilter getInstance() {
31 private static final Logger LOGGER = LoggerFactory.getLogger(ServiceFilter.class);
35 * Determine whether the service needs to send a notification TODO: filter according to the
36 * agreement, the only notice of agreement for REST \HTTP\ UI interface MSB - REST
41 public boolean isNeedNotifyByProtocol(String protocol) {
42 return CommonUtil.contain(RouteUtil.FILTER_PROTOCOLS, protocol.trim());
46 * Determine whether the service needs to send a notification TODO: according to the visual range
47 * filter conditions Regular language: all 、 default 、 !default 、 A、 |A 、 A|B、 !A&!B
52 public boolean isNeedNotifyByNameSpace(String nameSpace) {
54 String namespaceMatches = ConfigUtil.getInstance().getNamespaceMatches();
55 String[] namespaceArray = StringUtils.split(namespaceMatches, "|");
57 if (CommonUtil.contain(namespaceArray, "all")) {
61 if (CommonUtil.contain(namespaceArray, "default")) {
62 if (StringUtils.isEmpty(nameSpace) || "default".equals(nameSpace) ) {
69 if (CommonUtil.contain(namespaceArray, "!default")) {
70 if (StringUtils.isNotEmpty(nameSpace) && !"default".equals(nameSpace)) {
78 if (namespaceMatches.contains("!")) {
79 namespaceReg = "^" + namespaceMatches.replaceAll("!", "").replaceAll("&", "|") + "$";
80 return !Pattern.matches(namespaceReg, nameSpace);
82 namespaceReg = "^" + namespaceMatches + "$";
83 return Pattern.matches(namespaceReg, nameSpace);
86 } catch (Exception e) {
87 LOGGER.error(" Regular " + namespaceMatches + " throw exception:" + e.getMessage());
92 public boolean isNeedNotifyByVisualRange(String visualRange) {
94 String[] routeVisualRangeArray =
95 StringUtils.split(ConfigUtil.getInstance().getVisualRangeMatches(), "|");
97 String[] serviceVisualRangeArray = StringUtils.split(visualRange, "|");
99 if (CommonUtil.contain(serviceVisualRangeArray, routeVisualRangeArray)) {
107 public boolean isNeedNotifyByNetwork_plane_typeMatches(String network_plane_type) {
109 String network_plane_typeMatches = ConfigUtil.getInstance().getNetwork_plane_typeMatches();
110 if (StringUtils.isBlank(network_plane_typeMatches))
113 String[] routeNetwork_plane_typeArray = StringUtils.split(network_plane_typeMatches, "|");
115 String[] serviceVisualRangeArray = StringUtils.split(network_plane_type, "|");
117 if (CommonUtil.contain(serviceVisualRangeArray, routeNetwork_plane_typeArray)) {
126 * Determine whether the service needs to send a notification TODO: according to the visual range
132 public boolean isNeedNotifyByRouteLabels(Map<String, String> labelMap) {
134 Map<String, String> labelMapMatches = ConfigUtil.getInstance().getLabelMapMatches();
136 if (labelMapMatches == null || labelMapMatches.isEmpty()) {
140 for (Map.Entry<String, String> entry : labelMapMatches.entrySet()) {
141 String key = entry.getKey();
142 String value = entry.getValue();
144 // Multiple values match
146 if (StringUtils.isBlank(labelMap.get(key))) {
150 String[] routeLalelsArray = StringUtils.split(value, "|");
152 String[] serviceLabelsArray = StringUtils.split(labelMap.get(key), "|");
154 if (CommonUtil.contain(routeLalelsArray, serviceLabelsArray)) {
166 * public boolean isNeedNotifyByRoute(String protocol, String namespace, String visualRange,
167 * String network_plane_type, Map<String, String> labelMap) {
169 * return isNeedNotifyByProtocol(protocol) && isNeedNotifyByNameSpace(namespace) &&
170 * isNeedNotifyByVisualRange(visualRange) && isNeedNotifyByRouteLabels(labelMap) &&
171 * isNeedNotifyByNetwork_plane_typeMatches(network_plane_type);
176 public boolean isFilterCheck(ServiceHealth health){
177 return isFilterHealthCheck(health.getChecks()) && isFilterService(health.getService().getTags());
181 * @Title isFilterHealthCheck
182 * @Description TODO(判断服务实例的健康检查信息,全部为passing表示健康检查有效)
183 * @param List<HealthCheck>
184 * @return boolean checkList示例——"Checks" : [{
186 "CheckID" : "serfHealth",
187 "Name" : "Serf Health Status",
188 "Status" : "passing",
190 "Output" : "Agent alive and reachable",
193 "CreateIndex" : 65536,
194 "ModifyIndex" : 65536
197 "CheckID" : "service:_tcp_roundrobin_1_10.74.151.26_22",
198 "Name" : "Service 'tcp_roundrobin_1' check",
199 "Status" : "critical",
201 "Output" : "dial tcp: missing port in address ok",
202 "ServiceID" : "_tcp_roundrobin_1_10.74.151.26_22",
203 "ServiceName" : "tcp_roundrobin_1",
204 "CreateIndex" : 75988,
205 "ModifyIndex" : 76173
209 public boolean isFilterHealthCheck(List<HealthCheck> checkList){
210 if(checkList.isEmpty()){
214 for (HealthCheck check : checkList) {
215 if (!RouteUtil.HEALTH_CHECK_PASSING.equals(check.getStatus())) {
226 * @Title isFilterService
227 * @Description TODO(判断来自consul的服务信息是否需要过滤)
228 * @param List<String>
229 * @return boolean tagList示例—— [
230 * "\"base\":{\"protocol\":\"REST\",\"is_manual\":\"true\",\"version\":\"v1\",\"url\":\"/api/msbtest/v1\"}"
231 * , "\"ns\":{\"namespace\":\"nsName\"}",
232 * "\"labels\":{\"visualRange\":\"0\",\"network_plane_type\":\"net\",\"customLabel\":\"custom\"}"
235 @SuppressWarnings("unchecked")
236 public boolean isFilterService(List<String> tagList) {
238 if (tagList == null || tagList.size() == 0)
241 String visualRange = "", network_plane_type = "", protocol = "", namespace = "";
243 //针对多版本不同属性的tag会有多个,只要其中一个匹配即通过过滤,默认不通过
244 boolean visualRangeFilter=false,protocolFilter = false, namespaceFilter = false;
245 boolean hasnamespace=false;
249 for (String tag : tagList) {
252 if (!protocolFilter && tag.startsWith("\"base\"")) {
253 String ms_base_json = tag.split("\"base\":")[1];
255 Map<String, String> baseMap =
256 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
258 if (baseMap.get("protocol") != null) {
259 protocol = baseMap.get("protocol");
260 if ("PORTAL".equalsIgnoreCase(protocol)) {
264 if (isNeedNotifyByProtocol(protocol)) {
276 if (!namespaceFilter && tag.startsWith("\"ns\"")) {
277 String ms_ns_json = tag.split("\"ns\":")[1];
278 Map<String, String> nsMap =
279 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
281 if (nsMap.get("namespace") != null) {
282 namespace = nsMap.get("namespace");
285 if (isNeedNotifyByNameSpace(namespace)) {
286 namespaceFilter=true;
295 if (tag.startsWith("\"labels\"")) {
296 String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
298 Map<String, String> labelMap =
299 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
303 if (!visualRangeFilter && labelMap.get("visualRange") != null) {
304 visualRange = labelMap.get("visualRange");
305 labelMap.remove("visualRange"); // 自定义标签排除可见范围和网络平面
307 if(isNeedNotifyByVisualRange(visualRange)){
308 visualRangeFilter=true;
313 if (labelMap.get("network_plane_type") != null) {
314 network_plane_type = labelMap.get("network_plane_type");
315 labelMap.remove("network_plane_type");
317 if (!isNeedNotifyByNetwork_plane_typeMatches(network_plane_type)) {
321 if (!isNeedNotifyByRouteLabels(labelMap)) {
331 if (!hasnamespace && isNeedNotifyByNameSpace(namespace)) {
332 namespaceFilter=true;
335 return visualRangeFilter && protocolFilter && namespaceFilter;
338 } catch (Exception e) {
339 LOGGER.error(" read tag throw exception", e);
348 @SuppressWarnings("unchecked")
349 public Map<String, MicroServiceFullInfo> transMicroServiceInfoFromConsul(
350 List<ServiceHealth> serviceNodeList) {
352 Map<String, MicroServiceFullInfo> microServiceInfo4version =
353 new HashMap<String, MicroServiceFullInfo>();
356 for (ServiceHealth serviceNode : serviceNodeList) {
358 MicroServiceFullInfo microServiceInfo = new MicroServiceFullInfo();
360 String version = "", visualRange = "", protocol = "", lb_policy = "", namespace =
361 "", host = "", path = "", publish_port = "";
362 boolean enable_ssl = false;
364 HashSet<Node> nodes = new HashSet<Node>();
366 Service service = serviceNode.getService();
367 String serviceName = service.getService();
370 List<String> tagList = service.getTags();
372 for (String tag : tagList) {
374 if (tag.startsWith("\"base\"")) {
375 String ms_base_json = tag.split("\"base\":")[1];
378 Map<String, String> baseMap =
379 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
380 if (baseMap.get("url") != null) {
381 url = baseMap.get("url");
384 if (baseMap.get("version") != null) {
385 version = baseMap.get("version");
388 if (baseMap.get("protocol") != null) {
389 protocol = baseMap.get("protocol");
392 if (baseMap.get("host") != null) {
393 host = baseMap.get("host");
396 if (baseMap.get("path") != null) {
397 path = baseMap.get("path");
400 if (baseMap.get("publish_port") != null) {
401 publish_port = baseMap.get("publish_port");
405 if (baseMap.get("enable_ssl") != null) {
406 enable_ssl = Boolean.valueOf(baseMap.get("enable_ssl"));
414 if (tag.startsWith("\"ns\"")) {
415 String ms_ns_json = tag.split("\"ns\":")[1];
416 Map<String, String> nsMap =
417 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
419 if (nsMap.get("namespace") != null) {
420 namespace = nsMap.get("namespace");
426 if (tag.startsWith("\"labels\"")) {
427 String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
428 Map<String, String> labelMap =
429 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
432 if (labelMap.get("visualRange") != null) {
433 visualRange = labelMap.get("visualRange");
436 /*if (labelMap.get("network_plane_type") != null) {
437 network_plane_type = labelMap.get("network_plane_type");
443 if (tag.startsWith("\"lb\"")) {
444 String ms_lb_json = tag.split("\"lb\":")[1];
445 Map<String, String> lbMap =
446 (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_lb_json, Map.class);
448 if (lbMap.get("lb_policy") != null) {
449 lb_policy = lbMap.get("lb_policy");
458 } catch (Exception e) {
459 LOGGER.error(serviceName + " read tag throw exception", e);
462 if (!microServiceInfo4version.containsKey(version)) {
464 if ("PORTAL".equalsIgnoreCase(protocol)) {
466 microServiceInfo.setCustom(RouteUtil.CUSTOM_PORTAL);
469 microServiceInfo.setProtocol(protocol);
470 microServiceInfo.setUrl(url);
471 microServiceInfo.setServiceName(serviceName);
472 microServiceInfo.setLb_policy(lb_policy);
473 microServiceInfo.setVisualRange(visualRange);
475 microServiceInfo.setEnable_ssl(enable_ssl);
476 microServiceInfo.setVersion(version);
477 microServiceInfo.setNamespace(namespace);
478 microServiceInfo.setHost(host);
479 microServiceInfo.setPath(path);
480 //系统间apigateway 保存publish_port
481 if ("0".equals(ConfigUtil.getInstance().getVisualRangeMatches())) {
482 microServiceInfo.setPublish_port(publish_port);
485 nodes.add(new Node(service.getAddress(), String.valueOf(service.getPort())));
486 microServiceInfo.setNodes(nodes);
488 microServiceInfo4version.put(version, microServiceInfo);
491 Set<Node> newNodes = microServiceInfo4version.get(version).getNodes();
492 // 默认node是注册信息的IP和port
493 newNodes.add(new Node(service.getAddress(), String.valueOf(service.getPort())));
496 microServiceInfo4version.get(version).setNodes(newNodes);
502 * // 健康检查信息 List<Check> checks = value.getChecks(); node.setStatus("passing"); for (Check
503 * check : checks) { if (!"passing".equals(check.getStatus())) {
504 * node.setStatus(check.getStatus()); break; } }
511 return microServiceInfo4version;