blob: 3fc28fb40788a6cb3ab2a6e66c83a80560504c0e [file] [log] [blame]
tony-liuc3f9b652016-11-10 15:28:17 +08001/*
2 * Copyright 2016-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.tetunnel.impl;
18
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.core.DefaultGroupId;
28import org.onosproject.incubator.net.tunnel.DefaultTunnel;
29import org.onosproject.incubator.net.tunnel.Tunnel;
30import org.onosproject.incubator.net.tunnel.TunnelAdminService;
31import org.onosproject.incubator.net.tunnel.TunnelId;
32import org.onosproject.incubator.net.tunnel.TunnelName;
33import org.onosproject.incubator.net.tunnel.TunnelService;
34import org.onosproject.net.DefaultAnnotations;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.provider.ProviderId;
37import org.onosproject.tetopology.management.api.TeTopology;
38import org.onosproject.tetopology.management.api.TeTopologyKey;
39import org.onosproject.tetopology.management.api.TeTopologyService;
chenqinghui86320ae2016-12-01 15:40:39 +080040import org.onosproject.tetunnel.api.lsp.TeLsp;
41import org.onosproject.tetunnel.api.lsp.TeLspKey;
tony-liuc3f9b652016-11-10 15:28:17 +080042import org.onosproject.tetunnel.api.tunnel.TeTunnel;
43import org.onosproject.tetunnel.api.TeTunnelAdminService;
44import org.onosproject.tetunnel.api.TeTunnelProviderService;
45import org.onosproject.tetunnel.api.TeTunnelService;
46import org.onosproject.tetunnel.api.TeTunnelStore;
47import org.onosproject.tetunnel.api.tunnel.TeTunnelEndpoint;
48import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
49import org.slf4j.Logger;
50
51import java.util.Collection;
52import java.util.List;
53
54import static org.slf4j.LoggerFactory.getLogger;
55
56/**
57 * Implementation of TE tunnel attributes management service.
58 */
59@Component(immediate = true)
60@Service
61public class TeTunnelManager implements TeTunnelService, TeTunnelAdminService,
62 TeTunnelProviderService {
63
64 private static final String TE_TUNNEL_APP = "onos-app-tetunnel";
65
66 private final Logger log = getLogger(getClass());
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected CoreService coreService;
70
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected TeTunnelStore store;
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected TunnelService tunnelService;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected TunnelAdminService tunnelAdminService;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected TeTopologyService teTopologyService;
82
83 private ApplicationId appId;
84
85 @Activate
86 public void activate() {
87 appId = coreService.registerApplication(TE_TUNNEL_APP);
88
89 log.info("Started");
90 }
91
92 @Deactivate
93 public void deactivate() {
94 log.info("Stopped");
95 }
96
97 @Override
98 public TunnelId createTeTunnel(TeTunnel teTunnel) {
99 if (!store.addTeTunnel(teTunnel)) {
100 log.error("can not add teTunnel: {}", teTunnel);
101 return null;
102 }
103
104 TunnelId tunnelId = TunnelId.valueOf(teTunnel.teTunnelKey().toString());
105 Tunnel tunnel = new DefaultTunnel(ProviderId.NONE,
106 new TeTunnelEndpoint(teTunnel.srcNode(),
107 teTunnel.srcTp()),
108 new TeTunnelEndpoint(teTunnel.dstNode(),
109 teTunnel.dstTp()),
110 Tunnel.Type.MPLS, new DefaultGroupId(0),
111 tunnelId,
112 TunnelName.tunnelName(teTunnel.name()),
113 null,
114 DefaultAnnotations.builder().build());
115 store.setTunnelId(teTunnel.teTunnelKey(), tunnelId);
116 TeTopology srcTopology = teTopologyService.teTopology(
117 teTopologyService.teNode(teTunnel.srcNode())
118 .underlayTeTopologyId());
119 if (srcTopology == null) {
120 srcTopology = teTopologyService.teTopology(teTunnel.srcNode()
121 .teTopologyKey());
122 }
123 DeviceId domainId = srcTopology.ownerId();
124 TunnelId id = tunnelService.setupTunnel(appId, domainId, tunnel, null);
125 if (id == null) {
126 log.error("can not create tunnel for te {}",
127 teTunnel.teTunnelKey());
128 store.removeTeTunnel(teTunnel.teTunnelKey());
129 return null;
130 }
131 if (!id.equals(tunnelId)) {
132 //this should not happen
133 log.error("tunnelId changed, oldId:{}, newId:{}", tunnelId, id);
134 store.setTunnelId(teTunnel.teTunnelKey(), id);
135 }
136 return id;
137 }
138
139 @Override
140 public void setTunnelId(TeTunnelKey teTunnelKey, TunnelId tunnelId) {
141 store.setTunnelId(teTunnelKey, tunnelId);
142 }
143
144 @Override
145 public void updateTeTunnel(TeTunnel teTunnel) {
146 //TODO: updateTeTunnel
147 }
148
149 @Override
150 public void updateTunnelState(TeTunnelKey key, Tunnel.State state) {
151 tunnelAdminService.updateTunnelState(
152 tunnelService.queryTunnel(getTunnelId(key)), state);
153 }
154
155 @Override
chenqinghui86320ae2016-12-01 15:40:39 +0800156 public TeLspKey teLspAdded(TeLsp lsp) {
157 if (store.addTeLsp(lsp)) {
158 return lsp.teLspKey();
159 }
160
161 return null;
162 }
163
164 @Override
165 public void teLspRemoved(TeLsp lsp) {
166 store.removeTeLsp(lsp.teLspKey());
167 }
168
169 @Override
170 public void updateTeLsp(TeLsp lsp) {
171 store.updateTeLsp(lsp);
172 }
173
174 @Override
tony-liuc3f9b652016-11-10 15:28:17 +0800175 public void removeTeTunnel(TeTunnelKey teTunnelKey) {
176 tunnelAdminService.updateTunnelState(
177 tunnelService.queryTunnel(getTunnelId(teTunnelKey)),
178 Tunnel.State.REMOVING);
179 List<TeTunnelKey> segmentTunnels =
180 getTeTunnel(teTunnelKey).segmentTunnels();
181 if (segmentTunnels == null || segmentTunnels.isEmpty()) {
182 // this is a single domain tunnel, removes it right away
183 tunnelAdminService.removeTunnel(getTunnelId(teTunnelKey));
184 }
185 }
186
187 @Override
188 public void setSegmentTunnel(TeTunnelKey e2eTunnelKey,
189 List<TeTunnelKey> segmentTunnels) {
190 TeTunnel e2eTunnel = store.getTeTunnel(e2eTunnelKey);
191 if (e2eTunnel == null) {
tony-liuf7d2a262016-10-17 16:32:24 +0800192 log.error("unknown e2eTunnelKey: {}", e2eTunnelKey);
tony-liuc3f9b652016-11-10 15:28:17 +0800193 return;
194 }
195 e2eTunnel.segmentTunnels(segmentTunnels);
196
197 for (TeTunnelKey key : segmentTunnels) {
198 TeTunnel segmentTunnel = store.getTeTunnel(key);
199 if (segmentTunnel == null) {
200 log.warn("unknown segmentTunnel: {}", key);
201 continue;
202 }
tony-liuf7d2a262016-10-17 16:32:24 +0800203 segmentTunnel.e2eTunnelKey(e2eTunnelKey);
tony-liuc3f9b652016-11-10 15:28:17 +0800204 }
205 }
206
207 @Override
208 public TeTunnel getTeTunnel(TeTunnelKey key) {
209 return store.getTeTunnel(key);
210 }
211
212 @Override
213 public TeTunnel getTeTunnel(TunnelId id) {
214 return store.getTeTunnel(id);
215 }
216
217 @Override
218 public TunnelId getTunnelId(TeTunnelKey key) {
219 return store.getTunnelId(key);
220 }
221
222 @Override
223 public Collection<TeTunnel> getTeTunnels() {
224 return store.getTeTunnels();
225 }
226
227 @Override
228 public Collection<TeTunnel> getTeTunnels(TeTunnel.Type type) {
229 return store.getTeTunnels(type);
230 }
231
232 @Override
233 public Collection<TeTunnel> getTeTunnels(TeTopologyKey key) {
234 return store.getTeTunnels(key);
235 }
236
237 @Override
chenqinghui86320ae2016-12-01 15:40:39 +0800238 public TeLsp getTeLsp(TeLspKey key) {
239 return store.getTeLsp(key);
240 }
241
242 @Override
243 public Collection<TeLsp> getTeLsps() {
244 return store.getTeLsps();
245 }
246
247 @Override
tony-liuc3f9b652016-11-10 15:28:17 +0800248 public TunnelId teTunnelAdded(TeTunnel teTunnel) {
249 //TODO teTunnelAdded
250 return null;
251 }
252
253 @Override
254 public void teTunnelRemoved(TeTunnel teTunnel) {
tony-liuf7d2a262016-10-17 16:32:24 +0800255 TeTunnelKey e2eTunnelKey = teTunnel.e2eTunnelKey();
tony-liuc3f9b652016-11-10 15:28:17 +0800256 store.removeTeTunnel(teTunnel.teTunnelKey());
257
258 // it's a segment tunnel
259 if (e2eTunnelKey != null) {
260 boolean finished = true;
261 for (TeTunnelKey key : getTeTunnel(e2eTunnelKey).segmentTunnels()) {
262 if (getTeTunnel(key) != null) {
263 // FIXME need a better way to determine whether a segment tunnel is removed.
264 finished = false;
265 }
266 }
267 if (finished) {
268 // all segment tunnels are removed
269 tunnelAdminService.removeTunnel(getTunnelId(e2eTunnelKey));
270 store.removeTeTunnel(e2eTunnelKey);
271 }
272 }
273 }
274}