blob: 734cbdcd0293461ddaa5191a1d630908edd022d2 [file] [log] [blame]
pierventre1483e642016-06-08 18:52:29 +02001/*
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.sdxl2;
18
19
20import org.onosproject.core.ApplicationId;
21import org.onosproject.net.ConnectPoint;
22import org.onosproject.net.edge.EdgePortEvent;
23import org.onosproject.net.edge.EdgePortListener;
24import org.onosproject.net.edge.EdgePortService;
25import org.onosproject.net.intent.IntentEvent;
26import org.onosproject.net.intent.IntentListener;
27import org.onosproject.net.intent.IntentService;
28import org.onosproject.net.intent.IntentState;
29import org.onosproject.net.intent.Intent;
30import org.onosproject.net.intent.Key;
31import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
34import java.util.Iterator;
35import java.util.concurrent.ConcurrentHashMap;
36import java.util.concurrent.ConcurrentMap;
37
38/**
39 * Implementation of the SdxL2MonitoringService.
40 */
41public class SdxL2MonitoringManager implements SdxL2MonitoringService {
42
43 private static Logger log = LoggerFactory.getLogger(SdxL2MonitoringManager.class);
44 protected ApplicationId appId;
45 private final IntentService intentService;
46 private final EdgePortService edgePortService;
47
48 /**
49 * It is a local cache for the Intents' events.
50 */
51 private ConcurrentMap<Key, IntentEvent> intentsState;
52 /**
53 * Last time intentsState has been updated.
54 */
55 private long lastIntentUpdate;
56
57 /**
58 * It is a local cache for the edge ports related events.
59 */
60 private ConcurrentMap<ConnectPoint, EdgePortEvent> edgeportsState;
61 /**
62 * Last time edgeportsState has been updated.
63 */
64 private long lastEdgePortUpdate;
65
66 // A kind of timeout which causes a manual update.
67 private static int deltaUpdate = 60000;
68
69 private InternalIntentListener intentListener;
70 private InternalEdgePortListener edgePortListener;
71
72 /**
73 * Creates an SdxL2MonitoringManager.
74 *
75 * @param sdxl2id application id.
76 * @param intentService reference to the Intent service.
77 * @param edgePortService reference to the EdgePort service.
78 */
79 public SdxL2MonitoringManager(ApplicationId sdxl2id, IntentService intentService, EdgePortService edgePortService) {
80
81 this.appId = sdxl2id;
82 this.intentListener = new InternalIntentListener();
83 this.edgePortListener = new InternalEdgePortListener();
84 this.intentService = intentService;
85 this.edgePortService = edgePortService;
86
87 this.intentService.addListener(this.intentListener);
88 this.edgePortService.addListener(this.edgePortListener);
89
90 this.intentsState = new ConcurrentHashMap<>();
91 this.edgeportsState = new ConcurrentHashMap<>();
92
93 this.lastEdgePortUpdate = 0;
94 this.lastIntentUpdate = 0;
95
96 log.info("Started");
97
98 }
99
100 /**
101 * Remove listeners.
102 */
103 public void cleanup() {
104 this.intentService.removeListener(intentListener);
105 this.edgePortService.removeListener(edgePortListener);
106 }
107
108 /**
109 * Returns the state of the Intent that has been provided as input.
110 *
111 * @param intentKey key of the intent;
112 * @return the last state of the intent;
113 */
114 @Override
115 public SdxL2State getIntentState(Key intentKey) {
116 synchronized (intentsState) {
117 IntentEvent event = this.intentsState.get(intentKey);
118 long ts = System.currentTimeMillis();
119 if (event == null || (ts > lastIntentUpdate && ts - lastIntentUpdate > deltaUpdate)) {
120 Intent intent = this.intentService.getIntent(intentKey);
121 IntentState intentState = this.intentService.getIntentState(intentKey);
122 event = IntentEvent.getEvent(intentState, intent).get();
123 intentsState.put(intentKey, event);
124 this.lastIntentUpdate = ts;
125 }
126 return this.getSdxL2State(event.type());
127 }
128 }
129
130 /**
131 * Updates intentsState after an Intent event.
132 *
133 * @param event the event just happened
134 */
135 private void processIntentEvent(IntentEvent event) {
136 synchronized (intentsState) {
137 intentsState.put(event.subject().key(), event);
138 this.lastIntentUpdate = System.currentTimeMillis();
139 }
140 }
141
142 /**
143 * Translates the type of the IntentEvent in SdxL2State.
144 *
145 * @param type the type of event
146 * @return the SdxL2State
147 */
148 private SdxL2State getSdxL2State(IntentEvent.Type type) {
149 SdxL2State state;
150 switch (type) {
151 case INSTALLED:
152 state = SdxL2State.ONLINE;
153 break;
154 case FAILED:
155 state = SdxL2State.OFFLINE;
156 break;
157 case INSTALL_REQ:
158 case WITHDRAW_REQ:
159 case WITHDRAWN:
160 case CORRUPT:
161 case PURGED:
162 default:
163 state = SdxL2State.CHECK;
164 }
165 return state;
166 }
167
168 private class InternalIntentListener implements IntentListener {
169
170 /**
171 * Reacts to the specified event.
172 *
173 * @param event event to be processed
174 */
175 @Override
176 public void event(IntentEvent event) {
177 Intent intent = event.subject();
178 if (intent.appId().equals(appId)) {
179 if (event.type() == IntentEvent.Type.INSTALLED ||
180 event.type() == IntentEvent.Type.FAILED ||
181 event.type() == IntentEvent.Type.WITHDRAWN) {
182 log.info("Intent {} {}", event.subject().key(), event.type());
183 }
184 processIntentEvent(event);
185 }
186 }
187
188 }
189
190 /**
191 * Returns the state of the EdgePort that has been provided as input.
192 *
193 * @param edgeport the connect point representing the edge port
194 * @return the last state of the edge port;
195 */
196 @Override
197 public SdxL2State getEdgePortState(ConnectPoint edgeport) {
198 synchronized (edgeportsState) {
199 EdgePortEvent event = this.edgeportsState.get(edgeport);
200 long ts = System.currentTimeMillis();
201 if (event == null ||
202 (ts > lastEdgePortUpdate && ts - lastEdgePortUpdate > deltaUpdate)) {
203 event = new EdgePortEvent(EdgePortEvent.Type.EDGE_PORT_REMOVED, edgeport);
204 Iterator<ConnectPoint> cps = this.edgePortService.getEdgePoints(edgeport.deviceId()).iterator();
205 while (cps.hasNext()) {
206 if (edgeport.equals(cps.next())) {
207 event = new EdgePortEvent(EdgePortEvent.Type.EDGE_PORT_ADDED, edgeport);
208 break;
209 }
210 }
211 edgeportsState.put(edgeport, event);
212 this.lastEdgePortUpdate = ts;
213 }
214 return this.getSdxL2State(event.type());
215 }
216 }
217
218 /**
219 * Updates edgeportsState after an EdgePort event.
220 *
221 * @param event the event just happened
222 */
223 private void processEdgePortEvent(EdgePortEvent event) {
224 synchronized (edgeportsState) {
225 edgeportsState.put(event.subject(), event);
226 this.lastEdgePortUpdate = System.currentTimeMillis();
227 }
228 }
229
230 /**
231 * Translates the type of EdgePortEvent in SdxL2State.
232 *
233 * @param type the type of event
234 * @return the SdxL2State
235 */
236 private SdxL2State getSdxL2State(EdgePortEvent.Type type) {
237 return type == EdgePortEvent.Type.EDGE_PORT_ADDED ? SdxL2State.ONLINE : SdxL2State.OFFLINE;
238 }
239
240 private class InternalEdgePortListener implements EdgePortListener {
241
242 /**
243 * Reacts to the specified event.
244 *
245 * @param event event to be processed
246 */
247 @Override
248 public void event(EdgePortEvent event) {
249 ConnectPoint cp = event.subject();
250 log.info("ConnectPoint {}/{} {}", cp.elementId().toString(), cp.port().toString(), event.type().toString());
251 processEdgePortEvent(event);
252
253 }
254
255 }
256
257}