Package com.alibaba.dubbo.governance.web.governance.module.screen

Source Code of com.alibaba.dubbo.governance.web.governance.module.screen.Routes

/*
* Copyright 2011 Alibaba.com All right reserved. This software is the
* confidential and proprietary information of Alibaba.com ("Confidential
* Information"). You shall not disclose such Confidential Information and shall
* use it only in accordance with the terms of the license agreement you entered
* into with Alibaba.com.
*/
package com.alibaba.dubbo.governance.web.governance.module.screen;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.governance.service.ConsumerService;
import com.alibaba.dubbo.governance.service.OwnerService;
import com.alibaba.dubbo.governance.service.ProviderService;
import com.alibaba.dubbo.governance.service.RouteService;
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
import com.alibaba.dubbo.registry.common.domain.Consumer;
import com.alibaba.dubbo.registry.common.domain.Provider;
import com.alibaba.dubbo.registry.common.domain.Route;
import com.alibaba.dubbo.registry.common.route.ParseUtils;
import com.alibaba.dubbo.registry.common.route.RouteRule;
import com.alibaba.dubbo.registry.common.route.RouteUtils;
import com.alibaba.dubbo.registry.common.util.Tool;

/**
* Providers.
* URI: /services/$service/routes
*
* @author ding.lid
* @author william.liangf
* @author tony.chenl
*/
public class Routes extends Restful {
   
  private static final int MAX_RULE_LENGTH = 1000;
 
    @Autowired
    private RouteService routeService;
   
    @Autowired
    private ProviderService providerService;
   
    @Autowired
    private ConsumerService consumerService;
   
    static String[][] when_names = {
        {"method", "method", "unmethod"},
        {"consumer.application", "consumerApplication", "unconsumerApplication"},
        {"consumer.cluster", "consumerCluster", "unconsumerCluster"},
        {"consumer.host", "consumerHost", "unconsumerHost"},
        {"consumer.version", "consumerVersion", "unconsumerVersion"},
        {"consumer.group", "consumerGroup", "unconsumerGroup"},
    };

    static String[][] then_names = {
      {"provider.application", "providerApplication", "unproviderApplication"},
        {"provider.cluster", "providerCluster", "unproviderCluster"}, // 要校验Cluster是否存在
        {"provider.host", "providerHost", "unproviderHost"},
        {"provider.protocol", "providerProtocol", "unproviderProtocol"},
        {"provider.port", "providerPort", "unproviderPort"},
        {"provider.version", "providerVersion", "unproviderVersion"},
        {"provider.group", "providerGroup", "unproviderGroup"}
    };

    /**
     * 路由模块首页
     * @param context
     */
    public void index(Map<String, Object> context) {
        String service = (String) context.get("service");
        String address = (String) context.get("address");
        address = Tool.getIP(address);
        List<Route> routes;
        if (service != null && service.length() > 0
            && address != null && address.length() > 0) {
            routes = routeService.findByServiceAndAddress(service, address);
        } else if (service != null && service.length() > 0) {
            routes = routeService.findByService(service);
        } else if (address != null && address.length() > 0) {
            routes = routeService.findByAddress(address);
        } else {
            routes = routeService.findAll();
        }
        context.put("routes", routes);
    }

