Madan Jampani

Provide an implementation of ApplicationIdStore atop AtomicCounter and Consisten…

…tMap + Disaable the hazelcast version

Change-Id: I26afea0fadae272baafc55edd8f6c8194b41e3a7
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onosproject.store.core.impl;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.Map;
21 +import java.util.Set;
22 +import org.apache.felix.scr.annotations.Activate;
23 +import org.apache.felix.scr.annotations.Component;
24 +import org.apache.felix.scr.annotations.Deactivate;
25 +import org.apache.felix.scr.annotations.Reference;
26 +import org.apache.felix.scr.annotations.ReferenceCardinality;
27 +import org.apache.felix.scr.annotations.Service;
28 +import org.onlab.util.KryoNamespace;
29 +import org.onosproject.core.ApplicationId;
30 +import org.onosproject.core.ApplicationIdStore;
31 +import org.onosproject.core.DefaultApplicationId;
32 +import org.onosproject.store.serializers.KryoNamespaces;
33 +import org.onosproject.store.service.AtomicCounter;
34 +import org.onosproject.store.service.ConsistentMap;
35 +import org.onosproject.store.service.Serializer;
36 +import org.onosproject.store.service.StorageService;
37 +import org.onosproject.store.service.Versioned;
38 +import org.slf4j.Logger;
39 +
40 +import com.google.common.collect.ImmutableSet;
41 +import com.google.common.collect.Maps;
42 +
43 +/**
44 + * ApplicationIdStore implementation on top of {@code AtomicCounter}
45 + * and {@code ConsistentMap} primitives.
46 + */
47 +@Component(immediate = true, enabled = true)
48 +@Service
49 +public class ConsistentApplicationIdStore implements ApplicationIdStore {
50 +
51 + private final Logger log = getLogger(getClass());
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected StorageService storageService;
55 +
56 + private AtomicCounter appIdCounter;
57 + private ConsistentMap<String, ApplicationId> registeredIds;
58 + private Map<String, ApplicationId> nameToAppIdCache = Maps.newConcurrentMap();
59 + private Map<Short, ApplicationId> idToAppIdCache = Maps.newConcurrentMap();
60 +
61 + private static final Serializer SERIALIZER = Serializer.using(new KryoNamespace.Builder()
62 + .register(KryoNamespaces.API)
63 + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
64 + .build());
65 +
66 + @Activate
67 + public void activate() {
68 + appIdCounter = storageService.atomicCounterBuilder()
69 + .withName("onos-app-id-counter")
70 + .withPartitionsDisabled()
71 + .build();
72 +
73 + registeredIds = storageService.<String, ApplicationId>consistentMapBuilder()
74 + .withName("onos-app-ids")
75 + .withPartitionsDisabled()
76 + .withSerializer(SERIALIZER)
77 + .build();
78 +
79 + primeAppIds();
80 +
81 + log.info("Started");
82 + }
83 +
84 + @Deactivate
85 + public void deactivate() {
86 + log.info("Stopped");
87 + }
88 +
89 + @Override
90 + public Set<ApplicationId> getAppIds() {
91 + // TODO: Rework this when we have notification support in ConsistentMap.
92 + primeAppIds();
93 + return ImmutableSet.copyOf(nameToAppIdCache.values());
94 + }
95 +
96 + @Override
97 + public ApplicationId getAppId(Short id) {
98 + if (!idToAppIdCache.containsKey(id)) {
99 + primeAppIds();
100 + }
101 + return idToAppIdCache.get(id);
102 + }
103 +
104 + @Override
105 + public ApplicationId getAppId(String name) {
106 + ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> {
107 + Versioned<ApplicationId> existingAppId = registeredIds.get(key);
108 + return existingAppId != null ? existingAppId.value() : null;
109 + });
110 + if (appId != null) {
111 + idToAppIdCache.putIfAbsent(appId.id(), appId);
112 + }
113 + return appId;
114 + }
115 +
116 + @Override
117 + public ApplicationId registerApplication(String name) {
118 + ApplicationId appId = nameToAppIdCache.computeIfAbsent(name, key -> {
119 + Versioned<ApplicationId> existingAppId = registeredIds.get(name);
120 + if (existingAppId == null) {
121 + int id = (int) appIdCounter.incrementAndGet();
122 + DefaultApplicationId newAppId = new DefaultApplicationId(id, name);
123 + existingAppId = registeredIds.putIfAbsent(name, newAppId);
124 + if (existingAppId != null) {
125 + return existingAppId.value();
126 + } else {
127 + return newAppId;
128 + }
129 + } else {
130 + return existingAppId.value();
131 + }
132 + });
133 + idToAppIdCache.putIfAbsent(appId.id(), appId);
134 + return appId;
135 + }
136 +
137 + private void primeAppIds() {
138 + registeredIds.values()
139 + .stream()
140 + .map(Versioned::value)
141 + .forEach(appId -> {
142 + nameToAppIdCache.putIfAbsent(appId.name(), appId);
143 + idToAppIdCache.putIfAbsent(appId.id(), appId);
144 + });
145 + }
146 +}
...@@ -44,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -44,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap;
44 * Simple implementation of the application ID registry using in-memory 44 * Simple implementation of the application ID registry using in-memory
45 * structures. 45 * structures.
46 */ 46 */
47 -@Component(immediate = true) 47 +@Component(immediate = false, enabled = false)
48 @Service 48 @Service
49 public class DistributedApplicationIdStore 49 public class DistributedApplicationIdStore
50 extends AbstractHazelcastStore<AppIdEvent, AppIdStoreDelegate> 50 extends AbstractHazelcastStore<AppIdEvent, AppIdStoreDelegate>
......