/* * Copyright 2009-2016 Weibo, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.networknt.registry.support.command; import java.util.HashMap; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringUtils; import com.networknt.registry.NotifyListener; import com.networknt.registry.support.FailbackRegistry; import com.networknt.registry.URL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class CommandFailbackRegistry extends FailbackRegistry { private static final Logger logger = LoggerFactory.getLogger(CommandFailbackRegistry.class); private ConcurrentHashMap<URL, CommandServiceManager> commandManagerMap; public CommandFailbackRegistry(URL url) { super(url); commandManagerMap = new ConcurrentHashMap<>(); if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry init. url: " + url.toSimpleString()); } @Override protected void doSubscribe(URL url, final NotifyListener listener) { if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry subscribe. url: " + url.toSimpleString()); URL urlCopy = url.createCopy(); CommandServiceManager manager = getCommandServiceManager(urlCopy); manager.addNotifyListener(listener); subscribeService(urlCopy, manager); subscribeCommand(urlCopy, manager); List<URL> urls = doDiscover(urlCopy); if (urls != null && urls.size() > 0) { this.notify(urlCopy, listener, urls); } } @Override protected void doUnsubscribe(URL url, NotifyListener listener) { if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry unsubscribe. url: " + url.toSimpleString()); URL urlCopy = url.createCopy(); CommandServiceManager manager = commandManagerMap.get(urlCopy); manager.removeNotifyListener(listener); unsubscribeService(urlCopy, manager); unsubscribeCommand(urlCopy, manager); } @Override protected List<URL> doDiscover(URL url) { if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry discover. url: " + url.toSimpleString()); List<URL> finalResult; URL urlCopy = url.createCopy(); String commandStr = discoverCommand(urlCopy); RpcCommand rpcCommand = null; if (StringUtils.isNotEmpty(commandStr)) { rpcCommand = RpcCommandUtil.stringToCommand(commandStr); } if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry discover command. commandStr: " + commandStr + ", rpccommand " + (rpcCommand == null ? "is null." : "is not null.")); if (rpcCommand != null) { rpcCommand.sort(); CommandServiceManager manager = getCommandServiceManager(urlCopy); finalResult = manager.discoverServiceWithCommand(urlCopy, new HashMap<String, Integer>(), rpcCommand); // when subscribing command and notify immediately, other services might not subscribed yet // here just update command to manager to avoid first subscription failure. manager.setCommandCache(commandStr); } else { finalResult = discoverService(urlCopy); } if(logger.isInfoEnabled()) logger.info("CommandFailbackRegistry discover size: " + finalResult.size() + ", result:" + finalResult.toString()); return finalResult; } public List<URL> commandPreview(URL url, RpcCommand rpcCommand, String previewIP) { List<URL> finalResult; URL urlCopy = url.createCopy(); if (rpcCommand != null) { CommandServiceManager manager = getCommandServiceManager(urlCopy); finalResult = manager.discoverServiceWithCommand(urlCopy, new HashMap<>(), rpcCommand, previewIP); } else { finalResult = discoverService(urlCopy); } return finalResult; } private CommandServiceManager getCommandServiceManager(URL urlCopy) { CommandServiceManager manager = commandManagerMap.get(urlCopy); if (manager == null) { manager = new CommandServiceManager(urlCopy); manager.setRegistry(this); CommandServiceManager manager1 = commandManagerMap.putIfAbsent(urlCopy, manager); if (manager1 != null) manager = manager1; } return manager; } // for UnitTest public ConcurrentHashMap<URL, CommandServiceManager> getCommandManagerMap() { return commandManagerMap; } protected abstract void subscribeService(URL url, ServiceListener listener); protected abstract void subscribeCommand(URL url, CommandListener listener); protected abstract void unsubscribeService(URL url, ServiceListener listener); protected abstract void unsubscribeCommand(URL url, CommandListener listener); protected abstract List<URL> discoverService(URL url); protected abstract String discoverCommand(URL url); }