    /**
     * 显示路由详细信息
     * @param context
     */
    public void show(Map<String, Object> context) {
      try {
          Route route = routeService.findRoute(Long.parseLong((String)context.get("id")));
         
          if (route == null) {
              throw new IllegalArgumentException("The route is not existed.");
          }
          if(route.getService()!=null && !route.getService().isEmpty()){
              context.put("service", route.getService());
          }
         
          RouteRule routeRule= RouteRule.parse(route);
         
          @SuppressWarnings("unchecked")
          Map<String, RouteRule.MatchPair>[] paramArray = new Map[] {
              routeRule.getWhenCondition(), routeRule.getThenCondition()};
          String[][][] namesArray = new String[][][] {when_names, then_names };
         
          for(int i=0; i<paramArray.length; ++i) {
              Map<String, RouteRule.MatchPair> param = paramArray[i];
              String[][] names = namesArray[i];
              for(String[] name : names) {
                  RouteRule.MatchPair matchPair = param.get(name[0]);
                  if(matchPair == null) {
                      continue;
                  }
                 
                  if(!matchPair.getMatches().isEmpty()) {
                      String m = RouteRule.join(matchPair.getMatches());
                      context.put(name[1], m);
                  }
                  if(!matchPair.getUnmatches().isEmpty()) {
                      String u = RouteRule.join(matchPair.getUnmatches());
                      context.put(name[2], u);
                  }
              }
          }
          context.put("route", route);
          context.put("methods", CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(route.getService()))));
      } catch (ParseException e) {
      e.printStackTrace();
    }
    }
   
    /**
     * 载入新增路由页面
     * @param context
     */
    public void add(Map<String, Object> context) {
        String service = (String)context.get("service");
        if (service != null && service.length() > 0 && !service.contains("*")) {
            context.put("service", service);
            context.put("methods", CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(service))));
        } else {
            List<String> serviceList = Tool.sortSimpleName(new ArrayList<String>(providerService.findServices()));
            context.put("serviceList", serviceList);
        }
       
        if(context.get("input") != null) context.put("input", context.get("input"));
       
    }

    /**
     * 载入修改路由页面
     * @param context
     */
    public void edit(Map<String, Object> context) {
          add(context);
          show(context);
    }
   
    static void checkService(String service) {
        if(service.contains(",")) throw new IllegalStateException("service(" + service + ") contain illegale ','");
       
        String interfaceName = service;
        int gi = interfaceName.indexOf("/");
        if(gi != -1) interfaceName = interfaceName.substring(gi + 1);
        int vi = interfaceName.indexOf(':');
        if(vi != -1) interfaceName = interfaceName.substring(0, vi);
       
        if(interfaceName.indexOf('*') != -1 && interfaceName.indexOf('*') != interfaceName.length() -1) {
            throw new IllegalStateException("service(" + service + ") only allow 1 *, and must be last char!");
        }
    }
   
    /**
     * 保存路由信息到数据库中
     * @param context
     * @return
     */
    public boolean create(Map<String, Object> context) {
      String name = (String)context.get("name");
        String service = (String)context.get("service");
        if (StringUtils.isNotEmpty(service)
                && StringUtils.isNotEmpty(name)) {
            checkService(service);
         
            Map<String, String> when_name2valueList = new HashMap<String, String>();
            Map<String, String> notWhen_name2valueList = new HashMap<String, String>();
            for(String[] names : when_names) {
                when_name2valueList.put(names[0], (String)context.get(names[1]));
                notWhen_name2valueList.put(names[0], (String)context.get(names[2])); // value不为null的情况,这里处理,后面会保证
            }
           
            Map<String, String> then_name2valueList = new HashMap<String, String>();
            Map<String, String> notThen_name2valueList = new HashMap<String, String>();
            for(String[] names : then_names) {
                then_name2valueList.put(names[0], (String)context.get(names[1]));
                notThen_name2valueList.put(names[0], (String)context.get(names[2]));
            }

            RouteRule routeRule = RouteRule.createFromNameAndValueListString(
                    when_name2valueList, notWhen_name2valueList,
                    then_name2valueList, notThen_name2valueList);
           
            if (routeRule.getThenCondition().isEmpty()) {
                context.put("message", getMessage("Add route error! then is empty."));
                return false;
            }

            String matchRule = routeRule.getWhenConditionString();
            String filterRule = routeRule.getThenConditionString();
           
            //限制表达式的长度
            if (matchRule.length() > MAX_RULE_LENGTH) {
                context.put("message", getMessage("When rule is too long!"));
                return false;
            }
            if (filterRule.length() > MAX_RULE_LENGTH) {
                context.put("message", getMessage("Then rule is too long!"));
                return false;
            }
           
            Route route = new Route();
            route.setService(service);
            route.setName(name);
            route.setUsername((String)context.get("operator"));
            route.setOperator((String)context.get("operatorAddress"));
            route.setRule(routeRule.toString());
            if (StringUtils.isNotEmpty((String)context.get("priority"))) {
                route.setPriority(Integer.parseInt((String)context.get("priority")));
            }
            routeService.createRoute(route);
           
        }
       
        return true;
    }

    /**
     * 保存更新数据到数据库中
     * @param context
     * @return
     */
    public boolean update(Map<String, Object> context) {
      String idStr = (String)context.get("id");
        if (idStr != null && idStr.length() > 0 ) {
            String[] blacks = (String[])context.get("black");
            boolean black = false;
            if(blacks != null && blacks.length > 0){
                black = true;
            }

            Route oldRoute = routeService.findRoute(Long.valueOf(idStr));
            if(null == oldRoute) {
                context.put("message", getMessage("NoSuchRecord"));
                return false;
            }
            //判断参数,拼凑rule
            if (StringUtils.isNotEmpty((String)context.get("name"))) {
              String service = oldRoute.getService();
                if (context.get("operator") == null) {
                    context.put("message", getMessage("HaveNoServicePrivilege", service));
                    return false;
                }
               
                Map<String, String> when_name2valueList = new HashMap<String, String>();
                Map<String, String> notWhen_name2valueList = new HashMap<String, String>();
                for(String[] names : when_names) {
                    when_name2valueList.put(names[0], (String)context.get(names[1]));
                    notWhen_name2valueList.put(names[0], (String)context.get(names[2])); // value不为null的情况,这里处理,后面会保证
                }

                Map<String, String> then_name2valueList = new HashMap<String, String>();
                Map<String, String> notThen_name2valueList = new HashMap<String, String>();
                for(String[] names : then_names) {
                    then_name2valueList.put(names[0], (String)context.get(names[1]));
                    notThen_name2valueList.put(names[0], (String)context.get(names[2]));
                }

                RouteRule routeRule = RouteRule.createFromNameAndValueListString(
                        when_name2valueList, notWhen_name2valueList,
                        then_name2valueList, notThen_name2valueList);
               
                RouteRule result = null;
                if(black){
                    RouteRule.MatchPair matchPair = routeRule.getThenCondition().get("black");
                    Map<String, RouteRule.MatchPair> then = null;
                    if(null == matchPair) {
                        matchPair = new RouteRule.MatchPair();
                        then = new HashMap<String, RouteRule.MatchPair>();
                        then.put("black", matchPair);
                    }else{
                        matchPair.getMatches().clear();
                    }
                    matchPair.getMatches().add(String.valueOf(black));
                    result =  RouteRule.copyWithReplace(routeRule, null, then);
                }
               
                if(result == null){
                    result = routeRule;
                }
               
                if (result.getThenCondition().isEmpty()) {
                    context.put("message", getMessage("Update route error! then is empty."));
                    return false;
                }
               
                String matchRule = result.getWhenConditionString();
                String filterRule = result.getThenConditionString();
               
                //限制表达式的长度
                if (matchRule.length() > MAX_RULE_LENGTH) {
                    context.put("message", getMessage("When rule is too long!"));
                    return false;
                }
                if (filterRule.length() > MAX_RULE_LENGTH) {
                    context.put("message", getMessage("Then rule is too long!"));
                    return false;
                }
               
                int priority = 0;
                if (StringUtils.isNotEmpty((String)context.get("priority"))) {
                    priority = Integer.parseInt((String)context.get("priority"));
                }
               
                Route route = new Route();
                route.setRule(result.toString());
                route.setService(service);
                route.setPriority(priority);
                route.setName((String)context.get("name"));
                route.setUsername((String)context.get("operator"));
                route.setOperator((String)context.get("operatorAddress"));
                route.setId(Long.valueOf(idStr));
                route.setPriority(Integer.parseInt((String)context.get("priority")));
                route.setEnabled(oldRoute.isEnabled());
                routeService.updateRoute(route);
               
                Set<String> usernames = new HashSet<String>();
                usernames.add((String)context.get("operator"));
                usernames.add(route.getUsername());
                //RelateUserUtils.addOwnersOfService(usernames, route.getService(), ownerDAO);
               
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("action", "update");
                params.put("route", route);
               
            } else {
                context.put("message", getMessage("MissRequestParameters", "name"));
            }
        } else {
            context.put("message", getMessage("MissRequestParameters", "id"));
        }
       
        return true;
    }

    /**
     * 删除指定ID的route规则
     * @param ids
     * @return
     */
    public boolean delete(Long[] ids, Map<String, Object> context) {
       for (Long id : ids) {
         routeService.deleteRoute(id);
         }
      
         return true;
    }
   
    /**
     * 启用指定ID的route规则(可以批量处理)
     * @param ids
     * @return
     */
    public boolean enable(Long[] ids, Map<String, Object> context) {
        for(Long id : ids){
            routeService.enableRoute(id);
        }
       
        return true;
    }
   
    /**
     * 禁用指定ID的route规则(可以批量处理)
     * @param ids
     * @return
     */
    public boolean disable(Long[] ids, Map<String, Object> context) {
        for(Long id : ids){
            routeService.disableRoute(id);
        }
       
        return true;
    }
   
    /**
     * 选择消费者
     * @param context
     */
    public void routeselect(Map<String, Object> context){
      long rid = Long.valueOf((String)context.get("id"));
        context.put("id", rid);
       
        Route route = routeService.findRoute(rid);
        if (route == null) {
            throw new IllegalStateException("Route(id=" + rid + ") is not existed!");
        }
       
        context.put("route", route);
        // 获取数据
        List<Consumer> consumers = consumerService.findByService(route.getService());
        context.put("consumers", consumers);
       
        Map<String, Boolean> matchRoute = new HashMap<String, Boolean>();
        for(Consumer c : consumers) {
            matchRoute.put(c.getAddress(), RouteUtils.matchRoute(c.getAddress(), null, route, null));
        }
        context.put("matchRoute", matchRoute);
    }
   
   
    public void preview(Map<String, Object> context) throws Exception {
        String rid = (String)context.get("id");
        String consumerid = (String)context.get("cid");
       
       
        if(StringUtils.isEmpty(rid)) {
            context.put("message", getMessage("MissRequestParameters", "id"));
        }
       
        Map<String, String> serviceUrls = new HashMap<String, String>();
        Route route = routeService.findRoute(Long.valueOf(rid));
        if(null == route) {
            context.put("message", getMessage("NoSuchRecord"));
        }
        List<Provider> providers = providerService.findByService(route.getService());
        if (providers != null) {
            for (Provider p : providers) {
                serviceUrls.put(p.getUrl(), p.getParameters());
            }
        }
        if(StringUtils.isNotEmpty(consumerid)) {
            Consumer consumer = consumerService.findConsumer(Long.valueOf(consumerid));
            if(null == consumer) {
                context.put("message", getMessage("NoSuchRecord"));
            }
            Map<String, String> result = RouteUtils.previewRoute(consumer.getService(), consumer.getAddress(), consumer.getParameters(), serviceUrls,
                    route, null, null);
            context.put("route", route);
            context.put("consumer", consumer);
            context.put("result", result);
        }
        else {
            String address = (String)context.get("address");
            String service = (String)context.get("service");
           
            Map<String, String> result = RouteUtils.previewRoute(service, address, null, serviceUrls,
                    route, null, null);
            context.put("route", route);
           
            Consumer consumer = new Consumer();
            consumer.setService(service);
            consumer.setAddress(address);
            context.put("consumer", consumer);
            context.put("result", result);
        }
       
    }
   
    /**
     * 添加与服务相关的Owner
     *
     * @param usernames 用于添加的用户名
     * @param serviceName 不含通配符
     */
    public static void addOwnersOfService(Set<String> usernames, String serviceName,
                                          OwnerService ownerDAO) {
        List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
        for (String p : serviceNamePatterns) {
            if (ParseUtils.isMatchGlobPattern(p, serviceName)) {
                List<String> list = ownerDAO.findUsernamesByServiceName(p);
                usernames.addAll(list);
            }
        }
    }

    /**
     * 添加与服务模式相关的Owner
     *
     * @param usernames 用于添加的用户名
     * @param serviceNamePattern 服务模式,Glob模式
     */
    public static void addOwnersOfServicePattern(Set<String> usernames, String serviceNamePattern,
                                                OwnerService ownerDAO) {
        List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
        for (String p : serviceNamePatterns) {
            if (ParseUtils.hasIntersection(p, serviceNamePattern)) {
                List<String> list = ownerDAO.findUsernamesByServiceName(p);
                usernames.addAll(list);
            }
        }
    }
}
TOP

Related Classes of com.alibaba.dubbo.governance.web.governance.module.screen.Routes

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.