Initial code import
[msb/apigateway.git] / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / util / MicroServiceDB.java
diff --git a/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java b/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/util/MicroServiceDB.java
new file mode 100644 (file)
index 0000000..ed22745
--- /dev/null
@@ -0,0 +1,423 @@
+/**\r
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+package org.openo.msb.wrapper.util;\r
+\r
+import java.sql.Date;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.openo.msb.api.MicroServiceFullInfo;\r
+import org.openo.msb.api.MicroServiceInfo;\r
+import org.openo.msb.api.Node;\r
+import org.openo.msb.api.NodeInfo;\r
+import org.openo.msb.api.Service;\r
+import org.openo.msb.wrapper.serviceListener.IMicroServiceChangeListener;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import redis.clients.jedis.Jedis;\r
+\r
+public class MicroServiceDB {\r
+\r
+    private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceDB.class);\r
+\r
+    private static MicroServiceDB instance = new MicroServiceDB();\r
+\r
+    private List<IMicroServiceChangeListener> serviceListenerlist =\r
+            new ArrayList<IMicroServiceChangeListener>();\r
+\r
+    private MicroServiceDB() {}\r
+\r
+    public static MicroServiceDB getInstance() {\r
+        return instance;\r
+    }\r
+\r
+   \r
+    public void addServiceChangeListener(IMicroServiceChangeListener listener) {\r
+        synchronized (serviceListenerlist) {\r
+            serviceListenerlist.add(listener);\r
+        }\r
+    }\r
+\r
+   \r
+    public void removeServiceChangeListener(IMicroServiceChangeListener listener) {\r
+        synchronized (serviceListenerlist) {\r
+            serviceListenerlist.remove(listener);\r
+        }\r
+    }\r
+    \r
+    \r
+    public MicroServiceFullInfo[] getAllMicroServiceInstances() throws Exception {\r
+        Jedis jedis = null;\r
+        MicroServiceFullInfo[] microServiceList;\r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+\r
+            String routekey =\r
+                    MicroServiceUtil.getPrefixedKey("","*", MicroServiceUtil.SUFFIX_PATH_INFO);\r
+            Set<String> serviceSet = jedis.keys(routekey);\r
+            microServiceList = new MicroServiceFullInfo[serviceSet.size()];\r
+\r
+            Pattern redisKeyPattern = MicroServiceUtil.getRedisKeyPattern();\r
+            int i = 0;\r
+            for (String servicePath : serviceSet) {\r
+                Matcher matcher = redisKeyPattern.matcher(servicePath);\r
+                if (matcher.matches()) {\r
+                    microServiceList[i] = getMicroServiceByJedis(jedis, matcher.group("servicename"),matcher.group("version"), "");\r
+                    i++;\r
+                }\r
+            }\r
+        } catch (Exception e) {\r
+            LOGGER.error("call redis throw exception", e);\r
+            throw new Exception("call redis throw exception:"+e.getMessage());       \r
+       } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+        \r
+        return microServiceList;\r
+    }\r
+\r
+    public void saveMicroServiceInfo2Redis(MicroServiceInfo microServiceInfo,String serverPort) throws Exception {\r
+        // 1.1 set info\r
+        String serviceInfokey =\r
+                MicroServiceUtil.getServiceInfoKey(serverPort,microServiceInfo.getServiceName(),\r
+                        microServiceInfo.getVersion());\r
+        Map<String, String> serviceInfoMap = new HashMap<String, String>();\r
+        serviceInfoMap.put("url", microServiceInfo.getUrl());\r
+        serviceInfoMap.put("protocol", microServiceInfo.getProtocol());\r
+        serviceInfoMap.put("visualRange",microServiceInfo.getVisualRange());\r
+        serviceInfoMap.put("lb_policy",microServiceInfo.getLb_policy());\r
+        serviceInfoMap.put("status", "0");\r
+        \r
+        \r
+\r
+        // 1.2 set lb info\r
+        String serviceLBkey =\r
+                MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),\r
+                        microServiceInfo.getVersion(), MicroServiceUtil.ROUTE_PATH_LOADBALANCE);\r
+\r
+\r
+        Jedis jedis = null;\r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+            // 2.1 save info\r
+            jedis.hmset(serviceInfokey, serviceInfoMap);\r
+\r
+\r
+            for(Node node:microServiceInfo.getNodes()){\r
+               \r
+                String key=serviceLBkey+":"+node.getIp()+"-"+node.getPort();\r
+                \r
+                Map<String,String> nodeMap = new HashMap<String,String>();\r
+               \r
+                nodeMap.put("ip", node.getIp());\r
+                nodeMap.put("port", node.getPort());\r
+                nodeMap.put("ttl", Integer.toString(node.getTtl()));\r
+                long expiration_time=System.currentTimeMillis()+node.getTtl()*1000;\r
+                nodeMap.put("expiration", Long.toString(expiration_time));\r
+                \r
+                if(jedis.keys(key).isEmpty()){\r
+                    nodeMap.put("created_at",  Long.toString(System.currentTimeMillis()));\r
+                }\r
+//                else{\r
+//                    Map<String,String> nodeLBmap = jedis.hgetAll(key); \r
+//                    nodeMap.put("created_at", nodeLBmap.get("created_at"));\r
+//                }\r
+                nodeMap.put("updated_at", Long.toString(System.currentTimeMillis()));\r
+                \r
+                jedis.hmset(key, nodeMap);\r
+            }\r
+            \r
+//            jedis.sadd(serviceLBkey, nodeArray);\r
+\r
+        } catch (Exception e) {\r
+            LOGGER.error("save to redis throw exception", e);\r
+            throw new Exception("save to  redis throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+\r
+\r
+\r
+    }\r
+    \r
+    public void updateMicroServiceStatus(String serviceName, String version,String status) throws Exception{\r
+        \r
+        \r
+        String serviceInfokey = MicroServiceUtil.getServiceInfoKey("",serviceName, version);\r
+        Map<String, String> serviceInfoMap = new HashMap<String, String>();\r
+        serviceInfoMap.put("status", status);\r
+\r
+\r
+        Jedis jedis = null;\r
+        try {\r
+            jedis = JedisUtil.borrowJedisInstance();\r
+            if (jedis == null) {\r
+                throw new Exception("fetch from jedis pool failed,null object!");\r
+            }\r
+            jedis.hmset(serviceInfokey, serviceInfoMap);\r
+        }\r
+        catch (Exception e) {\r
+            LOGGER.error("update MicroService status throw exception", e);\r
+            throw new Exception("update MicroService status throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    public void  updateMicroServiceNode2Redis(String serviceName, String version,String ip,String port,int ttl) throws Exception {\r
+        String serviceLBkey =\r
+                MicroServiceUtil.getPrefixedKey("",serviceName,version, MicroServiceUtil.ROUTE_PATH_LOADBALANCE);\r
+\r
+\r
+        Jedis jedis = null;\r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+          \r
+               \r
+                String nodeKey=serviceLBkey+":"+ip+"-"+port;                \r
+                Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);\r
+                \r
+                if(nodeLBmap.isEmpty()){\r
+                    throw new NullPointerException(" MicroService Node not fond ");  \r
+                }\r
+                \r
+               \r
+                nodeLBmap.put("ttl", Integer.toString(ttl));\r
+                long expiration_time=System.currentTimeMillis()+ttl*1000;\r
+                nodeLBmap.put("expiration", Long.toString(expiration_time));\r
+                nodeLBmap.put("updated_at", Long.toString(System.currentTimeMillis()));\r
+                \r
+                jedis.hmset(nodeKey, nodeLBmap);\r
+\r
+\r
+        } \r
+        catch (NullPointerException e){\r
+            throw e;  \r
+        }\r
+        catch (Exception e) {\r
+            LOGGER.error("update MicroService Node throw exception", e);\r
+            throw new Exception("update MicroService Node throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+    }\r
+    \r
+    \r
+    public void noticeUpdateApiListener(String serviceName,String version,Service microServiceInfo,String serverPort) {\r
+        if (isNeedNotify(microServiceInfo)) {\r
+            for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {\r
+                serviceListener.onChange(serviceName,version, microServiceInfo,serverPort);\r
+            }\r
+        }\r
+        \r
+    }\r
+    \r
+    public void noticeUpdateStatusListener(Service microServiceInfo,String status) {\r
+       \r
+        for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {\r
+            serviceListener.onStatusChange(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),\r
+                    microServiceInfo.getVersion(),microServiceInfo.getProtocol(),status);\r
+        }\r
+    }\r
+    \r
\r
+\r
+    public void noticeApiListener(Service microServiceInfo, String type,String serverPort) {\r
+        if (isNeedNotify(microServiceInfo)) {\r
+\r
+            if ("ADD".equals(type)) {\r
+                for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {\r
+                    serviceListener.onSave(microServiceInfo,serverPort);\r
+                }\r
+            } else if ("DELETE".equals(type)) {\r
+                for (IMicroServiceChangeListener serviceListener : serviceListenerlist) {\r
+                    serviceListener.onDelete(microServiceInfo.getServiceName(),microServiceInfo.getUrl(),\r
+                            microServiceInfo.getVersion(),microServiceInfo.getProtocol(),serverPort);\r
+                }\r
+            } \r
+\r
+        }\r
+    }\r
+\r
+\r
+    public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort)\r
+            throws Exception {\r
+        if (null == version || "null".equals(version)) {\r
+            version = "";\r
+        }\r
+\r
+        Jedis jedis = null;\r
+        MicroServiceFullInfo microServiceInfo = null;\r
+       \r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+            \r
+            microServiceInfo= getMicroServiceByJedis(jedis,serviceName,version, serverPort);\r
+\r
+           \r
+        } catch (Exception e) {\r
+            LOGGER.error("call redis throw exception", e);\r
+            throw new Exception("call redis throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+        \r
+        return microServiceInfo;\r
+       \r
+    }\r
+\r
+    private MicroServiceFullInfo getMicroServiceByJedis(Jedis jedis,String serviceName, String version,String serverPort){\r
+        MicroServiceFullInfo microServiceInfo = null;\r
+        String serviceInfoKey = MicroServiceUtil.getServiceInfoKey(serverPort,serviceName, version);\r
+        Map<String, String> infomap = jedis.hgetAll(serviceInfoKey);\r
+        if (!infomap.isEmpty()) {\r
+            microServiceInfo = new MicroServiceFullInfo();\r
+            microServiceInfo.setServiceName(serviceName);\r
+            microServiceInfo.setVersion(version);\r
+            microServiceInfo.setUrl(infomap.get("url"));\r
+            microServiceInfo.setProtocol(infomap.get("protocol"));\r
+            microServiceInfo.setVisualRange(infomap.get("visualRange"));\r
+            microServiceInfo.setStatus(infomap.get("status"));\r
+            microServiceInfo.setLb_policy(infomap.get("lb_policy"));\r
+\r
+            String nodeLBkey =\r
+                    MicroServiceUtil.getPrefixedKey(serverPort,microServiceInfo.getServiceName(),\r
+                            microServiceInfo.getVersion(),\r
+                            MicroServiceUtil.ROUTE_PATH_LOADBALANCE);\r
+            \r
+            Set<String>  nodeKeys=jedis.keys(nodeLBkey+":*");\r
+            \r
+            Set<NodeInfo> nodes=new HashSet<NodeInfo>();\r
+            for(String nodeKey:nodeKeys){\r
+                Map<String,String> nodeLBmap = jedis.hgetAll(nodeKey);\r
+                NodeInfo nodeInfo=new NodeInfo();\r
+                nodeInfo.setNodeId(serviceName+"_"+nodeLBmap.get("ip")+"_"+nodeLBmap.get("port"));\r
+                nodeInfo.setIp(nodeLBmap.get("ip"));\r
+                nodeInfo.setPort(nodeLBmap.get("port"));\r
+                nodeInfo.setTtl(Integer.parseInt(nodeLBmap.get("ttl")));\r
+                nodeInfo.setCreated_at(new Date(Long.parseLong(nodeLBmap.get("created_at"))));\r
+                nodeInfo.setUpdated_at(new Date(Long.parseLong(nodeLBmap.get("updated_at"))));\r
+                nodeInfo.setExpiration(new Date(Long.parseLong(nodeLBmap.get("expiration"))));\r
+              \r
+                nodes.add(nodeInfo);\r
+            }\r
+            \r
+            microServiceInfo.setNodes(nodes);\r
+        }\r
+            \r
+           \r
+           \r
+            \r
+            return microServiceInfo;\r
+    }\r
+        \r
+\r
+    public void deleteMicroService(String serviceName, String version,String serverPort) throws Exception {\r
+        if (null == version || "null".equals(version)) {\r
+            version = "";\r
+        }\r
+        \r
+        Jedis jedis = null;\r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+            String routekey = MicroServiceUtil.getPrefixedKey(serverPort,serviceName, version, "*");\r
+            Set<String> infoSet = jedis.keys(routekey);\r
+\r
+            String[] paths = new String[infoSet.size()];\r
+\r
+            infoSet.toArray(paths);\r
+\r
+            jedis.del(paths);\r
+        } catch (Exception e) {\r
+            LOGGER.error("call redis throw exception", e);\r
+            throw new Exception("call redis throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+    }\r
+\r
+    public void deleteNode(String serviceName, String version, String ip,String port) throws Exception {\r
+        if (null == version || "null".equals(version)) {\r
+            version = "";\r
+        }\r
+        \r
+        Jedis jedis = null;\r
+        try {\r
+            jedis = JedisUtil.getJedis();\r
+            String serviceLBkey =\r
+                    MicroServiceUtil.getPrefixedKey("",serviceName, version,\r
+                            MicroServiceUtil.ROUTE_PATH_LOADBALANCE,ip+"-"+port);\r
+            jedis.del(serviceLBkey);\r
+        } catch (Exception e) {\r
+            LOGGER.error("call redis throw exception", e);\r
+            throw new Exception("call redis throw exception:"+e.getMessage());\r
+        } finally {\r
+            JedisUtil.returnJedisInstance(jedis);\r
+        }\r
+\r
+    }\r
+\r
+\r
+    /**\r
+     * Determine whether the service needs to send a notification \r
+     * TODO: filter according to the agreement,\r
+     * the only notice of agreement for REST \ UI interface MSB - REST     \r
+     * @param protocol\r
+     * @return\r
+     */\r
+    private boolean isNeedNotifyByProtocol(String protocol) {\r
+        return "UI".equalsIgnoreCase(protocol) ||("REST".equalsIgnoreCase(protocol));\r
+    }\r
+    \r
+    /**\r
+     * Determine whether the service needs to send a notification \r
+     * TODO: according to the visual range filter conditions   \r
+     * @param visualRange\r
+     * @return\r
+     */\r
+    private boolean isNeedNotifyByVisualRange(String visualRange) {\r
+        String[] rangeArray=StringUtils.split(visualRange, "|");\r
+        return RouteUtil.contain(RouteUtil.visualRangeMatches, rangeArray);\r
+    }\r
+\r
+    /**\r
+     * According to the MicroServiceInfo entity information to judge whether need to send a notification\r
+     * @param microServiceInfo\r
+     * @return\r
+     */\r
+    private boolean isNeedNotify(Service microServiceInfo) {\r
+        if (null != microServiceInfo) {\r
+            return isNeedNotifyByProtocol(microServiceInfo.getProtocol()) &&\r
+                   isNeedNotifyByVisualRange(microServiceInfo.getVisualRange());\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+    \r
+    \r
+    \r
+}\r