blob: 55208ce952643474180eb21a642a5e934895f7ee [file] [log] [blame]
Jian Li75642312017-01-19 14:23:05 -08001/*
2 * Copyright 2017-present 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 */
16package org.onosproject.mapping.impl;
17
Jian Li2c52e562017-03-02 00:15:45 +090018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Iterables;
20import com.google.common.collect.Maps;
Jian Li92919592017-02-27 17:10:47 +090021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
Jian Li2c52e562017-03-02 00:15:45 +090024import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
Jian Li92919592017-02-27 17:10:47 +090026import org.apache.felix.scr.annotations.Service;
Jian Li2c52e562017-03-02 00:15:45 +090027import org.onosproject.mapping.DefaultMapping;
28import org.onosproject.mapping.DefaultMappingEntry;
Jian Li92919592017-02-27 17:10:47 +090029import org.onosproject.mapping.Mapping;
Jian Li92919592017-02-27 17:10:47 +090030import org.onosproject.mapping.MappingEntry;
Jian Li2c52e562017-03-02 00:15:45 +090031import org.onosproject.mapping.MappingEvent;
32import org.onosproject.mapping.MappingId;
33import org.onosproject.mapping.MappingKey;
Jian Li75642312017-01-19 14:23:05 -080034import org.onosproject.mapping.MappingStore;
Jian Li95edb592017-01-29 08:42:07 +090035import org.onosproject.mapping.MappingStoreDelegate;
Jian Li2c52e562017-03-02 00:15:45 +090036import org.onosproject.mapping.MappingTreatment;
37import org.onosproject.mapping.MappingValue;
38import org.onosproject.mapping.actions.MappingAction;
39import org.onosproject.mapping.addresses.MappingAddress;
40import org.onosproject.mapping.instructions.MappingInstruction;
Jian Li92919592017-02-27 17:10:47 +090041import org.onosproject.net.DeviceId;
Jian Li2c52e562017-03-02 00:15:45 +090042import org.onosproject.net.device.DeviceService;
Jian Li92919592017-02-27 17:10:47 +090043import org.onosproject.store.AbstractStore;
Jian Li2c52e562017-03-02 00:15:45 +090044import org.onosproject.store.serializers.KryoNamespaces;
45import org.onosproject.store.service.ConsistentMap;
46import org.onosproject.store.service.MapEvent;
47import org.onosproject.store.service.MapEventListener;
48import org.onosproject.store.service.Serializer;
49import org.onosproject.store.service.StorageService;
Jian Li92919592017-02-27 17:10:47 +090050import org.slf4j.Logger;
51
Jian Li2c52e562017-03-02 00:15:45 +090052import java.util.Map;
53import java.util.concurrent.atomic.AtomicInteger;
54import java.util.stream.Collectors;
55
Jian Li92919592017-02-27 17:10:47 +090056import static org.slf4j.LoggerFactory.getLogger;
Jian Li75642312017-01-19 14:23:05 -080057
58/**
59 * Implementation of a distributed store for managing mapping information.
60 */
Jian Li92919592017-02-27 17:10:47 +090061@Component(immediate = true)
62@Service
63public class DistributedMappingStore
64 extends AbstractStore<MappingEvent, MappingStoreDelegate>
65 implements MappingStore {
66
67 private final Logger log = getLogger(getClass());
68
Jian Li2c52e562017-03-02 00:15:45 +090069 private ConsistentMap<MappingId, Mapping> database;
70 private ConsistentMap<MappingId, Mapping> cache;
71
72 private Map<MappingId, Mapping> databaseMap;
73 private Map<MappingId, Mapping> cacheMap;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected StorageService storageService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected DeviceService deviceService;
80
81 private final MapEventListener<MappingId, Mapping> listener = new InternalListener();
82
Jian Li92919592017-02-27 17:10:47 +090083 @Activate
Jian Li2c52e562017-03-02 00:15:45 +090084 public void activate() {
85
86 Serializer serializer = Serializer.using(KryoNamespaces.API,
87 Mapping.class,
88 DefaultMapping.class,
89 MappingId.class,
90 MappingEvent.Type.class,
91 MappingKey.class,
92 MappingValue.class,
93 MappingAddress.class,
94 MappingAddress.Type.class,
95 MappingAction.class,
96 MappingAction.Type.class,
97 MappingTreatment.class,
98 MappingInstruction.class,
99 MappingInstruction.Type.class);
100
101 database = storageService.<MappingId, Mapping>consistentMapBuilder()
102 .withName("onos-mapping-database")
103 .withSerializer(serializer)
104 .build();
105
106 cache = storageService.<MappingId, Mapping>consistentMapBuilder()
107 .withName("onos-mapping-cache")
108 .withSerializer(serializer)
109 .build();
110
111 database.addListener(listener);
112 cache.addListener(listener);
113 databaseMap = database.asJavaMap();
114 cacheMap = cache.asJavaMap();
Jian Li92919592017-02-27 17:10:47 +0900115 log.info("Started");
116 }
117
118 @Deactivate
Jian Li2c52e562017-03-02 00:15:45 +0900119 public void deactivate() {
120 database.removeListener(listener);
121 cache.removeListener(listener);
Jian Li92919592017-02-27 17:10:47 +0900122 log.info("Stopped");
123 }
124
Jian Li2c52e562017-03-02 00:15:45 +0900125 /**
126 * Obtains map representation of mapping store.
127 *
128 * @param type mapping store type
129 * @return map representation of mapping store
130 */
131 private Map<MappingId, Mapping> getStoreMap(Type type) {
132 switch (type) {
133 case MAP_DATABASE:
134 return databaseMap;
135 case MAP_CACHE:
136 return cacheMap;
137 default:
138 log.warn("Unrecognized map store type {}", type);
139 return Maps.newConcurrentMap();
140 }
Jian Li95edb592017-01-29 08:42:07 +0900141 }
142
Jian Li2c52e562017-03-02 00:15:45 +0900143 /**
144 * Obtains mapping store.
145 *
146 * @param type mapping store type
147 * @return mapping store
148 */
149 private ConsistentMap<MappingId, Mapping> getStore(Type type) {
150 switch (type) {
151 case MAP_DATABASE:
152 return database;
153 case MAP_CACHE:
154 return cache;
155 default:
156 throw new IllegalArgumentException("Wrong mapping store " + type);
157 }
Jian Li95edb592017-01-29 08:42:07 +0900158 }
Jian Li92919592017-02-27 17:10:47 +0900159
160 @Override
161 public int getMappingCount(Type type) {
Jian Li2c52e562017-03-02 00:15:45 +0900162 AtomicInteger sum = new AtomicInteger(0);
163 deviceService.getDevices().forEach(device ->
164 sum.addAndGet(Iterables.size(getMappingEntries(type, device.id()))));
165 return sum.get();
Jian Li92919592017-02-27 17:10:47 +0900166 }
167
168 @Override
169 public MappingEntry getMappingEntry(Type type, Mapping mapping) {
Jian Li2c52e562017-03-02 00:15:45 +0900170
171 return new DefaultMappingEntry(getStoreMap(type).get(mapping.id()));
Jian Li92919592017-02-27 17:10:47 +0900172 }
173
174 @Override
175 public Iterable<MappingEntry> getMappingEntries(Type type, DeviceId deviceId) {
Jian Li2c52e562017-03-02 00:15:45 +0900176
177 Map<MappingId, Mapping> storeMap = getStoreMap(type);
178 return ImmutableList.copyOf(storeMap.values().stream()
179 .filter(m -> m.deviceId() == deviceId)
180 .map(DefaultMappingEntry::new)
181 .collect(Collectors.toList()));
Jian Li92919592017-02-27 17:10:47 +0900182 }
183
184 @Override
Jian Li252750d2017-03-01 04:50:13 +0900185 public void storeMapping(Type type, Mapping mapping) {
186
Jian Li2c52e562017-03-02 00:15:45 +0900187 getStore(type).put(mapping.id(), mapping);
Jian Li252750d2017-03-01 04:50:13 +0900188 }
189
190 @Override
Jian Li2dc9f002017-03-03 04:26:31 +0900191 public MappingEvent removeMapping(Type type, Mapping mapping) {
Jian Li92919592017-02-27 17:10:47 +0900192
Jian Li2c52e562017-03-02 00:15:45 +0900193 getStore(type).remove(mapping.id());
Jian Li92919592017-02-27 17:10:47 +0900194 return null;
195 }
196
197 @Override
Jian Li2dc9f002017-03-03 04:26:31 +0900198 public void pendingDeleteMapping(Type type, Mapping mapping) {
199 // TODO: this will be implemented when management plane is ready
200 log.error("This method will be available when management plane is ready");
201 }
202
203 @Override
204 public MappingEvent addOrUpdateMappingEntry(Type type, MappingEntry entry) {
Jian Li2c52e562017-03-02 00:15:45 +0900205 // TODO: this will be implemented when management plane is ready
206 log.error("This method will be available when management plane is ready");
Jian Li92919592017-02-27 17:10:47 +0900207 return null;
208 }
209
210 @Override
211 public MappingEvent pendingMappingEntry(Type type, MappingEntry entry) {
Jian Li2c52e562017-03-02 00:15:45 +0900212 // TODO: this will be implemented when management plane is ready
213 log.error("This method will be available when management plane is ready");
Jian Li92919592017-02-27 17:10:47 +0900214 return null;
215 }
216
217 @Override
218 public void purgeMappingEntries(Type type) {
Jian Li2c52e562017-03-02 00:15:45 +0900219 getStore(type).clear();
220 }
Jian Li92919592017-02-27 17:10:47 +0900221
Jian Li2c52e562017-03-02 00:15:45 +0900222 /**
223 * Event listener to notify delegates about mapping events.
224 */
225 private class InternalListener implements MapEventListener<MappingId, Mapping> {
226
227 @Override
228 public void event(MapEvent<MappingId, Mapping> event) {
229 final MappingEvent.Type type;
230 final Mapping mapping;
231
232 switch (event.type()) {
233 case INSERT:
234 type = MappingEvent.Type.MAPPING_ADDED;
235 mapping = event.newValue().value();
236 break;
237 case UPDATE:
238 type = MappingEvent.Type.MAPPING_UPDATED;
239 mapping = event.newValue().value();
240 break;
241 case REMOVE:
242 type = MappingEvent.Type.MAPPING_REMOVED;
243 mapping = event.oldValue().value();
244 break;
245 default:
246 throw new IllegalArgumentException("Wrong event type " + event.type());
247 }
248 notifyDelegate(new MappingEvent(type, mapping));
249 }
Jian Li92919592017-02-27 17:10:47 +0900250 }
Jian Li75642312017-01-19 14:23:05 -0800251}