blob: 82ce04fe2562d30438127bcd4f0ff6e19adb6240 [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;
40import org.onosproject.tetunnel.api.tunnel.TeTunnel;
41import org.onosproject.tetunnel.api.TeTunnelAdminService;
42import org.onosproject.tetunnel.api.TeTunnelProviderService;
43import org.onosproject.tetunnel.api.TeTunnelService;
44import org.onosproject.tetunnel.api.TeTunnelStore;
45import org.onosproject.tetunnel.api.tunnel.TeTunnelEndpoint;
46import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
47import org.slf4j.Logger;
48
49import java.util.Collection;
50import java.util.List;
51
52import static org.slf4j.LoggerFactory.getLogger;
53
54/**
55 * Implementation of TE tunnel attributes management service.
56 */
57@Component(immediate = true)
58@Service
59public class TeTunnelManager implements TeTunnelService, TeTunnelAdminService,
60 TeTunnelProviderService {
61
62 private static final String TE_TUNNEL_APP = "onos-app-tetunnel";
63
64 private final Logger log = getLogger(getClass());
65
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected CoreService coreService;
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected TeTunnelStore store;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected TunnelService tunnelService;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected TunnelAdminService tunnelAdminService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected TeTopologyService teTopologyService;
80
81 private ApplicationId appId;
82
83 @Activate
84 public void activate() {
85 appId = coreService.registerApplication(TE_TUNNEL_APP);
86
87 log.info("Started");
88 }
89
90 @Deactivate
91 public void deactivate() {
92 log.info("Stopped");
93 }
94
95 @Override
96 public TunnelId createTeTunnel(TeTunnel teTunnel) {
97 if (!store.addTeTunnel(teTunnel)) {
98 log.error("can not add teTunnel: {}", teTunnel);
99 return null;
100 }
101
102 TunnelId tunnelId = TunnelId.valueOf(teTunnel.teTunnelKey().toString());
103 Tunnel tunnel = new DefaultTunnel(ProviderId.NONE,
104 new TeTunnelEndpoint(teTunnel.srcNode(),
105 teTunnel.srcTp()),
106 new TeTunnelEndpoint(teTunnel.dstNode(),
107 teTunnel.dstTp()),
108 Tunnel.Type.MPLS, new DefaultGroupId(0),
109 tunnelId,
110 TunnelName.tunnelName(teTunnel.name()),
111 null,
112 DefaultAnnotations.builder().build());
113 store.setTunnelId(teTunnel.teTunnelKey(), tunnelId);
114 TeTopology srcTopology = teTopologyService.teTopology(
115 teTopologyService.teNode(teTunnel.srcNode())
116 .underlayTeTopologyId());
117 if (srcTopology == null) {
118 srcTopology = teTopologyService.teTopology(teTunnel.srcNode()
119 .teTopologyKey());
120 }
121 DeviceId domainId = srcTopology.ownerId();
122 TunnelId id = tunnelService.setupTunnel(appId, domainId, tunnel, null);
123 if (id == null) {
124 log.error("can not create tunnel for te {}",
125 teTunnel.teTunnelKey());
126 store.removeTeTunnel(teTunnel.teTunnelKey());
127 return null;
128 }
129 if (!id.equals(tunnelId)) {
130 //this should not happen
131 log.error("tunnelId changed, oldId:{}, newId:{}", tunnelId, id);
132 store.setTunnelId(teTunnel.teTunnelKey(), id);
133 }
134 return id;
135 }
136
137 @Override
138 public void setTunnelId(TeTunnelKey teTunnelKey, TunnelId tunnelId) {
139 store.setTunnelId(teTunnelKey, tunnelId);
140 }
141
142 @Override
143 public void updateTeTunnel(TeTunnel teTunnel) {
144 //TODO: updateTeTunnel
145 }
146
147 @Override
148 public void updateTunnelState(TeTunnelKey key, Tunnel.State state) {
149 tunnelAdminService.updateTunnelState(
150 tunnelService.queryTunnel(getTunnelId(key)), state);
151 }
152
153 @Override
154 public void removeTeTunnel(TeTunnelKey teTunnelKey) {
155 tunnelAdminService.updateTunnelState(
156 tunnelService.queryTunnel(getTunnelId(teTunnelKey)),
157 Tunnel.State.REMOVING);
158 List<TeTunnelKey> segmentTunnels =
159 getTeTunnel(teTunnelKey).segmentTunnels();
160 if (segmentTunnels == null || segmentTunnels.isEmpty()) {
161 // this is a single domain tunnel, removes it right away
162 tunnelAdminService.removeTunnel(getTunnelId(teTunnelKey));
163 }
164 }
165
166 @Override
167 public void setSegmentTunnel(TeTunnelKey e2eTunnelKey,
168 List<TeTunnelKey> segmentTunnels) {
169 TeTunnel e2eTunnel = store.getTeTunnel(e2eTunnelKey);
170 if (e2eTunnel == null) {
tony-liuf7d2a262016-10-17 16:32:24 +0800171 log.error("unknown e2eTunnelKey: {}", e2eTunnelKey);
tony-liuc3f9b652016-11-10 15:28:17 +0800172 return;
173 }
174 e2eTunnel.segmentTunnels(segmentTunnels);
175
176 for (TeTunnelKey key : segmentTunnels) {
177 TeTunnel segmentTunnel = store.getTeTunnel(key);
178 if (segmentTunnel == null) {
179 log.warn("unknown segmentTunnel: {}", key);
180 continue;
181 }
tony-liuf7d2a262016-10-17 16:32:24 +0800182 segmentTunnel.e2eTunnelKey(e2eTunnelKey);
tony-liuc3f9b652016-11-10 15:28:17 +0800183 }
184 }
185
186 @Override
187 public TeTunnel getTeTunnel(TeTunnelKey key) {
188 return store.getTeTunnel(key);
189 }
190
191 @Override
192 public TeTunnel getTeTunnel(TunnelId id) {
193 return store.getTeTunnel(id);
194 }
195
196 @Override
197 public TunnelId getTunnelId(TeTunnelKey key) {
198 return store.getTunnelId(key);
199 }
200
201 @Override
202 public Collection<TeTunnel> getTeTunnels() {
203 return store.getTeTunnels();
204 }
205
206 @Override
207 public Collection<TeTunnel> getTeTunnels(TeTunnel.Type type) {
208 return store.getTeTunnels(type);
209 }
210
211 @Override
212 public Collection<TeTunnel> getTeTunnels(TeTopologyKey key) {
213 return store.getTeTunnels(key);
214 }
215
216 @Override
217 public TunnelId teTunnelAdded(TeTunnel teTunnel) {
218 //TODO teTunnelAdded
219 return null;
220 }
221
222 @Override
223 public void teTunnelRemoved(TeTunnel teTunnel) {
tony-liuf7d2a262016-10-17 16:32:24 +0800224 TeTunnelKey e2eTunnelKey = teTunnel.e2eTunnelKey();
tony-liuc3f9b652016-11-10 15:28:17 +0800225 store.removeTeTunnel(teTunnel.teTunnelKey());
226
227 // it's a segment tunnel
228 if (e2eTunnelKey != null) {
229 boolean finished = true;
230 for (TeTunnelKey key : getTeTunnel(e2eTunnelKey).segmentTunnels()) {
231 if (getTeTunnel(key) != null) {
232 // FIXME need a better way to determine whether a segment tunnel is removed.
233 finished = false;
234 }
235 }
236 if (finished) {
237 // all segment tunnels are removed
238 tunnelAdminService.removeTunnel(getTunnelId(e2eTunnelKey));
239 store.removeTeTunnel(e2eTunnelKey);
240 }
241 }
242 }
243}