2 * Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package org.openo.msb.wrapper.util;
\r
19 import java.sql.Date;
\r
20 import java.util.ArrayList;
\r
21 import java.util.HashMap;
\r
22 import java.util.HashSet;
\r
23 import java.util.List;
\r
24 import java.util.Map;
\r
25 import java.util.Set;
\r
26 import java.util.regex.Matcher;
\r
27 import java.util.regex.Pattern;
\r
29 import org.apache.commons.lang3.StringUtils;
\r
30 import org.openo.msb.api.MicroServiceFullInfo;
\r
31 import org.openo.msb.api.MicroServiceInfo;
\r
32 import org.openo.msb.api.Node;
\r
33 import org.openo.msb.api.NodeInfo;
\r
34 import org.openo.msb.api.Service;
\r
35 import org.openo.msb.wrapper.serviceListener.IMicroServiceChangeListener;
\r
36 import org.slf4j.Logger;
\r
37 import org.slf4j.LoggerFactory;
\r
39 import redis.clients.jedis.Jedis;
\r
41 public class MicroServiceDB {
\r
43 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceDB.class);
\r
45 private static MicroServiceDB instance = new MicroServiceDB();
\r
47 private List<IMicroServiceChangeListener> serviceListenerlist =
\r
48 new ArrayList<IMicroServiceChangeListener>();
\r
50 private MicroServiceDB() {}
\r
52 public static MicroServiceDB getInstance() {
\r
57 public void addServiceChangeListener(IMicroServiceChangeListener listener) {
\r
58 synchronized (serviceListenerlist) {
\r
59 serviceListenerlist.add(listener);
\r
64 public void removeServiceChangeListener(IMicroServiceChangeListener listener) {
\r
65 synchronized (serviceListenerlist) {
\r
66 serviceListenerlist.remove(listener);
\r
71 public MicroServiceFullInfo[] getAllMicroServiceInstances() throws Exception {
\r
73 MicroServiceFullInfo[] microServiceList;
\r
75 jedis = JedisUtil.getJedis();
\r
78 MicroServiceUtil.getPrefixedKey("","*", MicroServiceUtil.SUFFIX_PATH_INFO);
\r
79 Set<String> serviceSet = jedis.keys(routekey);
\r
80 microServiceList = new MicroServiceFullInfo[serviceSet.size()];
\r
82 Pattern redisKeyPattern = MicroServiceUtil.getRedisKeyPattern();
\r
84 for (String servicePath : serviceSet) {
\r
85 Matcher matcher = redisKeyPattern.matcher(servicePath);
\r
86 if (matcher.matches()) {
\r
87 microServiceList[i] = getMicroServiceByJedis(jedis, matcher.group("servicename"),matcher.group("version"), "");
\r
91 } catch (Exception e) {
\r
92 LOGGER.error("call redis throw exception", e);
\r
93 throw new Exception("call redis throw exception:"+e.getMessage());
\r
95 JedisUtil.returnJedisInstance(jedis);
\r
98 return microServiceList;
\r
101 public void saveMicroServiceInfo2Redis(MicroServiceInfo microServiceInfo,String serverPort) throws Exception {
\r
103 String serviceInfokey =
\r
104 MicroServiceUtil.getServiceInfoKey(serverPort,microServiceInfo.getServiceName(),
\r
105 microServiceInfo.getVersion());
\r
106 Map<String, String> serviceInfoMap = new HashMap<String, String>();
\r
107 serviceInfoMap.put("url", microServiceInfo.getUrl());
\r
108 serviceInfoMap.put("protocol", microServiceInfo.getProtocol());
\r
109 serviceInfoMap.put("visualRange",microServiceInfo.getVisualRange());
\r
110 serviceInfoMap.put("lb_policy",microServiceInfo.getLb_policy());
\r
111 serviceInfoMap.put("status", "0");
\r
116 String serviceLBkey =
\r
117 MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),
\r
118 microServiceInfo.getVersion(), MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
\r
121 Jedis jedis = null;
\r
123 jedis = JedisUtil.getJedis();
\r
125 jedis.hmset(serviceInfokey, serviceInfoMap);
\r
128 for(Node node:microServiceInfo.getNodes()){
\r
130 String key=serviceLBkey+":"+node.getIp()+"-"+node.getPort();
\r
132 Map<String,String> nodeMap = new HashMap<String,String>();
\r
134 nodeMap.put("ip", node.getIp());
\r
135 nodeMap.put("port", node.getPort());
\r
136 nodeMap.put("ttl", Integer.toString(node.getTtl()));
\r
137 long expiration_time=System.currentTimeMillis()+node.getTtl()*1000;
\r
138 nodeMap.put("expiration", Long.toString(expiration_time));
\r
140 if(jedis.keys(key).isEmpty()){
\r
141 nodeMap.put("created_at", Long.toString(System.currentTimeMillis()));
\r
144 // Map<String,String> nodeLBmap = jedis.hgetAll(key);
\r
145 // nodeMap.put("created_at", nodeLBmap.get("created_at"));
\r
147 nodeMap.put("updated_at", Long.toString(System.currentTimeMillis()));
\r
149 jedis.hmset(key, nodeMap);
\r
152 // jedis.sadd(serviceLBkey, nodeArray);
\r
154 } catch (Exception e) {
\r
155 LOGGER.error("save to redis throw exception", e);
\r
156 throw new Exception("save to redis throw exception:"+e.getMessage());
\r
158 JedisUtil.returnJedisInstance(jedis);
\r
165 public void updateMicroServiceStatus(String serviceName, String version,String status) throws Exception{
\r
168 String serviceInfokey = MicroServiceUtil.getServiceInfoKey("",serviceName, version);
\r
169 Map<String, String> serviceInfoMap = new HashMap<String, String>();
\r
170 serviceInfoMap.put("status", status);
\r
173 Jedis jedis = null;
\r
175 jedis = JedisUtil.borrowJedisInstance();
\r
176 if (jedis == null) {
\r
177 throw new Exception("fetch from jedis pool failed,null object!");
\r
179 jedis.hmset(serviceInfokey, serviceInfoMap);
\r
181 catch (Exception e) {
\r
182 LOGGER.error("update MicroService status throw exception", e);
\r
183 throw new Exception("update MicroService status throw exception:"+e.getMessage());
\r
185 JedisUtil.returnJedisInstance(jedis);
\r
191 public void updateMicroServiceNode2Redis(String serviceName, String version,String ip,String port,int ttl) throws Exception {
\r
192 String serviceLBkey =
\r
193 MicroServiceUtil.getPrefixedKey("",serviceName,version, MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
\r
196 Jedis jedis = null;
\r
198 jedis = JedisUtil.getJedis();
\r
201 String nodeKey=serviceLBkey+":"+ip+"-"+port;
\r
202 Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);
\r
204 if(nodeLBmap.isEmpty()){
\r
205 throw new NullPointerException(" MicroService Node not fond ");
\r
209 nodeLBmap.put("ttl", Integer.toString(ttl));
\r
210 long expiration_time=System.currentTimeMillis()+ttl*1000;
\r
211 nodeLBmap.put("expiration", Long.toString(expiration_time));
\r
212 nodeLBmap.put("updated_at", Long.toString(System.currentTimeMillis()));
\r
214 jedis.hmset(nodeKey, nodeLBmap);
\r
218 catch (NullPointerException e){
\r
221 catch (Exception e) {
\r
222 LOGGER.error("update MicroService Node throw exception", e);
\r
223 throw new Exception("update MicroService Node throw exception:"+e.getMessage());
\r
225 JedisUtil.returnJedisInstance(jedis);
\r
230 public void noticeUpdateApiListener(String serviceName,String version,Service microServiceInfo,String serverPort) {
\r
231 if (isNeedNotify(microServiceInfo)) {
\r
232 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
\r
233 serviceListener.onChange(serviceName,version, microServiceInfo,serverPort);
\r
239 public void noticeUpdateStatusListener(Service microServiceInfo,String status) {
\r
241 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
\r
242 serviceListener.onStatusChange(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),
\r
243 microServiceInfo.getVersion(),microServiceInfo.getProtocol(),status);
\r
249 public void noticeApiListener(Service microServiceInfo, String type,String serverPort) {
\r
250 if (isNeedNotify(microServiceInfo)) {
\r
252 if ("ADD".equals(type)) {
\r
253 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
\r
254 serviceListener.onSave(microServiceInfo,serverPort);
\r
256 } else if ("DELETE".equals(type)) {
\r
257 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
\r
258 serviceListener.onDelete(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),
\r
259 microServiceInfo.getVersion(),microServiceInfo.getProtocol(),serverPort);
\r
267 public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort)
\r
269 if (null == version || "null".equals(version)) {
\r
273 Jedis jedis = null;
\r
274 MicroServiceFullInfo microServiceInfo = null;
\r
277 jedis = JedisUtil.getJedis();
\r
279 microServiceInfo= getMicroServiceByJedis(jedis,serviceName,version, serverPort);
\r
282 } catch (Exception e) {
\r
283 LOGGER.error("call redis throw exception", e);
\r
284 throw new Exception("call redis throw exception:"+e.getMessage());
\r
286 JedisUtil.returnJedisInstance(jedis);
\r
289 return microServiceInfo;
\r
293 private MicroServiceFullInfo getMicroServiceByJedis(Jedis jedis,String serviceName, String version,String serverPort){
\r
294 MicroServiceFullInfo microServiceInfo = null;
\r
295 String serviceInfoKey = MicroServiceUtil.getServiceInfoKey(serverPort,serviceName, version);
\r
296 Map<String, String> infomap = jedis.hgetAll(serviceInfoKey);
\r
297 if (!infomap.isEmpty()) {
\r
298 microServiceInfo = new MicroServiceFullInfo();
\r
299 microServiceInfo.setServiceName(serviceName);
\r
300 microServiceInfo.setVersion(version);
\r
301 microServiceInfo.setUrl(infomap.get("url"));
\r
302 microServiceInfo.setProtocol(infomap.get("protocol"));
\r
303 microServiceInfo.setVisualRange(infomap.get("visualRange"));
\r
304 microServiceInfo.setStatus(infomap.get("status"));
\r
305 microServiceInfo.setLb_policy(infomap.get("lb_policy"));
\r
308 MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),
\r
309 microServiceInfo.getVersion(),
\r
310 MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
\r
312 Set<String> nodeKeys=jedis.keys(nodeLBkey+":*");
\r
314 Set<NodeInfo> nodes=new HashSet<NodeInfo>();
\r
315 for(String nodeKey:nodeKeys){
\r
316 Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);
\r
317 NodeInfo nodeInfo=new NodeInfo();
\r
318 nodeInfo.setNodeId(serviceName+"_"+nodeLBmap.get("ip")+"_"+nodeLBmap.get("port"));
\r
319 nodeInfo.setIp(nodeLBmap.get("ip"));
\r
320 nodeInfo.setPort(nodeLBmap.get("port"));
\r
321 nodeInfo.setTtl(Integer.parseInt(nodeLBmap.get("ttl")));
\r
322 nodeInfo.setCreated_at(new Date(Long.parseLong(nodeLBmap.get("created_at"))));
\r
323 nodeInfo.setUpdated_at(new Date(Long.parseLong(nodeLBmap.get("updated_at"))));
\r
324 nodeInfo.setExpiration(new Date(Long.parseLong(nodeLBmap.get("expiration"))));
\r
326 nodes.add(nodeInfo);
\r
329 microServiceInfo.setNodes(nodes);
\r
335 return microServiceInfo;
\r
339 public void deleteMicroService(String serviceName, String version,String serverPort) throws Exception {
\r
340 if (null == version || "null".equals(version)) {
\r
344 Jedis jedis = null;
\r
346 jedis = JedisUtil.getJedis();
\r
347 String routekey = MicroServiceUtil.getPrefixedKey(serverPort,serviceName, version, "*");
\r
348 Set<String> infoSet = jedis.keys(routekey);
\r
350 String[] paths = new String[infoSet.size()];
\r
352 infoSet.toArray(paths);
\r
355 } catch (Exception e) {
\r
356 LOGGER.error("call redis throw exception", e);
\r
357 throw new Exception("call redis throw exception:"+e.getMessage());
\r
359 JedisUtil.returnJedisInstance(jedis);
\r
363 public void deleteNode(String serviceName, String version, String ip,String port) throws Exception {
\r
364 if (null == version || "null".equals(version)) {
\r
368 Jedis jedis = null;
\r
370 jedis = JedisUtil.getJedis();
\r
371 String serviceLBkey =
\r
372 MicroServiceUtil.getPrefixedKey("",serviceName, version,
\r
373 MicroServiceUtil.ROUTE_PATH_LOADBALANCE,ip+"-"+port);
\r
374 jedis.del(serviceLBkey);
\r
375 } catch (Exception e) {
\r
376 LOGGER.error("call redis throw exception", e);
\r
377 throw new Exception("call redis throw exception:"+e.getMessage());
\r
379 JedisUtil.returnJedisInstance(jedis);
\r
386 * Determine whether the service needs to send a notification
\r
387 * TODO: filter according to the agreement,
\r
388 * the only notice of agreement for REST \ UI interface MSB - REST
\r
392 private boolean isNeedNotifyByProtocol(String protocol) {
\r
393 return "UI".equalsIgnoreCase(protocol) ||("REST".equalsIgnoreCase(protocol));
\r
397 * Determine whether the service needs to send a notification
\r
398 * TODO: according to the visual range filter conditions
\r
399 * @param visualRange
\r
402 private boolean isNeedNotifyByVisualRange(String visualRange) {
\r
403 String[] rangeArray=StringUtils.split(visualRange, "|");
\r
404 return RouteUtil.contain(RouteUtil.visualRangeMatches, rangeArray);
\r
408 * According to the MicroServiceInfo entity information to judge whether need to send a notification
\r
409 * @param microServiceInfo
\r
412 private boolean isNeedNotify(Service microServiceInfo) {
\r
413 if (null != microServiceInfo) {
\r
414 return isNeedNotifyByProtocol(microServiceInfo.getProtocol()) &&
\r
415 isNeedNotifyByVisualRange(microServiceInfo.getVisualRange());
\r