2 * Copyright (c) 2014, 2015 Hewlett-Packard Development Company, L.P. 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.aaa.store;
12 import java.lang.management.ManagementFactory;
13 import java.util.Dictionary;
14 import java.util.Hashtable;
15 import java.util.concurrent.locks.ReentrantLock;
16 import javax.management.MBeanServer;
17 import net.sf.ehcache.Cache;
18 import net.sf.ehcache.CacheManager;
19 import net.sf.ehcache.Element;
20 import net.sf.ehcache.config.CacheConfiguration;
21 import net.sf.ehcache.management.ManagementService;
22 import org.apache.felix.dm.Component;
23 import org.opendaylight.aaa.api.Authentication;
24 import org.opendaylight.aaa.api.TokenStore;
25 import org.osgi.service.cm.ConfigurationException;
26 import org.osgi.service.cm.ManagedService;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * A default token store for STS.
36 public class DefaultTokenStore implements TokenStore, ManagedService {
37 private static final Logger LOG = LoggerFactory.getLogger(DefaultTokenStore.class);
38 private static final String TOKEN_STORE_CONFIG_ERR = "Token store configuration error";
40 private static final String TOKEN_CACHE_MANAGER = "org.opendaylight.aaa";
41 private static final String TOKEN_CACHE = "tokens";
42 private static final String EHCACHE_XML = "etc/ehcache.xml";
44 static final String MAX_CACHED_MEMORY = "maxCachedTokensInMemory";
45 static final String MAX_CACHED_DISK = "maxCachedTokensOnDisk";
46 static final String SECS_TO_LIVE = "secondsToLive";
47 static final String SECS_TO_IDLE = "secondsToIdle";
49 // Defaults (needed only for non-Karaf deployments)
50 static final Dictionary<String, String> defaults = new Hashtable<>();
52 defaults.put(MAX_CACHED_MEMORY, Long.toString(10000));
53 defaults.put(MAX_CACHED_DISK, Long.toString(1000000));
54 defaults.put(SECS_TO_IDLE, Long.toString(3600));
55 defaults.put(SECS_TO_LIVE, Long.toString(3600));
59 private static final ReentrantLock cacheLock = new ReentrantLock();
64 // This should be a singleton
68 // Called by DM when all required dependencies are satisfied.
69 void init(Component c) {
70 File ehcache = new File(EHCACHE_XML);
72 if (ehcache.exists()) {
73 cm = CacheManager.create(ehcache.getAbsolutePath());
74 tokens = cm.getCache(TOKEN_CACHE);
75 LOG.info("Initialized token store with custom cache config");
77 cm = CacheManager.getInstance();
79 new CacheConfiguration(TOKEN_CACHE,
80 Integer.parseInt(defaults.get(MAX_CACHED_MEMORY))).maxEntriesLocalDisk(
81 Integer.parseInt(defaults.get(MAX_CACHED_DISK)))
83 Long.parseLong(defaults.get(SECS_TO_LIVE)))
85 Long.parseLong(defaults.get(SECS_TO_IDLE))));
87 LOG.info("Initialized token store with default cache config");
89 cm.setName(TOKEN_CACHE_MANAGER);
91 // JMX for cache management
92 MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
93 ManagementService.registerMBeans(cm, mBeanServer, false, false, false, true);
98 LOG.info("Shutting down token store...");
99 CacheManager.getInstance().shutdown();
103 public Authentication get(String token) {
104 Element elem = tokens.get(token);
105 return (Authentication) ((elem != null) ? elem.getObjectValue() : null);
109 public void put(String token, Authentication auth) {
110 tokens.put(new Element(token, auth));
114 public boolean delete(String token) {
115 return tokens.remove(token);
119 public long tokenExpiration() {
120 return tokens.getCacheConfiguration().getTimeToLiveSeconds();
124 public void updated(@SuppressWarnings("rawtypes") Dictionary props)
125 throws ConfigurationException {
126 LOG.info("Updating token store configuration...");
128 // Someone deleted the configuration, use defaults
134 // Refresh cache configuration...
135 private void reconfig(@SuppressWarnings("rawtypes") Dictionary props)
136 throws ConfigurationException {
139 long secsToIdle = Long.parseLong(props.get(SECS_TO_IDLE).toString());
140 long secsToLive = Long.parseLong(props.get(SECS_TO_LIVE).toString());
141 int maxMem = Integer.parseInt(props.get(MAX_CACHED_MEMORY).toString());
142 int maxDisk = Integer.parseInt(props.get(MAX_CACHED_DISK).toString());
143 CacheConfiguration config = tokens.getCacheConfiguration();
144 config.setTimeToIdleSeconds(secsToIdle);
145 config.setTimeToLiveSeconds(secsToLive);
146 config.maxEntriesLocalHeap(maxMem);
147 config.maxEntriesLocalDisk(maxDisk);
148 } catch (Throwable t) {
149 throw new ConfigurationException(null, TOKEN_STORE_CONFIG_ERR, t);