blob: 24f4f74e3c9247c64ae6cb81c003b75d4d4d4607 [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;
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Service;
29import org.onlab.onos.core.ApplicationId;
30import org.onlab.onos.core.ApplicationIdStore;
31import org.onlab.onos.core.DefaultApplicationId;
32import org.onlab.onos.store.hz.AbstractHazelcastStore;
33import org.onlab.onos.store.hz.SMap;
34import org.onlab.onos.store.serializers.KryoNamespaces;
35import org.onlab.onos.store.serializers.KryoSerializer;
36import org.onlab.util.KryoNamespace;
37
38import java.util.Map;
39import java.util.Set;
40import java.util.concurrent.ConcurrentHashMap;
41
42/**
43 * Simple implementation of the application ID registry using in-memory
44 * structures.
45 */
46@Component(immediate = true)
47@Service
48public class DistributedApplicationIdStore
49 extends AbstractHazelcastStore<AppIdEvent, AppIdStoreDelegate>
50 implements ApplicationIdStore {
51
52 protected IAtomicLong lastAppId;
53 protected SMap<String, DefaultApplicationId> appIdsByName;
54
55 protected Map<Short, DefaultApplicationId> appIds = new ConcurrentHashMap<>();
56
57
58 @Override
59 @Activate
60 public void activate() {
61 super.activate();
62
63 this.serializer = new KryoSerializer() {
64 @Override
65 protected void setupKryoPool() {
66 serializerPool = KryoNamespace.newBuilder()
67 .register(KryoNamespaces.API)
68 .build()
69 .populate(1);
70 }
71 };
72
73 lastAppId = theInstance.getAtomicLong("applicationId");
74
75 appIdsByName = new SMap<>(theInstance.<byte[], byte[]>getMap("appIdsByName"), this.serializer);
76 appIdsByName.addEntryListener((new RemoteAppIdEventHandler()), true);
77
78 primeAppIds();
79
80 log.info("Started");
81 }
82
83 @Deactivate
84 public void deactivate() {
85 log.info("Stopped");
86 }
87
88 @Override
89 public Set<ApplicationId> getAppIds() {
90 return ImmutableSet.<ApplicationId>copyOf(appIds.values());
91 }
92
93 @Override
94 public ApplicationId getAppId(Short id) {
95 ApplicationId appId = appIds.get(id);
96 if (appId == null) {
97 primeAppIds();
98 }
99 return appId;
100 }
101
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700102 private void primeAppIds() {
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700103 for (DefaultApplicationId appId : appIdsByName.values()) {
104 appIds.put(appId.id(), appId);
105 }
106 }
107
108 @Override
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700109 public ApplicationId registerApplication(String name) {
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700110 DefaultApplicationId appId = appIdsByName.get(name);
111 if (appId == null) {
112 short id = (short) lastAppId.getAndIncrement();
Yuta HIGUCHI72569d62014-10-28 22:40:01 -0700113 appId = putIfAbsent(appIdsByName, name,
114 new DefaultApplicationId(id, name));
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700115 }
116 return appId;
117 }
118
119 private class RemoteAppIdEventHandler implements EntryListener<String, DefaultApplicationId> {
120 @Override
121 public void entryAdded(EntryEvent<String, DefaultApplicationId> event) {
122 DefaultApplicationId appId = event.getValue();
123 appIds.put(appId.id(), appId);
124 }
125
126 @Override
127 public void entryRemoved(EntryEvent<String, DefaultApplicationId> event) {
128 }
129
130 @Override
131 public void entryUpdated(EntryEvent<String, DefaultApplicationId> event) {
132 entryAdded(event);
133 }
134
135 @Override
136 public void entryEvicted(EntryEvent<String, DefaultApplicationId> event) {
137 }
138
139 @Override
140 public void mapEvicted(MapEvent event) {
141 }
142
143 @Override
144 public void mapCleared(MapEvent event) {
145 }
146 }
147}