2 * Copyright (c) 2013 Contextream, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.lispflowmapping.implementation.dao;
11 import java.lang.reflect.ParameterizedType;
12 import java.util.EnumSet;
13 import java.util.HashMap;
14 import java.util.Iterator;
16 import java.util.concurrent.ConcurrentMap;
17 import java.util.concurrent.Executors;
18 import java.util.concurrent.ScheduledExecutorService;
19 import java.util.concurrent.TimeUnit;
21 import org.opendaylight.controller.clustering.services.CacheConfigException;
22 import org.opendaylight.controller.clustering.services.CacheExistException;
23 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
24 import org.opendaylight.controller.clustering.services.IClusterServices;
25 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
26 import org.opendaylight.lispflowmapping.interfaces.dao.ILispTypeConverter;
27 import org.opendaylight.lispflowmapping.interfaces.dao.IQueryAll;
28 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
29 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
30 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOC;
31 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceValue;
32 import org.opendaylight.lispflowmapping.interfaces.dao.MappingValueKey;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 public class ClusterDAOService implements ILispDAO, IQueryAll {
38 protected static final Logger logger = LoggerFactory.getLogger(ClusterDAOService.class);
39 private IClusterContainerServices clusterContainerService = null;
40 private ConcurrentMap<Class<?>, Map<Object, Map<String, Object>>> typeToKeysToValues;
41 private final String CACHE_NAME = "mappingServiceCache";
42 private TimeUnit timeUnit = TimeUnit.SECONDS;
43 private int recordTimeOut = 240;
44 private int cleanInterval = 10;
45 private ScheduledExecutorService scheduler;
47 void setClusterContainerService(IClusterContainerServices s) {
48 this.clusterContainerService = s;
51 scheduler = Executors.newScheduledThreadPool(1);
52 scheduler.scheduleAtFixedRate(new Runnable() {
57 }, 0, cleanInterval, timeUnit);
60 void unsetClusterContainerService(IClusterContainerServices s) {
61 logger.debug("Cluster Service unset");
62 if (this.clusterContainerService == s) {
63 this.clusterContainerService = null;
65 scheduler.shutdownNow();
68 @SuppressWarnings("deprecation")
69 private void allocateCache() {
70 if (this.clusterContainerService == null) {
71 logger.error("un-initialized clusterContainerService, can't create cache");
74 logger.debug("Creating Cache for ClusterDAOService");
76 this.clusterContainerService.createCache(CACHE_NAME, EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
77 } catch (CacheConfigException cce) {
78 logger.error("Cache couldn't be created for ClusterDAOService - check cache mode");
79 } catch (CacheExistException cce) {
80 logger.error("Cache for ClusterDAOService already exists, destroy and recreate");
82 logger.debug("Cache successfully created for ClusterDAOService");
85 @SuppressWarnings({ "unchecked", "deprecation" })
86 private void retrieveCache() {
87 if (this.clusterContainerService == null) {
88 logger.error("un-initialized clusterContainerService, can't retrieve cache");
91 logger.debug("Retrieving cache for ClusterDAOService");
92 typeToKeysToValues = (ConcurrentMap<Class<?>, Map<Object, Map<String, Object>>>) this.clusterContainerService.getCache(CACHE_NAME);
93 if (typeToKeysToValues == null) {
94 logger.error("Cache couldn't be retrieved for ClusterDAOService");
96 logger.debug("Cache was successfully retrieved for ClusterDAOService");
99 public void getAll(IRowVisitor visitor) {
100 for (Map.Entry<Class<?>, Map<Object, Map<String, Object>>> typeEntry : typeToKeysToValues.entrySet()) {
101 for (Map.Entry<Object, Map<String, Object>> keyEntry : typeEntry.getValue().entrySet()) {
102 for (Map.Entry<String, Object> valueEntry : keyEntry.getValue().entrySet()) {
103 visitor.visitRow(typeEntry.getKey(), keyEntry.getKey(), valueEntry.getKey(), valueEntry.getValue());
109 public <K> void put(K key, MappingEntry<?>... values) {
110 Map<Object, Map<String, Object>> keysToValues = getTypeMap(key);
111 Map<String, Object> keyToValues = new HashMap<String, Object>();
112 for (MappingEntry<?> entry : values) {
113 keyToValues.put(entry.getKey(), entry.getValue());
115 keysToValues.put(key, keyToValues);
118 private <K> Map<Object, Map<String, Object>> getTypeMap(K key) {
120 throw new IllegalArgumentException("Illegal null key.");
122 Map<Object, Map<String, Object>> keysToValues = typeToKeysToValues.get(key.getClass());
123 if (keysToValues == null) {
124 throw new IllegalArgumentException("Unknown key type " + key.getClass() + ". must register with IConverter first.");
129 @SuppressWarnings("unchecked")
130 public <K, V> V getSpecific(K key, MappingValueKey<V> valueKey) {
131 Map<Object, Map<String, Object>> keysToValues = getTypeMap(key);
132 Map<String, Object> keyToValues = keysToValues.get(key);
133 if (keyToValues == null) {
136 return (V) keyToValues.get(valueKey.getKey());
139 public void cleanOld() {
140 getAll(new IRowVisitor() {
141 public void visitRow(Class<?> keyType, Object keyId, String valueKey, Object value) {
142 if (value instanceof MappingServiceValue) {
143 MappingServiceValue msv = (MappingServiceValue) value;
144 for (Iterator<MappingServiceRLOC> it = msv.getRlocs().iterator(); it.hasNext();) {
145 MappingServiceRLOC rloc = it.next();
146 if (isExpired(rloc)) {
150 if (msv.getKey() == null && msv.getRlocs().size() == 0) {
156 private boolean isExpired(MappingServiceRLOC rloc) {
157 return System.currentTimeMillis() - rloc.getRegisterdDate().getTime() > TimeUnit.MILLISECONDS.convert(recordTimeOut, timeUnit);
162 public <K> Object getSpecific(K key, String valueKey) {
163 return getSpecific(key, new MappingValueKey<Object>(valueKey));
166 public <K> Map<String, ?> get(K key) {
167 Map<Object, Map<String, Object>> keysToValues = getTypeMap(key);
168 return keysToValues.get(key);
171 public <K> boolean remove(K key) {
172 Map<Object, Map<String, Object>> keysToValues = getTypeMap(key);
173 return keysToValues.remove(key) != null;
176 public <UserType, DbType> void register(Class<? extends ILispTypeConverter<UserType, DbType>> userType) {
177 Class<?> eidType = (Class<?>) ((ParameterizedType) userType.getGenericInterfaces()[0]).getActualTypeArguments()[0];
178 typeToKeysToValues.put(eidType, new HashMap<Object, Map<String, Object>>());
181 public void clearAll() {
182 typeToKeysToValues.clear();
185 public TimeUnit getTimeUnit() {
189 public void setRecordTimeOut(int recordTimeOut) {
190 this.recordTimeOut = recordTimeOut;
193 public int getRecordTimeOut() {
194 return recordTimeOut;
197 public void setTimeUnit(TimeUnit timeUnit) {
198 this.timeUnit = timeUnit;
201 public int getCleanInterval() {
202 return cleanInterval;
205 public void setCleanInterval(int cleanInterval) {
206 this.cleanInterval = cleanInterval;