/** * Project: dubbo.registry-1.1.0-SNAPSHOT * * File Created at 2010-4-15 * $Id: ProviderServiceImpl.java 185206 2012-07-09 03:06:37Z tony.chenl $ * * Copyright 2008 Alibaba.com Croporation Limited. * All rights reserved. * * This software is the confidential and proprietary information of * Alibaba Company. ("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.service.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; import org.springframework.beans.factory.annotation.Autowired; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.utils.StringUtils; import com.alibaba.dubbo.governance.service.OverrideService; import com.alibaba.dubbo.governance.service.ProviderService; import com.alibaba.dubbo.governance.sync.util.Pair; import com.alibaba.dubbo.governance.sync.util.SyncUtils; import com.alibaba.dubbo.registry.common.domain.Override; import com.alibaba.dubbo.registry.common.domain.Provider; import com.alibaba.dubbo.registry.common.route.ParseUtils; /** * IbatisProviderService * * @author tony.chenl */ public class ProviderServiceImpl extends AbstractService implements ProviderService { @Autowired OverrideService overrideService; public void create(Provider provider) { URL url = provider.toUrl(); registryService.register(url); } public void enableProvider(Long id) { if(id == null) { throw new IllegalStateException("no provider id"); } Provider oldProvider = findProvider(id); if(oldProvider == null) { throw new IllegalStateException("Provider was changed!"); } if (oldProvider.isDynamic()) { //保证disable的override唯一 if(!oldProvider.isEnabled()){ Override override = new Override(); override.setAddress(oldProvider.getAddress()); override.setService(oldProvider.getService()); override.setEnabled(true); override.setParams(Constants.DISABLED_KEY+"=false"); overrideService.saveOverride(override); return; } List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); for(Override o : oList){ Map<String, String> params = StringUtils.parseQueryString(o.getParams()); if(params.containsKey(Constants.DISABLED_KEY)){ if(params.get(Constants.DISABLED_KEY) .equals("true")){ overrideService.deleteOverride(o.getId()); } } } } else { oldProvider.setEnabled(true); updateProvider(oldProvider); } } public void disableProvider(Long id) { if(id == null) { throw new IllegalStateException("no provider id"); } Provider oldProvider = findProvider(id); if(oldProvider == null) { throw new IllegalStateException("Provider was changed!"); } if (oldProvider.isDynamic()) { //保证disable的override唯一 if(oldProvider.isEnabled()){ Override override = new Override(); override.setAddress(oldProvider.getAddress()); override.setService(oldProvider.getService()); override.setEnabled(true); override.setParams(Constants.DISABLED_KEY+"=true"); overrideService.saveOverride(override); return; } List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); for(Override o : oList){ Map<String, String> params = StringUtils.parseQueryString(o.getParams()); if(params.containsKey(Constants.DISABLED_KEY)){ if(params.get(Constants.DISABLED_KEY) .equals("false")){ overrideService.deleteOverride(o.getId()); } } } } else { oldProvider.setEnabled(false); updateProvider(oldProvider); } } public void doublingProvider(Long id) { setWeight(id, 2F); } public void halvingProvider(Long id) { setWeight(id, 0.5F); } public void setWeight(Long id, float factor) { if(id == null) { throw new IllegalStateException("no provider id"); } Provider oldProvider = findProvider(id); if(oldProvider == null) { throw new IllegalStateException("Provider was changed!"); } Map<String, String> map = StringUtils.parseQueryString(oldProvider.getParameters()); String weight = map.get(Constants.WEIGHT_KEY); if (oldProvider.isDynamic()) { //保证disable的override唯一 List<Override> overrides = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); if (overrides == null || overrides.size() == 0) { int value = getWeight(weight, factor); if (value != Constants.DEFAULT_WEIGHT) { Override override = new Override(); override.setAddress(oldProvider.getAddress()); override.setService(oldProvider.getService()); override.setEnabled(true); override.setParams(Constants.WEIGHT_KEY + "=" + String.valueOf(value)); overrideService.saveOverride(override); } } else { for(Override override : overrides){ Map<String, String> params = StringUtils.parseQueryString(override.getParams()); String overrideWeight = params.get(Constants.WEIGHT_KEY); if (overrideWeight == null || overrideWeight.length() == 0) { overrideWeight = weight; } int value = getWeight(overrideWeight, factor); if (value == getWeight(weight, 1)) { params.remove(Constants.WEIGHT_KEY); } else { params.put(Constants.WEIGHT_KEY, String.valueOf(value)); } if (params.size() > 0) { override.setParams(StringUtils.toQueryString(params)); overrideService.updateOverride(override); } else { overrideService.deleteOverride(override.getId()); } } } } else { int value = getWeight(weight, factor); if (value == Constants.DEFAULT_WEIGHT) { map.remove(Constants.WEIGHT_KEY); } else { map.put(Constants.WEIGHT_KEY, String.valueOf(value)); } oldProvider.setParameters(StringUtils.toQueryString(map)); updateProvider(oldProvider); } } private int getWeight(String value, float factor) { int weight = 100; if (value != null && value.length() > 0) { weight = Integer.parseInt(value); } weight = (int) (weight * factor); if (weight < 1) weight = 1; if (weight == 2) weight = 3; if (weight == 24) weight = 25; return weight; } public void deleteStaticProvider(Long id) { URL oldProvider = findProviderUrl(id); if(oldProvider == null) { throw new IllegalStateException("Provider was changed!"); } registryService.unregister(oldProvider); } public void updateProvider(Provider provider) { Long id = provider.getId(); if(id == null) { throw new IllegalStateException("no provider id"); } URL oldProvider = findProviderUrl(id); if(oldProvider == null) { throw new IllegalStateException("Provider was changed!"); } URL newProvider = provider.toUrl(); registryService.unregister(oldProvider); registryService.register(newProvider); } public Provider findProvider(Long id) { return SyncUtils.url2Provider(findProviderUrlPair(id)); } public Pair<Long, URL> findProviderUrlPair(Long id) { return SyncUtils.filterFromCategory(getRegistryCache(), Constants.PROVIDERS_CATEGORY, id); } public List<String> findServices() { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(providerUrls != null) ret.addAll(providerUrls.keySet()); return ret; } public List<String> findAddresses() { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(null == providerUrls) return ret; for(Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) { Map<Long, URL> value = e1.getValue(); for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); String app = u.getAddress(); if(app != null) ret.add(app); } } return ret; } public List<String> findAddressesByApplication(String application) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); for(Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) { Map<Long, URL> value = e1.getValue(); for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); if(application.equals(u.getParameter(Constants.APPLICATION_KEY))) { String addr = u.getAddress(); if(addr != null) ret.add(addr); } } } return ret; } public List<String> findAddressesByService(String service) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(null == providerUrls) return ret; for(Map.Entry<Long, URL> e2 : providerUrls.get(service).entrySet()) { URL u = e2.getValue(); String app = u.getAddress(); if(app != null) ret.add(app); } return ret; } public List<String> findApplicationsByServiceName(String service) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(null == providerUrls) return ret; Map<Long, URL> value = providerUrls.get(service); if(value == null){ return ret; } for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); String app = u.getParameter(Constants.APPLICATION_KEY); if(app != null) ret.add(app); } return ret; } public List<Provider> findByService(String serviceName) { return SyncUtils.url2ProviderList(findProviderUrlByService(serviceName)); } private Map<Long, URL> findProviderUrlByService(String service) { Map<String, String> filter = new HashMap<String, String>(); filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); filter.put(SyncUtils.SERVICE_FILTER_KEY, service); return SyncUtils.filterFromCategory(getRegistryCache(), filter); } public List<Provider> findAll() { return SyncUtils.url2ProviderList(findAllProviderUrl()); } private Map<Long, URL> findAllProviderUrl() { Map<String, String> filter = new HashMap<String, String>(); filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); return SyncUtils.filterFromCategory(getRegistryCache(), filter); } public List<Provider> findByAddress(String providerAddress) { return SyncUtils.url2ProviderList(findProviderUrlByAddress(providerAddress)); } public Map<Long, URL> findProviderUrlByAddress(String address) { Map<String, String> filter = new HashMap<String, String>(); filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); return SyncUtils.filterFromCategory(getRegistryCache(), filter); } public List<String> findServicesByAddress(String address) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(providerUrls == null || address == null || address.length() == 0) return ret; for(Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) { Map<Long, URL> value = e1.getValue(); for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); if(address.equals(u.getAddress())) { ret.add(e1.getKey()); break; } } } return ret; } public List<String> findApplications() { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(providerUrls == null) return ret; for(Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) { Map<Long, URL> value = e1.getValue(); for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); String app = u.getParameter(Constants.APPLICATION_KEY); if(app != null) ret.add(app); } } return ret; } public List<Provider> findByApplication(String application) { return SyncUtils.url2ProviderList(findProviderUrlByApplication(application)); } private Map<Long, URL> findProviderUrlByApplication(String application) { Map<String, String> filter = new HashMap<String, String>(); filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); filter.put(Constants.APPLICATION_KEY, application); return SyncUtils.filterFromCategory(getRegistryCache(), filter); } public List<String> findServicesByApplication(String application) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(providerUrls == null || application == null || application.length() == 0) return ret; for(Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) { Map<Long, URL> value = e1.getValue(); for(Map.Entry<Long, URL> e2 : value.entrySet()) { URL u = e2.getValue(); if(application.equals(u.getParameter(Constants.APPLICATION_KEY))) { ret.add(e1.getKey()); break; } } } return ret; } public List<String> findMethodsByService(String service) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); if(providerUrls == null || service == null || service.length() == 0) return ret; Map<Long, URL> providers = providerUrls.get(service); if(null == providers || providers.isEmpty()) return ret; Entry<Long, URL> p = providers.entrySet().iterator().next(); String value = p.getValue().getParameter("methods"); if (value == null || value.length() == 0) { return ret; } String[] methods = value.split(ParseUtils.METHOD_SPLIT); if (methods == null || methods.length == 0) { return ret; } for(String m : methods) { ret.add(m); } return ret; } private URL findProviderUrl(Long id) { return findProvider(id).toUrl(); } public Provider findByServiceAndAddress(String service, String address) { return SyncUtils.url2Provider(findProviderUrl(service, address)); } private Pair<Long, URL> findProviderUrl(String service, String address) { Map<String, String> filter = new HashMap<String, String>(); filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); Map<Long, URL> ret = SyncUtils.filterFromCategory(getRegistryCache(), filter); if(ret.isEmpty()) { return null; } else { Long key = ret.entrySet().iterator().next().getKey(); return new Pair<Long, URL>(key, ret.get(key)); } } }