blob: e3c94c27708582aebe2566a11663050bac7dfe3b [file] [log] [blame]
Aaron Kruglikov309068e2017-03-17 15:25:54 -07001/*
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.netconf.storeadapter;
18
19import com.google.common.annotations.Beta;
20import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.onosproject.config.DynamicConfigEvent;
27import org.onosproject.config.DynamicConfigListener;
28import org.onosproject.config.DynamicConfigService;
29import org.onosproject.config.Filter;
30import org.onosproject.mastership.MastershipService;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.resource.Resource;
33import org.onosproject.netconf.client.NetconfTranslator;
34import org.onosproject.netconf.client.NetconfTranslator.OperationType;
35import org.onosproject.yang.model.DataNode;
36import org.onosproject.yang.model.ResourceId;
37import org.onosproject.yang.runtime.DefaultResourceData;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.io.IOException;
42
43@Beta
44@Component(immediate = true)
45public class NetconfYangListener implements DynamicConfigListener {
46
47 private static final Logger log = LoggerFactory.getLogger(NetconfYangListener.class);
48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 protected DynamicConfigService cfgServcie;
50 public static final String DEVNMSPACE = "namespace1";
51
52 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected NetconfTranslator netconfTranslator;
54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected MastershipService mastershipService;
57
58 private ResourceId resId = new ResourceId.Builder()
59 .addBranchPointSchema("device", DEVNMSPACE )
60 .build();
61 @Activate
62 protected void activate() {
63 cfgServcie.addListener(this);
64 log.info("Started");
65 }
66
67 @Deactivate
68 protected void deactivate() {
69 cfgServcie.removeListener(this);
70 log.info("Stopped");
71 }
72
73 @Override
74 public boolean isRelevant(DynamicConfigEvent event) {
75 if (event.subject().equals(resId) &&
76 mastershipService.isLocalMaster(retrieveDeviceId(event.subject()))) {
77 return true;
78 } else {
79 return false;
80 }
81 }
82 @Override
83 public void event(DynamicConfigEvent event) {
84 Filter filt = new Filter();
85 DataNode node = cfgServcie.readNode(event.subject(), filt);
86 DeviceId deviceId = retrieveDeviceId(event.subject());
87 switch (event.type()) {
88 case NODE_ADDED:
89 case NODE_UPDATED:
90 case NODE_REPLACED:
91 configUpdate(node, deviceId, event.subject());
92 break;
93 case NODE_DELETED:
94 configDelete(node, deviceId, event.subject());
95 break;
96 case UNKNOWN_OPRN:
97 default:
98 log.warn("NetConfListener: unknown event: {}", event.type());
99 break;
100 }
101 }
102
103 /**
104 * Performs the delete operation corresponding to the passed event.
105 * @param node a relevant dataNode
106 * @param deviceId the deviceId of the device to be updated
107 * @param resourceId the resourceId of the root of the subtree to be edited
108 * @return true if the update succeeds false otherwise
109 */
110 private boolean configDelete(DataNode node, DeviceId deviceId, ResourceId resourceId) {
111 return parseAndEdit(node, deviceId, resourceId, OperationType.DELETE);
112 }
113
114 /**
115 * Performs the update operation corresponding to the passed event.
116 * @param node a relevant dataNode
117 * @param deviceId the deviceId of the device to be updated
118 * @param resourceId the resourceId of the root of the subtree to be edited
119 * @return true if the update succeeds false otherwise
120 */
121 private boolean configUpdate(DataNode node, DeviceId deviceId, ResourceId resourceId) {
122 return parseAndEdit(node, deviceId, resourceId, OperationType.REPLACE);
123 }
124
125 /**
126 * Parses the incoming event and pushes configuration to the effected
127 * device.
128 * @param node the dataNode effecting a particular device of which this node
129 * is master
130 * @param deviceId the deviceId of the device to be modified
131 * @param resourceId the resourceId of the root of the subtree to be edited
132 * @param operationType the type of editing to be performed
133 * @return true if the operation succeeds, false otherwise
134 */
135 private boolean parseAndEdit(DataNode node, DeviceId deviceId,
136 ResourceId resourceId,
137 NetconfTranslator.OperationType operationType) {
138 try {
139 return netconfTranslator.editDeviceConfig(
140 deviceId,
141 DefaultResourceData.builder()
142 .addDataNode(node)
143 .resourceId(resourceId)
144 .build(),
145 operationType);
146 } catch (IOException e) {
147 e.printStackTrace();
148 return false;
149 }
150 }
151
152 /**
153 * Takes a resourceId corresponding to the provided event and uses it to
154 * retrieve/generate a deviceId corresponding to the effected device.
155 * @param resourceId the resourceId associated with the event
156 * @return the deviceId of the effected device
157 */
158 private DeviceId retrieveDeviceId(ResourceId resourceId) {
159 /*TODO this requires a real implementation instead of a placeholder */
160 return DeviceId.NONE;
161 }
162}