/** * Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors * (see CONTRIBUTORS.md) * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. A copy of the * License is distributed with this work in the LICENSE.md file. You may * also obtain a copy of the License from * * 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 org.gennai.gungnir; import static org.gennai.gungnir.GungnirConfig.*; import java.util.concurrent.locks.ReentrantLock; import org.gennai.gungnir.cluster.ClusterManager; import org.gennai.gungnir.cluster.DistributedClusterManager; import org.gennai.gungnir.cluster.LocalClusterManager; import org.gennai.gungnir.metastore.MetaStore; import org.gennai.gungnir.metastore.MetaStoreException; import org.gennai.gungnir.metastore.NotStoredException; import org.gennai.gungnir.metrics.MetricsManager; import org.gennai.gungnir.tuple.persistent.PersistentDeserializer; import org.gennai.gungnir.tuple.persistent.PersistentDispatcher; import org.gennai.gungnir.tuple.persistent.PersistentEmitter; import org.gennai.gungnir.tuple.persistent.TrackingData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class GungnirManager { private static final Logger LOG = LoggerFactory.getLogger(GungnirManager.class); private static volatile GungnirManager MANAGER; private GungnirConfig config; private volatile MetaStore metaStore; private ReentrantLock metaStoreLock; private volatile MetricsManager metricsManager; private ReentrantLock metricsManagerLock; private volatile ClusterManager clusterManager; private ReentrantLock clusterManagerLock; private GungnirManager(GungnirConfig config) { this.config = config; metaStoreLock = new ReentrantLock(); metricsManagerLock = new ReentrantLock(); clusterManagerLock = new ReentrantLock(); } public static GungnirManager getManager() { if (MANAGER == null) { synchronized (GungnirManager.class) { if (MANAGER == null) { MANAGER = new GungnirManager(GungnirConfig.readGugnirConfig()); } } } return MANAGER; } public GungnirConfig getConfig() { return config; } public MetaStore getMetaStore() throws MetaStoreException { if (metaStore == null) { metaStoreLock.lock(); try { if (metaStore == null) { try { Class<?> metaStoreClass = config.getClass(METASTORE); if (MetaStore.class.isAssignableFrom(metaStoreClass)) { metaStore = (MetaStore) metaStoreClass.newInstance(); metaStore.open(); } else { LOG.error("Invalid metastore class '{}'", metaStoreClass.getName()); throw new MetaStoreException("Failed to create metastore"); } } catch (ClassNotFoundException e) { LOG.error("Failed to create metastore", e); throw new MetaStoreException("Failed to create metastore"); } catch (InstantiationException e) { LOG.error("Failed to create metastore", e); throw new MetaStoreException("Failed to create metastore"); } catch (IllegalAccessException e) { LOG.error("Failed to create metastore", e); throw new MetaStoreException("Failed to create metastore"); } } } finally { metaStoreLock.unlock(); } } return metaStore; } public MetricsManager getMetricsManager() { if (metricsManager == null) { metricsManagerLock.lock(); try { if (metricsManager == null) { metricsManager = new MetricsManager(config); } } finally { metricsManagerLock.unlock(); } } return metricsManager; } public PersistentDispatcher createDispatcher(UserEntity owner) throws MetaStoreException { PersistentDeserializer deserializer = null; try { Class<?> deserClass = config.getClass(PERSISTENT_DESERIALIZER); if (PersistentDeserializer.class.isAssignableFrom(deserClass)) { deserializer = (PersistentDeserializer) deserClass.newInstance(); } else { LOG.error("Invalid persistent deserializer class '{}'", deserClass.getName()); } } catch (ClassNotFoundException e) { LOG.error("Failed to create persistent deserializer", e); } catch (InstantiationException e) { LOG.error("Failed to create persistent deserializer", e); } catch (IllegalAccessException e) { LOG.error("Failed to create persistent deserializer", e); } PersistentEmitter emitter = null; try { Class<?> emitterClass = config.getClass(PERSISTENT_EMITTER); if (PersistentEmitter.class.isAssignableFrom(emitterClass)) { emitter = (PersistentEmitter) emitterClass.newInstance(); } else { LOG.error("Invalid persistent emitter class '{}'", emitterClass.getName()); } } catch (ClassNotFoundException e) { LOG.error("Failed to create persistent emitter", e); } catch (InstantiationException e) { LOG.error("Failed to create persistent emitter", e); } catch (IllegalAccessException e) { LOG.error("Failed to create persistent emitter", e); } if (deserializer != null && emitter != null) { return new PersistentDispatcher(owner, deserializer, emitter); } else { return null; } } public ClusterManager getClusterManager() { if (clusterManager == null) { clusterManagerLock.lock(); try { if (clusterManager == null) { String clusterMode = config.getString(CLUSTER_MODE); if (clusterMode.equals(LOCAL_CLUSTER)) { clusterManager = new LocalClusterManager(); } else { clusterManager = new DistributedClusterManager(); } } } finally { clusterManagerLock.unlock(); } } return clusterManager; } // TODO: No15 public void dispatchTrackingData(String accountId, TrackingData trackingData) throws MetaStoreException, NotStoredException { PersistentDispatcher dispatcher = getClusterManager().getDispatcher(accountId); if (dispatcher != null) { dispatcher.dispatch(trackingData); if (LOG.isInfoEnabled()) { LOG.info("Accept tracking data {}", trackingData); } } else { LOG.warn("Invalid account ID '{}'", accountId); } } public void close() { if (metaStore != null) { metaStore.close(); } if (metricsManager != null) { metricsManager.close(); } if (clusterManager != null) { clusterManager.close(); } } }