blob: 4c3aa7ae7dfe0b493f4a7e5beb885511e3f13c64 [file] [log] [blame]
Thomas Vachuskae0f804a2014-10-27 23:40:48 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuskae0f804a2014-10-27 23:40:48 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuskae0f804a2014-10-27 23:40:48 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070015 */
16package org.onlab.onos.store.core.impl;
17
Yuta HIGUCHI72569d62014-10-28 22:40:01 -070018import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent;
19
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070020import com.google.common.collect.ImmutableSet;
21import com.hazelcast.core.EntryEvent;
22import com.hazelcast.core.EntryListener;
23import com.hazelcast.core.IAtomicLong;
24import com.hazelcast.core.MapEvent;
Yuta HIGUCHId1a63e92014-12-02 13:14:28 -080025
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070026import org.apache.felix.scr.annotations.Activate;
27import org.apache.felix.scr.annotations.Component;
28import org.apache.felix.scr.annotations.Deactivate;
29import org.apache.felix.scr.annotations.Service;
30import org.onlab.onos.core.ApplicationId;
31import org.onlab.onos.core.ApplicationIdStore;
32import org.onlab.onos.core.DefaultApplicationId;
33import org.onlab.onos.store.hz.AbstractHazelcastStore;
34import org.onlab.onos.store.hz.SMap;
35import org.onlab.onos.store.serializers.KryoNamespaces;
36import org.onlab.onos.store.serializers.KryoSerializer;
37import org.onlab.util.KryoNamespace;
38
39import java.util.Map;
40import java.util.Set;
41import java.util.concurrent.ConcurrentHashMap;
42
43/**
44 * Simple implementation of the application ID registry using in-memory
45 * structures.
46 */
47@Component(immediate = true)
48@Service
49public class DistributedApplicationIdStore
50 extends AbstractHazelcastStore<AppIdEvent, AppIdStoreDelegate>
51 implements ApplicationIdStore {
52
53 protected IAtomicLong lastAppId;
54 protected SMap<String, DefaultApplicationId> appIdsByName;
55
56 protected Map<Short, DefaultApplicationId> appIds = new ConcurrentHashMap<>();
57
Yuta HIGUCHId1a63e92014-12-02 13:14:28 -080058 private String listenerId;
59
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070060
61 @Override
62 @Activate
63 public void activate() {
64 super.activate();
65
66 this.serializer = new KryoSerializer() {
67 @Override
68 protected void setupKryoPool() {
69 serializerPool = KryoNamespace.newBuilder()
70 .register(KryoNamespaces.API)
Yuta HIGUCHI91768e32014-11-22 05:06:35 -080071 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
72 .build();
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070073 }
74 };
75
76 lastAppId = theInstance.getAtomicLong("applicationId");
77
78 appIdsByName = new SMap<>(theInstance.<byte[], byte[]>getMap("appIdsByName"), this.serializer);
Yuta HIGUCHId1a63e92014-12-02 13:14:28 -080079 listenerId = appIdsByName.addEntryListener((new RemoteAppIdEventHandler()), true);
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070080
81 primeAppIds();
82
83 log.info("Started");
84 }
85
86 @Deactivate
87 public void deactivate() {
Yuta HIGUCHId1a63e92014-12-02 13:14:28 -080088 appIdsByName.removeEntryListener(listenerId);
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070089 log.info("Stopped");
90 }
91
92 @Override
93 public Set<ApplicationId> getAppIds() {
94 return ImmutableSet.<ApplicationId>copyOf(appIds.values());
95 }
96
97 @Override
98 public ApplicationId getAppId(Short id) {
99 ApplicationId appId = appIds.get(id);
100 if (appId == null) {
101 primeAppIds();
102 }
103 return appId;
104 }
105
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700106 private void primeAppIds() {
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700107 for (DefaultApplicationId appId : appIdsByName.values()) {
108 appIds.put(appId.id(), appId);
109 }
110 }
111
112 @Override
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700113 public ApplicationId registerApplication(String name) {
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700114 DefaultApplicationId appId = appIdsByName.get(name);
115 if (appId == null) {
116 short id = (short) lastAppId.getAndIncrement();
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700117 appId = putIfAbsent(appIdsByName, name,
118 new DefaultApplicationId(id, name));
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700119 }
120 return appId;
121 }
122
123 private class RemoteAppIdEventHandler implements EntryListener<String, DefaultApplicationId> {
124 @Override
125 public void entryAdded(EntryEvent<String, DefaultApplicationId> event) {
126 DefaultApplicationId appId = event.getValue();
127 appIds.put(appId.id(), appId);
128 }
129
130 @Override
131 public void entryRemoved(EntryEvent<String, DefaultApplicationId> event) {
132 }
133
134 @Override
135 public void entryUpdated(EntryEvent<String, DefaultApplicationId> event) {
136 entryAdded(event);
137 }
138
139 @Override
140 public void entryEvicted(EntryEvent<String, DefaultApplicationId> event) {
141 }
142
143 @Override
144 public void mapEvicted(MapEvent event) {
145 }
146
147 @Override
148 public void mapCleared(MapEvent event) {
149 }
150 }
151}