blob: f182489a1ede7d0aee9b4c28e88c4befcbfdb347 [file] [log] [blame]
Charles Chan0214ded2016-11-18 17:48:37 -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 */
16
17package org.onosproject.incubator.store.routing.impl;
18
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Modified;
22import org.apache.felix.scr.annotations.Property;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.apache.felix.scr.annotations.Service;
26import org.onlab.packet.IpAddress;
Jonathan Hart96c146b2017-02-24 16:32:00 -080027import org.onlab.packet.IpPrefix;
Charles Chan0214ded2016-11-18 17:48:37 -080028import org.onlab.util.Tools;
29import org.onosproject.cfg.ComponentConfigService;
Jonathan Hart96c146b2017-02-24 16:32:00 -080030import org.onosproject.incubator.net.routing.InternalRouteEvent;
Charles Chan0214ded2016-11-18 17:48:37 -080031import org.onosproject.incubator.net.routing.NextHopData;
32import org.onosproject.incubator.net.routing.Route;
Jonathan Hart96c146b2017-02-24 16:32:00 -080033import org.onosproject.incubator.net.routing.RouteSet;
Charles Chan0214ded2016-11-18 17:48:37 -080034import org.onosproject.incubator.net.routing.RouteStore;
35import org.onosproject.incubator.net.routing.RouteStoreDelegate;
36import org.onosproject.incubator.net.routing.RouteTableId;
37import org.onosproject.store.AbstractStore;
38import org.onosproject.store.service.StorageService;
39import org.osgi.service.component.ComponentContext;
40import org.osgi.service.component.annotations.Activate;
41import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
43
44import java.util.Collection;
45import java.util.Dictionary;
46import java.util.Map;
47import java.util.Set;
48
Charles Chan143bc182017-01-13 15:46:03 -080049import static com.google.common.base.Preconditions.checkState;
50
Charles Chan0214ded2016-11-18 17:48:37 -080051/**
52 * An implementation of RouteStore that is backed by either LocalRouteStore or
53 * DistributedRouteStore according to configuration.
54 */
55@Service
56@Component
Jonathan Hart96c146b2017-02-24 16:32:00 -080057public class RouteStoreImpl extends AbstractStore<InternalRouteEvent, RouteStoreDelegate>
Charles Chan0214ded2016-11-18 17:48:37 -080058 implements RouteStore {
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected ComponentConfigService componentConfigService;
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 public StorageService storageService;
65
66 @Property(name = "distributed", boolValue = false,
67 label = "Enable distributed route store")
68 private boolean distributed;
69
70 private final Logger log = LoggerFactory.getLogger(getClass());
71 private RouteStore currentRouteStore;
72
73 @Activate
74 public void activate(ComponentContext context) {
75 componentConfigService.registerProperties(getClass());
76 modified(context);
77 }
78
79 @Deactivate
80 public void deactivate() {
81 if (distributed) {
82 ((DistributedRouteStore) currentRouteStore).deactivate();
83 } else {
84 ((LocalRouteStore) currentRouteStore).deactivate();
85 }
86 componentConfigService.unregisterProperties(getClass(), false);
87 }
88
89 @Modified
90 public void modified(ComponentContext context) {
91 Dictionary<?, ?> properties = context.getProperties();
92 if (properties == null) {
93 return;
94 }
95
96 String strDistributed = Tools.get(properties, "distributed");
97 boolean expectDistributed = Boolean.parseBoolean(strDistributed);
98
99 // Start route store during first start or config change
100 // NOTE: new route store will be empty
101 if (currentRouteStore == null || expectDistributed != distributed) {
102 if (expectDistributed) {
103 if (currentRouteStore != null) {
104 ((LocalRouteStore) currentRouteStore).deactivate();
105 }
106 currentRouteStore = new DistributedRouteStore(storageService);
107 ((DistributedRouteStore) currentRouteStore).activate();
Charles Chan143bc182017-01-13 15:46:03 -0800108 ((DistributedRouteStore) currentRouteStore).setDelegate(delegate);
Charles Chan0214ded2016-11-18 17:48:37 -0800109 } else {
110 if (currentRouteStore != null) {
111 ((DistributedRouteStore) currentRouteStore).deactivate();
112 }
113 currentRouteStore = new LocalRouteStore();
114 ((LocalRouteStore) currentRouteStore).activate();
Charles Chan143bc182017-01-13 15:46:03 -0800115 ((LocalRouteStore) currentRouteStore).setDelegate(delegate);
Charles Chan0214ded2016-11-18 17:48:37 -0800116 }
117
118 this.distributed = expectDistributed;
119 log.info("Switched to {} route store", distributed ? "distributed" : "local");
120 }
121
122 }
123
124 @Override
Charles Chan143bc182017-01-13 15:46:03 -0800125 public void setDelegate(RouteStoreDelegate delegate) {
126 checkState(this.delegate == null || this.delegate == delegate,
127 "Store delegate already set");
128 this.delegate = delegate;
129
130 // Set the delegate of underlying route store implementation
131 currentRouteStore.setDelegate(delegate);
132 }
133
134 @Override
135 public void unsetDelegate(RouteStoreDelegate delegate) {
136 if (this.delegate == delegate) {
137 this.delegate = null;
138 }
139
140 // Unset the delegate of underlying route store implementation
141 currentRouteStore.unsetDelegate(delegate);
142 }
143
144 @Override
Charles Chan0214ded2016-11-18 17:48:37 -0800145 public void updateRoute(Route route) {
146 currentRouteStore.updateRoute(route);
147 }
148
149 @Override
150 public void removeRoute(Route route) {
151 currentRouteStore.removeRoute(route);
152 }
153
154 @Override
155 public Set<RouteTableId> getRouteTables() {
156 return currentRouteStore.getRouteTables();
157 }
158
159 @Override
Jonathan Hart96c146b2017-02-24 16:32:00 -0800160 public Collection<RouteSet> getRoutes(RouteTableId table) {
Charles Chan0214ded2016-11-18 17:48:37 -0800161 return currentRouteStore.getRoutes(table);
162 }
163
164 @Override
165 public Route longestPrefixMatch(IpAddress ip) {
166 return currentRouteStore.longestPrefixMatch(ip);
167 }
168
169 @Override
170 public Collection<Route> getRoutesForNextHop(IpAddress ip) {
171 return currentRouteStore.getRoutesForNextHop(ip);
172 }
173
174 @Override
Jonathan Hart96c146b2017-02-24 16:32:00 -0800175 public RouteSet getRoutes(IpPrefix prefix) {
176 return currentRouteStore.getRoutes(prefix);
177 }
178
179 @Override
Charles Chan0214ded2016-11-18 17:48:37 -0800180 public void updateNextHop(IpAddress ip, NextHopData nextHopData) {
181 currentRouteStore.updateNextHop(ip, nextHopData);
182 }
183
184 @Override
185 public void removeNextHop(IpAddress ip, NextHopData nextHopData) {
186 currentRouteStore.removeNextHop(ip, nextHopData);
187 }
188
189 @Override
190 public NextHopData getNextHop(IpAddress ip) {
191 return currentRouteStore.getNextHop(ip);
192 }
193
194 @Override
195 public Map<IpAddress, NextHopData> getNextHops() {
196 return currentRouteStore.getNextHops();
197 }
198}