blob: 92043d5bd9c9703780f6cd7bcf78d9970475fb5d [file] [log] [blame]
Aaron Kruglikov309068e2017-03-17 15:25:54 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Aaron Kruglikov309068e2017-03-17 15:25:54 -07003 *
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
Thomas Vachuska59d24eb2017-03-22 10:57:34 -070017package org.onosproject.netconf.client.impl;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070018
19import com.google.common.annotations.Beta;
20import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070022import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onosproject.config.DynamicConfigEvent;
26import org.onosproject.config.DynamicConfigListener;
27import org.onosproject.config.DynamicConfigService;
Sithara Punnassery0b51d432017-03-28 01:09:28 -070028import org.onosproject.config.ResourceIdParser;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070029import org.onosproject.config.Filter;
30import org.onosproject.mastership.MastershipService;
31import org.onosproject.net.DeviceId;
Thomas Vachuska59d24eb2017-03-22 10:57:34 -070032import org.onosproject.netconf.NetconfController;
33import org.onosproject.netconf.NetconfException;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070034import org.onosproject.netconf.client.NetconfTranslator;
35import org.onosproject.netconf.client.NetconfTranslator.OperationType;
36import org.onosproject.yang.model.DataNode;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053037import org.onosproject.yang.model.InnerNode;
Sithara Punnassery425837f2017-03-21 12:58:00 -070038import org.onosproject.yang.model.LeafNode;
Sithara Punnasserybda82502017-03-22 19:08:19 -070039import org.onosproject.yang.model.ListKey;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053040import org.onosproject.yang.model.NodeKey;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070041import org.onosproject.yang.model.ResourceId;
Thomas Vachuskaa4d5a492017-05-10 12:02:43 -070042import org.onosproject.yang.model.DefaultResourceData;
Sithara Punnassery326b61d2017-03-24 14:15:04 -070043import org.onlab.util.AbstractAccumulator;
44import org.onlab.util.Accumulator;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070045import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47
48import java.io.IOException;
Thomas Vachuska59d24eb2017-03-22 10:57:34 -070049import java.net.URI;
50import java.net.URISyntaxException;
Sithara Punnassery0b51d432017-03-28 01:09:28 -070051import java.util.ArrayList;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053052import java.util.Iterator;
Sithara Punnassery0b51d432017-03-28 01:09:28 -070053import java.util.LinkedHashMap;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053054import java.util.List;
55import java.util.Map;
Sithara Punnassery326b61d2017-03-24 14:15:04 -070056import java.util.Timer;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053057
58import static com.google.common.base.Preconditions.checkNotNull;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070059
Sithara Punnassery425837f2017-03-21 12:58:00 -070060
Aaron Kruglikov309068e2017-03-17 15:25:54 -070061@Beta
62@Component(immediate = true)
Sithara Punnassery425837f2017-03-21 12:58:00 -070063public class NetconfActiveComponent implements DynamicConfigListener {
Aaron Kruglikov309068e2017-03-17 15:25:54 -070064
Sithara Punnassery425837f2017-03-21 12:58:00 -070065 private static final Logger log = LoggerFactory.getLogger(NetconfActiveComponent.class);
Aaron Kruglikov309068e2017-03-17 15:25:54 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sithara Punnassery425837f2017-03-21 12:58:00 -070067 protected DynamicConfigService cfgService;
Aaron Kruglikov309068e2017-03-17 15:25:54 -070068
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected NetconfTranslator netconfTranslator;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected MastershipService mastershipService;
74
Sithara Punnassery425837f2017-03-21 12:58:00 -070075 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected NetconfController controller;
77
Sithara Punnassery326b61d2017-03-24 14:15:04 -070078 private final Accumulator<DynamicConfigEvent> accumulator = new InternalEventAccummulator();
79 private static final String DEVNMSPACE = "ne-l3vpn-api";
80 private static final String DEVICES = "devices";
81 private static final String DEVICE = "device";
82 private static final String DEVICE_ID = "deviceid";
Sithara Punnasserydcc83b12017-03-28 18:19:14 -070083 private static final String DEF_IP = "0:0:0"; //hack, remove later
Sithara Punnassery326b61d2017-03-24 14:15:04 -070084
85 //Symbolic constants for use with the accumulator
86 private static final int MAX_EVENTS = 1000;
87 private static final int MAX_BATCH_MS = 5000;
88 private static final int MAX_IDLE_MS = 1000;
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053089
Sithara Punnasserydcc83b12017-03-28 18:19:14 -070090
Sithara Punnassery0b51d432017-03-28 01:09:28 -070091 private ResourceId defParent = new ResourceId.Builder()
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +053092 .addBranchPointSchema(DEVICES, DEVNMSPACE)
93 .addBranchPointSchema(DEVICE, DEVNMSPACE)
Sithara Punnasserydcc83b12017-03-28 18:19:14 -070094 //.addBranchPointSchema(DEVICE_ID, DEVNMSPACE)
95 .addKeyLeaf(DEVICE_ID, DEVNMSPACE, DEF_IP)
Aaron Kruglikov309068e2017-03-17 15:25:54 -070096 .build();
Thomas Vachuska59d24eb2017-03-22 10:57:34 -070097
Sithara Punnassery0b51d432017-03-28 01:09:28 -070098 //TODO remove this hack after store ordering is fixed
99 private static final String EXCPATH = "root|devices#ne-l3vpn-api|" +
100 "device#ne-l3vpn-api$deviceid#ne-l3vpn-api#netconf:172.16.5.11:22|" +
101 "l3vpn#ne-l3vpn-api|l3vpncomm#ne-l3vpn-api|l3vpnInstances#ne-l3vpn-api|" +
102 "l3vpnInstance#ne-l3vpn-api$vrfName#ne-l3vpn-api#vrf2|l3vpnIfs#ne-l3vpn-api";
103 //end of hack
104
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700105 @Activate
106 protected void activate() {
Sithara Punnassery425837f2017-03-21 12:58:00 -0700107 cfgService.addListener(this);
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700108 log.info("Started");
109 }
110
111 @Deactivate
112 protected void deactivate() {
Sithara Punnassery425837f2017-03-21 12:58:00 -0700113 cfgService.removeListener(this);
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700114 log.info("Stopped");
115 }
116
117 @Override
118 public boolean isRelevant(DynamicConfigEvent event) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700119 String resId = ResourceIdParser.parseResId(event.subject());
120 String refId = ResourceIdParser.parseResId(defParent);
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700121 refId = refId.substring(0, refId.length() - (DEF_IP.length() + 1));
122 if (!resId.contains(refId)) {
123 return false;
124 }
125 if (resId.length() < refId.length()) {
126 return false;
127 }
128 return (resId.substring(0, (refId.length())).compareTo(refId) == 0);
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700129 }
Sithara Punnassery425837f2017-03-21 12:58:00 -0700130
131 public boolean isMaster(DeviceId deviceId) {
Thomas Vachuska59d24eb2017-03-22 10:57:34 -0700132 return mastershipService.isLocalMaster(deviceId);
Sithara Punnassery425837f2017-03-21 12:58:00 -0700133 }
134
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700135
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700136 @Override
137 public void event(DynamicConfigEvent event) {
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700138 accumulator.add(event);
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700139 }
140
141 /**
142 * Performs the delete operation corresponding to the passed event.
Thomas Vachuska59d24eb2017-03-22 10:57:34 -0700143 *
144 * @param node a relevant dataNode
145 * @param deviceId the deviceId of the device to be updated
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700146 * @param resourceId the resourceId of the root of the subtree to be edited
147 * @return true if the update succeeds false otherwise
148 */
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700149 private boolean configDelete(DataNode node, DeviceId deviceId, ResourceId resourceId) {
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700150 return parseAndEdit(node, deviceId, resourceId, OperationType.DELETE);
151 }
152
153 /**
154 * Performs the update operation corresponding to the passed event.
Thomas Vachuska59d24eb2017-03-22 10:57:34 -0700155 *
156 * @param node a relevant dataNode
157 * @param deviceId the deviceId of the device to be updated
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700158 * @param resourceId the resourceId of the root of the subtree to be edited
159 * @return true if the update succeeds false otherwise
160 */
161 private boolean configUpdate(DataNode node, DeviceId deviceId, ResourceId resourceId) {
162 return parseAndEdit(node, deviceId, resourceId, OperationType.REPLACE);
163 }
164
165 /**
166 * Parses the incoming event and pushes configuration to the effected
167 * device.
Thomas Vachuska59d24eb2017-03-22 10:57:34 -0700168 *
169 * @param node the dataNode effecting a particular device of which this node
170 * is master
171 * @param deviceId the deviceId of the device to be modified
172 * @param resourceId the resourceId of the root of the subtree to be edited
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700173 * @param operationType the type of editing to be performed
174 * @return true if the operation succeeds, false otherwise
175 */
176 private boolean parseAndEdit(DataNode node, DeviceId deviceId,
177 ResourceId resourceId,
178 NetconfTranslator.OperationType operationType) {
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700179 //FIXME Separate edit and delete, delete can proceed with a null node
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +0530180 DefaultResourceData.Builder builder = DefaultResourceData.builder();
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700181 if (node != null) {
182 //add all low level nodes of devices
183 Iterator<Map.Entry<NodeKey, DataNode>> it = ((InnerNode) node)
184 .childNodes().entrySet().iterator();
185 while (it.hasNext()) {
186 DataNode n = it.next().getValue();
187 if (!n.key().schemaId().name().equals("deviceid")) {
188 builder.addDataNode(n);
189 }
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +0530190 }
191 }
192 //add resouce id //TODO: check if it is correct
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700193 try {
194 return netconfTranslator.editDeviceConfig(
Bharat saraswalb0dbe6b2017-03-24 22:51:06 +0530195 deviceId, builder.build(), operationType);
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700196 } catch (IOException e) {
197 e.printStackTrace();
198 return false;
199 }
200 }
201
202 /**
Sithara Punnassery425837f2017-03-21 12:58:00 -0700203 * Retrieves device id from Data node.
204 *
205 * @param node the node associated with the event
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700206 * @return the deviceId of the effected device
207 */
Sithara Punnasserybda82502017-03-22 19:08:19 -0700208 @Beta
Sithara Punnassery425837f2017-03-21 12:58:00 -0700209 public DeviceId getDeviceId(DataNode node) {
210 String[] temp;
211 String ip, port;
212 if (node.type() == DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE) {
213 temp = ((LeafNode) node).asString().split("\\:");
214 if (temp.length != 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800215 throw new IllegalStateException(new NetconfException("Invalid device id form, cannot apply"));
Sithara Punnassery425837f2017-03-21 12:58:00 -0700216 }
217 ip = temp[1];
218 port = temp[2];
Sithara Punnasserybda82502017-03-22 19:08:19 -0700219 } else if (node.type() == DataNode.Type.MULTI_INSTANCE_NODE) {
220 ListKey key = (ListKey) node.key();
221 temp = key.keyLeafs().get(0).leafValAsString().split("\\:");
222 if (temp.length != 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800223 throw new IllegalStateException(new NetconfException("Invalid device id form, cannot apply"));
Sithara Punnasserybda82502017-03-22 19:08:19 -0700224 }
225 ip = temp[1];
226 port = temp[2];
Sithara Punnassery425837f2017-03-21 12:58:00 -0700227 } else {
Ray Milkey986a47a2018-01-25 11:38:51 -0800228 throw new IllegalStateException(new NetconfException("Invalid device id type, cannot apply"));
Sithara Punnassery425837f2017-03-21 12:58:00 -0700229 }
230 try {
231 return DeviceId.deviceId(new URI("netconf", ip + ":" + port, (String) null));
232 } catch (URISyntaxException var4) {
233 throw new IllegalArgumentException("Unable to build deviceID for device " + ip + ":" + port, var4);
234 }
235 }
236
237 /**
238 * Inititates a Netconf connection to the device.
239 *
240 * @param deviceId of the added device
241 */
242 private void initiateConnection(DeviceId deviceId) {
243 if (controller.getNetconfDevice(deviceId) == null) {
244 try {
245 //if (this.isReachable(deviceId)) {
Thomas Vachuska59d24eb2017-03-22 10:57:34 -0700246 this.controller.connectDevice(deviceId);
Sithara Punnassery425837f2017-03-21 12:58:00 -0700247 //}
248 } catch (Exception ex) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800249 throw new IllegalStateException(new NetconfException("Unable to connect to NETCONF device on " +
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700250 deviceId, ex));
251 }
252 }
253 }
254
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700255 /**
256 * Retrieves device key from Resource id.
257 *
258 * @param path associated with the event
259 * @return the deviceId of the effected device
260 */
261 @Beta
262 public ResourceId getDeviceKey(ResourceId path) {
263 String resId = ResourceIdParser.parseResId(path);
264 String[] el = resId.split(ResourceIdParser.EL_CHK);
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700265 if (el.length < 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800266 throw new IllegalStateException(new NetconfException("Invalid resource id, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700267 }
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700268 if (!el[2].contains((ResourceIdParser.KEY_SEP))) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800269 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700270 }
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700271 String[] keys = el[2].split(ResourceIdParser.KEY_CHK);
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700272 if (keys.length < 2) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800273 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700274 }
275 String[] parts = keys[1].split(ResourceIdParser.NM_CHK);
276 if (parts.length < 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800277 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700278 }
279 if (parts[2].split("\\:").length != 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800280 throw new IllegalStateException(new NetconfException("Invalid device id form, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700281 }
282 return (new ResourceId.Builder()
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700283 .addBranchPointSchema(el[1].split(ResourceIdParser.NM_CHK)[0],
284 el[1].split(ResourceIdParser.NM_CHK)[1])
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700285 .addBranchPointSchema(keys[0].split(ResourceIdParser.NM_CHK)[0],
286 keys[0].split(ResourceIdParser.NM_CHK)[1])
287 .addKeyLeaf(parts[0], parts[1], parts[2])
288 .build());
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700289 }
290
291 /**
292 * Retrieves device id from Resource id.
293 *
294 * @param path associated with the event
295 * @return the deviceId of the effected device
296 */
297 @Beta
298 public DeviceId getDeviceId(ResourceId path) {
299 String resId = ResourceIdParser.parseResId(path);
300 String[] el = resId.split(ResourceIdParser.EL_CHK);
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700301 if (el.length < 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800302 throw new IllegalStateException(new NetconfException("Invalid resource id, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700303 }
304 if (!el[2].contains((ResourceIdParser.KEY_SEP))) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800305 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700306 }
307 String[] keys = el[2].split(ResourceIdParser.KEY_CHK);
308 if (keys.length < 2) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800309 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700310 }
311 String[] parts = keys[1].split(ResourceIdParser.NM_CHK);
312 if (parts.length < 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800313 throw new IllegalStateException(new NetconfException("Invalid device id key, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700314 }
315 String[] temp = parts[2].split("\\:");
316 String ip, port;
317 if (temp.length != 3) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800318 throw new IllegalStateException(new NetconfException("Invalid device id form, cannot apply"));
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700319 }
320 ip = temp[1];
321 port = temp[2];
322 try {
323 return DeviceId.deviceId(new URI("netconf", ip + ":" + port, (String) null));
324 } catch (URISyntaxException ex) {
325 throw new IllegalArgumentException("Unable to build deviceID for device " + ip + ":" + port, ex);
326 }
327 }
328
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700329 /* Accumulates events to allow processing after a desired number of events were accumulated.
330 */
331 private class InternalEventAccummulator extends AbstractAccumulator<DynamicConfigEvent> {
332 protected InternalEventAccummulator() {
333 super(new Timer("dyncfgevt-timer"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
334 }
335 @Override
336 public void processItems(List<DynamicConfigEvent> events) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700337 Map<ResourceId, List<DynamicConfigEvent>> evtmap = new LinkedHashMap<>();
338 Boolean handleEx = false; //hack
339 ResourceId exId = null; //hack
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700340 for (DynamicConfigEvent e : events) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700341 checkNotNull(e, "process:Event cannot be null");
342 ResourceId cur = e.subject();
343 //TODO remove this hack after store ordering is fixed
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700344 String expat = ResourceIdParser.parseResId(cur);
345 if ((expat.compareTo(EXCPATH) == 0) && (e.type() == DynamicConfigEvent.Type.NODE_ADDED)) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700346 handleEx = true;
347 exId = cur;
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700348 } else { //actual code
349 ResourceId key = getDeviceKey(e.subject());
350 List<DynamicConfigEvent> el = evtmap.get(key);
351 if (el == null) {
352 el = new ArrayList<>();
353 }
354 el.add(e);
355 evtmap.put(key, el);
Sithara Punnassery326b61d2017-03-24 14:15:04 -0700356 }
Sithara Punnassery425837f2017-03-21 12:58:00 -0700357 }
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700358 evtmap.forEach((k, v) -> {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700359 DeviceId curDevice = getDeviceId(k);
360 if (!isMaster(curDevice)) {
361 log.info("NetConfListener: not master, ignoring config for device {}", k);
362 return;
363 }
364 initiateConnection(curDevice);
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700365 for (DynamicConfigEvent curEvt : v) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700366 switch (curEvt.type()) {
367 case NODE_ADDED:
368 case NODE_UPDATED:
369 case NODE_REPLACED:
Yuta HIGUCHIac85ee12017-08-03 20:07:35 -0700370 Filter filt = Filter.builder().build();
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700371 DataNode node = cfgService.readNode(k, filt);
372 configUpdate(node, curDevice, k);
373 break;
374 case NODE_DELETED:
Sithara Punnasserydcc83b12017-03-28 18:19:14 -0700375 configDelete(null, curDevice, k); //TODO curEvt.subject())??
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700376 break;
377 case UNKNOWN_OPRN:
378 default:
379 log.warn("NetConfListener: unknown event: {}", curEvt.type());
380 break;
381 }
382 }
383 });
384 //TODO remove this hack after store ordering is fixed
385 if (handleEx) {
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700386 DeviceId exDevice = getDeviceId(exId);
387 if (!isMaster(exDevice)) {
388 log.info("NetConfListener: not master, ignoring config for expath {}", exId);
389 return;
390 }
391 initiateConnection(exDevice);
Yuta HIGUCHIac85ee12017-08-03 20:07:35 -0700392 Filter filt = Filter.builder().build();
Sithara Punnassery0b51d432017-03-28 01:09:28 -0700393 DataNode exnode = cfgService.readNode(exId, filt);
394 configUpdate(exnode, exDevice, exId);
395 } //end of hack
Sithara Punnassery425837f2017-03-21 12:58:00 -0700396 }
Aaron Kruglikov309068e2017-03-17 15:25:54 -0700397 }
398}