package com.tesora.dve.externalservice; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.lang.reflect.Constructor; import java.net.InetSocketAddress; import java.util.AbstractMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.log4j.Logger; import com.tesora.dve.exceptions.PEException; import com.tesora.dve.groupmanager.GroupManager; import com.tesora.dve.membership.GroupMembershipListener.MembershipEventType; public class ExternalServiceFactory { private static Logger logger = Logger.getLogger(ExternalServiceFactory.class); static Map<String, Entry<ExternalServicePlugin, ExternalServiceContext>> externalServiceMap = new HashMap<String, Entry<ExternalServicePlugin, ExternalServiceContext>>(); public static ExternalServicePlugin register(String serviceName, String externalServiceClass) throws PEException { ExternalServicePlugin esp = null; GroupManager.getCoordinationServices().registerExternalService(serviceName); ExternalServiceContext ctxt = new ExternalServiceContextImpl(serviceName); try { Class<?> pluginClass = Class.forName(externalServiceClass); Constructor<?> ctor = pluginClass.getConstructor(new Class[] {}); esp = (ExternalServicePlugin) ctor.newInstance(new Object[] {}); try { if (esp.denyServiceStart(ctxt)) { esp = null; return esp; } esp.initialize(ctxt); if (logger.isDebugEnabled()) { logger.debug("Service '" + serviceName + "' registered."); } } catch (PEException e) { logger.error("Unable to start external service \"" + serviceName + "\"", e); throw e; } externalServiceMap.put(serviceName, new AbstractMap.SimpleEntry<ExternalServicePlugin, ExternalServiceContext>(esp, ctxt)); } catch (Exception e) { GroupManager.getCoordinationServices().deregisterExternalService(serviceName); if (logger.isDebugEnabled()) { logger.debug("Service '" + serviceName + "' deregistered due to failure to initialize."); } throw new PEException("Cannot instantiate ExternalService '" + externalServiceClass + "'", e); } if (ctxt.getServiceAutoStart()) esp.start(); return esp; } public static boolean isRegistered(String name) { Entry<ExternalServicePlugin, ExternalServiceContext> mapEntry = externalServiceMap.get(name); return ( mapEntry != null ? true : false ); } public static ExternalServicePlugin getInstance(String name) throws PEException { Entry<ExternalServicePlugin, ExternalServiceContext> mapEntry = externalServiceMap.get(name); if ( mapEntry != null ) return mapEntry.getKey(); else throw new PEException("Service '" + name + "' isn't registered" ); } public static void deregister(String name) throws PEException { ExternalServicePlugin esp = externalServiceMap.get(name).getKey(); ExternalServiceContext esc = externalServiceMap.get(name).getValue(); if ( esp == null || esc == null ) { throw new PEException("Could not find a registered service called '" + name + "'"); } esp.close(); esc.close(); externalServiceMap.remove(name); GroupManager.getCoordinationServices().deregisterExternalService(name); } public static void closeExternalServices() throws PEException { Set<String> externalServiceNames = new HashSet<String>(externalServiceMap.keySet()); for (String externalServiceName : externalServiceNames) { deregister(externalServiceName); } externalServiceMap.clear(); } public static void onGroupMembershipEvent(MembershipEventType eventType, InetSocketAddress inetSocketAddress) { Set<String> externalServiceNames = new HashSet<String>(externalServiceMap.keySet()); for (String externalServiceName : externalServiceNames) { try { getInstance(externalServiceName).handleGroupMembershipEvent(eventType, inetSocketAddress); } catch (PEException e) { logger.warn("Service '" + externalServiceName + "' failed to handle group membership event.", e); } } } }