blob: d007bb2519662d0154449a22d1b2cc571da70916 [file] [log] [blame]
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07001/*
2 * Copyright 2015-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 */
alshabib79e52872015-12-07 16:01:01 -080016package org.onosproject.incubator.store.mcast.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
alshabib79e52872015-12-07 16:01:01 -080024import org.onlab.util.KryoNamespace;
25import org.onosproject.net.ConnectPoint;
26import org.onosproject.net.mcast.McastEvent;
27import org.onosproject.net.mcast.McastRoute;
28import org.onosproject.net.mcast.McastRouteInfo;
29import org.onosproject.net.mcast.McastStore;
30import org.onosproject.net.mcast.McastStoreDelegate;
31import org.onosproject.store.AbstractStore;
Jonathan Hart07eb0412016-02-08 16:42:29 -080032import org.onosproject.store.serializers.KryoNamespaces;
alshabib79e52872015-12-07 16:01:01 -080033import org.onosproject.store.service.ConsistentMap;
34import org.onosproject.store.service.Serializer;
35import org.onosproject.store.service.StorageService;
36import org.slf4j.Logger;
37
alshabib79e52872015-12-07 16:01:01 -080038import java.util.Map;
39import java.util.Set;
Madan Jampani72282af2016-02-23 14:23:52 -080040import java.util.concurrent.atomic.AtomicReference;
alshabib79e52872015-12-07 16:01:01 -080041
42import static org.slf4j.LoggerFactory.getLogger;
43
44/**
45 * A distributed mcast store implementation. Routes are stored consistently
46 * across the cluster.
47 */
48@Component(immediate = true)
49@Service
50public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreDelegate>
51 implements McastStore {
52 //FIXME the number of events that will potentially be generated here is
alshabib6ec1ee72015-12-18 19:42:24 -080053 // not sustainable, consider changing this to an eventually consistent
54 // map and not emitting events but rather use a provider-like mechanism
55 // to program the dataplane.
alshabib79e52872015-12-07 16:01:01 -080056
57 private static final String MCASTRIB = "mcast-rib-table";
58 private Logger log = getLogger(getClass());
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart07eb0412016-02-08 16:42:29 -080061 protected StorageService storageService;
alshabib79e52872015-12-07 16:01:01 -080062
Jonathan Hart51539b82015-10-29 09:53:04 -070063 protected ConsistentMap<McastRoute, MulticastData> mcastRib;
alshabib79e52872015-12-07 16:01:01 -080064 protected Map<McastRoute, MulticastData> mcastRoutes;
65
66
67 @Activate
68 public void activate() {
69
Jonathan Hart51539b82015-10-29 09:53:04 -070070 mcastRib = storageService.<McastRoute, MulticastData>consistentMapBuilder()
alshabib79e52872015-12-07 16:01:01 -080071 .withName(MCASTRIB)
Jonathan Hart07eb0412016-02-08 16:42:29 -080072 .withSerializer(Serializer.using(KryoNamespace.newBuilder()
alshabib1aa58142016-02-17 15:37:56 -080073 .register(KryoNamespaces.API)
74 .register(
Madan Jampani72282af2016-02-23 14:23:52 -080075 AtomicReference.class,
alshabib1aa58142016-02-17 15:37:56 -080076 MulticastData.class,
77 McastRoute.class,
78 McastRoute.Type.class
79 ).build()))
Jonathan Hart1d006392016-02-11 09:12:56 -080080 //.withRelaxedReadConsistency()
alshabib79e52872015-12-07 16:01:01 -080081 .build();
82
Jonathan Hart51539b82015-10-29 09:53:04 -070083 mcastRoutes = mcastRib.asJavaMap();
alshabib79e52872015-12-07 16:01:01 -080084
85
86 log.info("Started");
87 }
88
89 @Deactivate
90 public void deactivate() {
91 log.info("Stopped");
92 }
93
94 @Override
95 public void storeRoute(McastRoute route, Type operation) {
96 switch (operation) {
97 case ADD:
98 if (mcastRoutes.putIfAbsent(route, MulticastData.empty()) == null) {
99 delegate.notify(new McastEvent(McastEvent.Type.ROUTE_ADDED,
100 McastRouteInfo.mcastRouteInfo(route)));
101 }
102 break;
103 case REMOVE:
104 if (mcastRoutes.remove(route) != null) {
105 delegate.notify(new McastEvent(McastEvent.Type.ROUTE_REMOVED,
106 McastRouteInfo.mcastRouteInfo(route)));
107 }
108 break;
109 default:
110 log.warn("Unknown mcast operation type: {}", operation);
111 }
112 }
113
114 @Override
115 public void storeSource(McastRoute route, ConnectPoint source) {
116 MulticastData data = mcastRoutes.compute(route, (k, v) -> {
117 if (v == null) {
118 return new MulticastData(source);
119 } else {
120 v.setSource(source);
121 }
122 return v;
123 });
124
125
126 if (data != null) {
127 delegate.notify(new McastEvent(McastEvent.Type.SOURCE_ADDED,
128 McastRouteInfo.mcastRouteInfo(route,
129 data.sinks(),
130 source)));
131 }
132
133 }
134
135 @Override
136 public void storeSink(McastRoute route, ConnectPoint sink, Type operation) {
137 MulticastData data = mcastRoutes.compute(route, (k, v) -> {
138 switch (operation) {
139 case ADD:
140 if (v == null) {
141 v = MulticastData.empty();
142 }
143 v.appendSink(sink);
144 break;
145 case REMOVE:
146 if (v != null) {
147 v.removeSink(sink);
148 }
149 break;
150 default:
151 log.warn("Unknown mcast operation type: {}", operation);
152 }
153 return v;
154 });
155
156
157 if (data != null) {
158 switch (operation) {
159 case ADD:
160 delegate.notify(new McastEvent(
161 McastEvent.Type.SINK_ADDED,
162 McastRouteInfo.mcastRouteInfo(route,
163 sink,
164 data.source())));
165 break;
166 case REMOVE:
167 if (data != null) {
168 delegate.notify(new McastEvent(
169 McastEvent.Type.SINK_REMOVED,
170 McastRouteInfo.mcastRouteInfo(route,
171 sink,
172 data.source())));
173 }
174 break;
175 default:
176 log.warn("Unknown mcast operation type: {}", operation);
177 }
178 }
179
180 }
181
182 @Override
183 public ConnectPoint sourceFor(McastRoute route) {
184 return mcastRoutes.getOrDefault(route, MulticastData.empty()).source();
185 }
186
187 @Override
188 public Set<ConnectPoint> sinksFor(McastRoute route) {
189 return mcastRoutes.getOrDefault(route, MulticastData.empty()).sinks();
190 }
191
Jonathan Hart07eb0412016-02-08 16:42:29 -0800192 @Override
193 public Set<McastRoute> getRoutes() {
194 return mcastRoutes.keySet();
195 }
196
alshabib79e52872015-12-07 16:01:01 -0800197}