2 * Copyright 2016 ZTE Corporation.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.openo.msb.wrapper.util;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
28 import org.apache.commons.lang3.StringUtils;
29 import org.openo.msb.api.MicroServiceFullInfo;
30 import org.openo.msb.api.MicroServiceInfo;
31 import org.openo.msb.api.Node;
32 import org.openo.msb.api.NodeInfo;
33 import org.openo.msb.api.Service;
34 import org.openo.msb.wrapper.serviceListener.IMicroServiceChangeListener;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 import redis.clients.jedis.Jedis;
40 public class MicroServiceDB {
42 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceDB.class);
44 private static MicroServiceDB instance = new MicroServiceDB();
46 private List<IMicroServiceChangeListener> serviceListenerlist =
47 new ArrayList<IMicroServiceChangeListener>();
49 private MicroServiceDB() {}
51 public static MicroServiceDB getInstance() {
56 public void addServiceChangeListener(IMicroServiceChangeListener listener) {
57 synchronized (serviceListenerlist) {
58 serviceListenerlist.add(listener);
63 public void removeServiceChangeListener(IMicroServiceChangeListener listener) {
64 synchronized (serviceListenerlist) {
65 serviceListenerlist.remove(listener);
70 public MicroServiceFullInfo[] getAllMicroServiceInstances() throws Exception {
72 MicroServiceFullInfo[] microServiceList;
74 jedis = JedisUtil.getJedis();
77 MicroServiceUtil.getPrefixedKey("","*", MicroServiceUtil.SUFFIX_PATH_INFO);
78 Set<String> serviceSet = jedis.keys(routekey);
79 microServiceList = new MicroServiceFullInfo[serviceSet.size()];
81 Pattern redisKeyPattern = MicroServiceUtil.getRedisKeyPattern();
83 for (String servicePath : serviceSet) {
84 Matcher matcher = redisKeyPattern.matcher(servicePath);
85 if (matcher.matches()) {
86 microServiceList[i] = getMicroServiceByJedis(jedis, matcher.group("servicename"),matcher.group("version"), "");
90 } catch (Exception e) {
91 LOGGER.error("call redis throw exception", e);
92 throw new Exception("call redis throw exception:"+e.getMessage());
94 JedisUtil.returnJedisInstance(jedis);
97 return microServiceList;
100 public void saveMicroServiceInfo2Redis(MicroServiceInfo microServiceInfo,String serverPort) throws Exception {
102 String serviceInfokey =
103 MicroServiceUtil.getServiceInfoKey(serverPort,microServiceInfo.getServiceName(),
104 microServiceInfo.getVersion());
105 Map<String, String> serviceInfoMap = new HashMap<String, String>();
106 serviceInfoMap.put("url", microServiceInfo.getUrl());
107 serviceInfoMap.put("protocol", microServiceInfo.getProtocol());
108 serviceInfoMap.put("visualRange",microServiceInfo.getVisualRange());
109 serviceInfoMap.put("lb_policy",microServiceInfo.getLb_policy());
110 serviceInfoMap.put("status", "1");
115 String serviceLBkey =
116 MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),
117 microServiceInfo.getVersion(), MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
122 jedis = JedisUtil.getJedis();
124 jedis.hmset(serviceInfokey, serviceInfoMap);
127 for(Node node:microServiceInfo.getNodes()){
129 String key=serviceLBkey+":"+node.getIp()+"-"+node.getPort();
131 Map<String,String> nodeMap = new HashMap<String,String>();
133 nodeMap.put("ip", node.getIp());
134 nodeMap.put("port", node.getPort());
135 nodeMap.put("ttl", Integer.toString(node.getTtl()));
136 long expiration_time=System.currentTimeMillis()+node.getTtl()*1000;
137 nodeMap.put("expiration", Long.toString(expiration_time));
139 if(jedis.keys(key).isEmpty()){
140 nodeMap.put("created_at", Long.toString(System.currentTimeMillis()));
143 // Map<String,String> nodeLBmap = jedis.hgetAll(key);
144 // nodeMap.put("created_at", nodeLBmap.get("created_at"));
146 nodeMap.put("updated_at", Long.toString(System.currentTimeMillis()));
148 jedis.hmset(key, nodeMap);
151 // jedis.sadd(serviceLBkey, nodeArray);
153 } catch (Exception e) {
154 LOGGER.error("save to redis throw exception", e);
155 throw new Exception("save to redis throw exception:"+e.getMessage());
157 JedisUtil.returnJedisInstance(jedis);
164 public void updateMicroServiceStatus(String serviceName, String version,String status) throws Exception{
167 String serviceInfokey = MicroServiceUtil.getServiceInfoKey("",serviceName, version);
168 Map<String, String> serviceInfoMap = new HashMap<String, String>();
169 serviceInfoMap.put("status", status);
174 jedis = JedisUtil.borrowJedisInstance();
176 throw new Exception("fetch from jedis pool failed,null object!");
178 jedis.hmset(serviceInfokey, serviceInfoMap);
180 catch (Exception e) {
181 LOGGER.error("update MicroService status throw exception", e);
182 throw new Exception("update MicroService status throw exception:"+e.getMessage());
184 JedisUtil.returnJedisInstance(jedis);
190 public void updateMicroServiceNode2Redis(String serviceName, String version,String ip,String port,int ttl) throws Exception {
191 String serviceLBkey =
192 MicroServiceUtil.getPrefixedKey("",serviceName,version, MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
197 jedis = JedisUtil.getJedis();
200 String nodeKey=serviceLBkey+":"+ip+"-"+port;
201 Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);
203 if(nodeLBmap.isEmpty()){
204 throw new NullPointerException(" MicroService Node not fond ");
208 nodeLBmap.put("ttl", Integer.toString(ttl));
209 long expiration_time=System.currentTimeMillis()+ttl*1000;
210 nodeLBmap.put("expiration", Long.toString(expiration_time));
211 nodeLBmap.put("updated_at", Long.toString(System.currentTimeMillis()));
213 jedis.hmset(nodeKey, nodeLBmap);
217 catch (NullPointerException e){
220 catch (Exception e) {
221 LOGGER.error("update MicroService Node throw exception", e);
222 throw new Exception("update MicroService Node throw exception:"+e.getMessage());
224 JedisUtil.returnJedisInstance(jedis);
229 public void noticeUpdateApiListener(String serviceName,String version,Service microServiceInfo,String serverPort) {
230 if (isNeedNotify(microServiceInfo)) {
231 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
232 serviceListener.onChange(serviceName,version, microServiceInfo,serverPort);
238 public void noticeUpdateStatusListener(Service microServiceInfo,String status) {
240 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
241 serviceListener.onStatusChange(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),
242 microServiceInfo.getVersion(),microServiceInfo.getProtocol(),status);
248 public void noticeApiListener(Service microServiceInfo, String type,String serverPort) {
249 if (isNeedNotify(microServiceInfo)) {
251 if ("ADD".equals(type)) {
252 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
253 serviceListener.onSave(microServiceInfo,serverPort);
255 } else if ("DELETE".equals(type)) {
256 for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {
257 serviceListener.onDelete(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),
258 microServiceInfo.getVersion(),microServiceInfo.getProtocol(),serverPort);
266 public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort)
268 if (null == version || "null".equals(version)) {
273 MicroServiceFullInfo microServiceInfo = null;
276 jedis = JedisUtil.getJedis();
278 microServiceInfo= getMicroServiceByJedis(jedis,serviceName,version, serverPort);
281 } catch (Exception e) {
282 LOGGER.error("call redis throw exception", e);
283 throw new Exception("call redis throw exception:"+e.getMessage());
285 JedisUtil.returnJedisInstance(jedis);
288 return microServiceInfo;
292 private MicroServiceFullInfo getMicroServiceByJedis(Jedis jedis,String serviceName, String version,String serverPort){
293 MicroServiceFullInfo microServiceInfo = null;
294 String serviceInfoKey = MicroServiceUtil.getServiceInfoKey(serverPort,serviceName, version);
295 Map<String, String> infomap = jedis.hgetAll(serviceInfoKey);
296 if (!infomap.isEmpty()) {
297 microServiceInfo = new MicroServiceFullInfo();
298 microServiceInfo.setServiceName(serviceName);
299 microServiceInfo.setVersion(version);
300 microServiceInfo.setUrl(infomap.get("url"));
301 microServiceInfo.setProtocol(infomap.get("protocol"));
302 microServiceInfo.setVisualRange(infomap.get("visualRange"));
303 microServiceInfo.setStatus(infomap.get("status"));
304 microServiceInfo.setLb_policy(infomap.get("lb_policy"));
307 MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),
308 microServiceInfo.getVersion(),
309 MicroServiceUtil.ROUTE_PATH_LOADBALANCE);
311 Set<String> nodeKeys=jedis.keys(nodeLBkey+":*");
313 Set<NodeInfo> nodes=new HashSet<NodeInfo>();
314 for(String nodeKey:nodeKeys){
315 Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);
316 NodeInfo nodeInfo=new NodeInfo();
317 nodeInfo.setNodeId(serviceName+"_"+nodeLBmap.get("ip")+"_"+nodeLBmap.get("port"));
318 nodeInfo.setIp(nodeLBmap.get("ip"));
319 nodeInfo.setPort(nodeLBmap.get("port"));
320 nodeInfo.setTtl(Integer.parseInt(nodeLBmap.get("ttl")));
321 nodeInfo.setCreated_at(new Date(Long.parseLong(nodeLBmap.get("created_at"))));
322 nodeInfo.setUpdated_at(new Date(Long.parseLong(nodeLBmap.get("updated_at"))));
323 nodeInfo.setExpiration(new Date(Long.parseLong(nodeLBmap.get("expiration"))));
328 microServiceInfo.setNodes(nodes);
334 return microServiceInfo;
338 public void deleteMicroService(String serviceName, String version,String serverPort) throws Exception {
339 if (null == version || "null".equals(version)) {
345 jedis = JedisUtil.getJedis();
346 String routekey = MicroServiceUtil.getPrefixedKey(serverPort,serviceName, version, "*");
347 Set<String> infoSet = jedis.keys(routekey);
349 if (infoSet.isEmpty()) {
350 LOGGER.error("delete MicroService FAIL:serviceName-"
351 + serviceName + ",version:" + version + " not fond ");
354 String[] paths = new String[infoSet.size()];
356 infoSet.toArray(paths);
360 } catch (Exception e) {
361 LOGGER.error("call redis throw exception", e);
362 throw new Exception("call redis throw exception:"+e.getMessage());
364 JedisUtil.returnJedisInstance(jedis);
368 public void deleteNode(String serviceName, String version, String ip,String port) throws Exception {
369 if (null == version || "null".equals(version)) {
375 jedis = JedisUtil.getJedis();
376 String serviceLBkey =
377 MicroServiceUtil.getPrefixedKey("",serviceName, version,
378 MicroServiceUtil.ROUTE_PATH_LOADBALANCE,ip+"-"+port);
379 jedis.del(serviceLBkey);
380 } catch (Exception e) {
381 LOGGER.error("call redis throw exception", e);
382 throw new Exception("call redis throw exception:"+e.getMessage());
384 JedisUtil.returnJedisInstance(jedis);
391 * Determine whether the service needs to send a notification
392 * TODO: filter according to the agreement,
393 * the only notice of agreement for REST \ UI interface MSB - REST
397 private boolean isNeedNotifyByProtocol(String protocol) {
398 return "UI".equalsIgnoreCase(protocol) || "REST".equalsIgnoreCase(protocol) || "HTTP".equalsIgnoreCase(protocol);
402 * Determine whether the service needs to send a notification
403 * TODO: according to the visual range filter conditions
407 private boolean isNeedNotifyByVisualRange(String visualRange) {
408 String[] rangeArray=StringUtils.split(visualRange, "|");
409 return RouteUtil.contain(RouteUtil.visualRangeMatches, rangeArray);
413 * According to the MicroServiceInfo entity information to judge whether need to send a notification
414 * @param microServiceInfo
417 private boolean isNeedNotify(Service microServiceInfo) {
418 if (null != microServiceInfo) {
419 return isNeedNotifyByProtocol(microServiceInfo.getProtocol()) &&
420 isNeedNotifyByVisualRange(microServiceInfo.getVisualRange());