Akihiro Yamanouchi
Committed by Gerrit Code Review

[ONOS-4654] NETCONF function for FUJITSU OLT #1

Change-Id: I3565d127252de732d249ed5dd919874d6438c2fa
1 +/*
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 +
17 +package org.onosproject.drivers.fujitsu;
18 +
19 +import com.google.common.collect.ImmutableList;
20 +import org.apache.commons.configuration.HierarchicalConfiguration;
21 +import org.onosproject.drivers.utilities.XmlConfigParser;
22 +import org.onlab.packet.IpAddress;
23 +import org.onosproject.mastership.MastershipService;
24 +import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.behaviour.ControllerConfig;
26 +import org.onosproject.net.behaviour.ControllerInfo;
27 +import org.onosproject.net.driver.AbstractHandlerBehaviour;
28 +import org.onosproject.net.driver.DriverHandler;
29 +import org.onosproject.netconf.NetconfController;
30 +import org.slf4j.Logger;
31 +
32 +import java.io.ByteArrayInputStream;
33 +import java.io.IOException;
34 +import java.nio.charset.StandardCharsets;
35 +import java.util.ArrayList;
36 +import java.util.List;
37 +
38 +import static com.google.common.base.Preconditions.checkNotNull;
39 +import static org.slf4j.LoggerFactory.getLogger;
40 +
41 +/**
42 + * Implementation to get and set parameters available in VOLT NE
43 + * through the Netconf protocol.
44 + */
45 +public class FujitsuVoltControllerConfig extends AbstractHandlerBehaviour
46 + implements ControllerConfig {
47 +
48 + private final Logger log = getLogger(FujitsuVoltControllerConfig.class);
49 +
50 + private static final String DOT = ".";
51 + private static final String VOLT_NE_NAMESPACE =
52 + "xmlns=\"http://fujitsu.com/ns/volt/1.1\"";
53 + private static final String DATA = "data";
54 + private static final String VOLT_NE = "volt-ne";
55 + private static final String VOLT_OFCONFIG = "volt-ofconfig";
56 + private static final String OF_CONTROLLERS = "of-controllers";
57 + private static final String OF_CONTROLLER = "of-controller";
58 + private static final String CONTROLLER_INFO = "controller-info";
59 + private static final String REPORT_ALL = "report-all";
60 + private static final String IP_ADDRESS = "ip-address";
61 + private static final String PORT = "port";
62 + private static final String PROTOCOL = "protocol";
63 +
64 + private static final String VOLT_NE_OPEN = "<" + VOLT_NE + " ";
65 + private static final String VOLT_NE_CLOSE = "</" + VOLT_NE + ">";
66 + private static final String VOLT_OFCONFIG_EL = "<" + VOLT_OFCONFIG + "/>\n";
67 +
68 + private static final String VOLT_DATACONFIG = DATA + DOT + VOLT_NE + DOT +
69 + VOLT_OFCONFIG + DOT + OF_CONTROLLERS + DOT + OF_CONTROLLER;
70 +
71 + @Override
72 + public List<ControllerInfo> getControllers() {
73 + DriverHandler handler = handler();
74 + NetconfController controller = handler.get(NetconfController.class);
75 + MastershipService mastershipService = handler.get(MastershipService.class);
76 + DeviceId ncDeviceId = handler.data().deviceId();
77 + checkNotNull(controller, "Netconf controller is null");
78 + List<ControllerInfo> controllers = new ArrayList<>();
79 + if (mastershipService.isLocalMaster(ncDeviceId)) {
80 + try {
81 + StringBuilder request = new StringBuilder();
82 + request.append(VOLT_NE_OPEN).append(VOLT_NE_NAMESPACE).append(">\n");
83 + request.append(VOLT_OFCONFIG_EL);
84 + request.append(VOLT_NE_CLOSE);
85 +
86 + String reply;
87 + reply = controller.
88 + getDevicesMap().get(ncDeviceId).getSession().
89 + get(request.toString(), REPORT_ALL);
90 + log.debug("Reply XML {}", reply);
91 + controllers.addAll(parseStreamVoltControllers(XmlConfigParser.
92 + loadXml(new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8)))));
93 + } catch (IOException e) {
94 + log.error("Cannot communicate to device {} ", ncDeviceId);
95 + }
96 + } else {
97 + log.warn("I'm not master for {} please use master, {} to execute command",
98 + ncDeviceId,
99 + mastershipService.getMasterFor(ncDeviceId));
100 + }
101 + return ImmutableList.copyOf(controllers);
102 + }
103 +
104 + @Override
105 + public void setControllers(List<ControllerInfo> controllers) {
106 + // TODO update later
107 + log.warn("Operation not supported");
108 + }
109 +
110 + /**
111 + * Parses XML string to get controller information.
112 + *
113 + * @param cfg a hierarchical configuration
114 + * @return a list of controllers
115 + */
116 + private List<ControllerInfo> parseStreamVoltControllers(HierarchicalConfiguration cfg) {
117 + List<ControllerInfo> controllers = new ArrayList<>();
118 + List<HierarchicalConfiguration> fields =
119 + cfg.configurationsAt(VOLT_DATACONFIG);
120 +
121 + for (HierarchicalConfiguration sub : fields) {
122 + List<HierarchicalConfiguration> childFields =
123 + sub.configurationsAt(CONTROLLER_INFO);
124 +
125 + for (HierarchicalConfiguration child : childFields) {
126 + ControllerInfo controller = new ControllerInfo(
127 + IpAddress.valueOf(child.getString(IP_ADDRESS)),
128 + Integer.parseInt(child.getString(PORT)),
129 + child.getString(PROTOCOL));
130 +
131 + log.debug("VOLT: OFCONTROLLER: PROTOCOL={}, IP={}, PORT={} ",
132 + controller.type(), controller.ip(), controller.port());
133 + controllers.add(controller);
134 + }
135 + }
136 + return controllers;
137 + }
138 +
139 +}
...@@ -21,5 +21,8 @@ ...@@ -21,5 +21,8 @@
21 <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery" 21 <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
22 impl="org.onosproject.drivers.fujitsu.FujitsuT100DeviceDescription"/> 22 impl="org.onosproject.drivers.fujitsu.FujitsuT100DeviceDescription"/>
23 </driver> 23 </driver>
24 + <driver name="fujitsu-volt-netconf" manufacturer="Fujitsu" hwVersion="svkOLT" swVersion="v1.0">
25 + <behaviour api="org.onosproject.net.behaviour.ControllerConfig"
26 + impl="org.onosproject.drivers.fujitsu.FujitsuVoltControllerConfig"/>
27 + </driver>
24 </drivers> 28 </drivers>
...\ No newline at end of file ...\ No newline at end of file
25 -
......
...@@ -48,6 +48,18 @@ public interface NetconfSession { ...@@ -48,6 +48,18 @@ public interface NetconfSession {
48 String get(String request) throws NetconfException; 48 String get(String request) throws NetconfException;
49 49
50 /** 50 /**
51 + * Retrives the requested data.
52 + *
53 + * @param filterSchema XML subtrees to include in the reply
54 + * @param withDefaultsMode with-defaults mode
55 + * @return Server response
56 + * @throws NetconfException when there is a problem in the communication process on
57 + * the underlying connection
58 + */
59 + String get(String filterSchema, String withDefaultsMode)
60 + throws NetconfException;
61 +
62 + /**
51 * Executes an synchronous RPC to the server. 63 * Executes an synchronous RPC to the server.
52 * 64 *
53 * @param request the XML containing the RPC for the server. 65 * @param request the XML containing the RPC for the server.
......
...@@ -58,8 +58,20 @@ public class NetconfSessionImpl implements NetconfSession { ...@@ -58,8 +58,20 @@ public class NetconfSessionImpl implements NetconfSession {
58 private static final String END_OF_RPC_OPEN_TAG = "\">"; 58 private static final String END_OF_RPC_OPEN_TAG = "\">";
59 private static final String EQUAL = "="; 59 private static final String EQUAL = "=";
60 private static final String NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\""; 60 private static final String NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\"";
61 + private static final String RPC_OPEN = "<rpc ";
62 + private static final String RPC_CLOSE = "</rpc>";
63 + private static final String GET_OPEN = "<get>";
64 + private static final String GET_CLOSE = "</get>";
65 + private static final String WITH_DEFAULT_OPEN = "<with-defaults ";
66 + private static final String WITH_DEFAULT_CLOSE = "</with-defaults>";
67 + private static final String FILTER_OPEN = "<filter type=\"subtree\">";
68 + private static final String FILTER_CLOSE = "</filter>";
61 private static final String XML_HEADER = 69 private static final String XML_HEADER =
62 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 70 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
71 + private static final String NETCONF_BASE_NAMESPACE =
72 + "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"";
73 + private static final String NETCONF_WITH_DEFAULTS_NAMESPACE =
74 + "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\"";
63 75
64 private final AtomicInteger messageIdInteger = new AtomicInteger(0); 76 private final AtomicInteger messageIdInteger = new AtomicInteger(0);
65 private Connection netconfConnection; 77 private Connection netconfConnection;
...@@ -76,13 +88,14 @@ public class NetconfSessionImpl implements NetconfSession { ...@@ -76,13 +88,14 @@ public class NetconfSessionImpl implements NetconfSession {
76 88
77 public NetconfSessionImpl(NetconfDeviceInfo deviceInfo) throws NetconfException { 89 public NetconfSessionImpl(NetconfDeviceInfo deviceInfo) throws NetconfException {
78 this.deviceInfo = deviceInfo; 90 this.deviceInfo = deviceInfo;
91 + this.netconfConnection = null;
92 + this.sshSession = null;
79 connectionActive = false; 93 connectionActive = false;
80 replies = new HashMap<>(); 94 replies = new HashMap<>();
81 errorReplies = new ArrayList<>(); 95 errorReplies = new ArrayList<>();
82 startConnection(); 96 startConnection();
83 } 97 }
84 98
85 -
86 private void startConnection() throws NetconfException { 99 private void startConnection() throws NetconfException {
87 if (!connectionActive) { 100 if (!connectionActive) {
88 netconfConnection = new Connection(deviceInfo.ip().toString(), deviceInfo.port()); 101 netconfConnection = new Connection(deviceInfo.ip().toString(), deviceInfo.port());
...@@ -233,6 +246,34 @@ public class NetconfSessionImpl implements NetconfSession { ...@@ -233,6 +246,34 @@ public class NetconfSessionImpl implements NetconfSession {
233 } 246 }
234 247
235 @Override 248 @Override
249 + public String get(String filterSchema, String withDefaultsMode) throws NetconfException {
250 + StringBuilder rpc = new StringBuilder(XML_HEADER);
251 + rpc.append(RPC_OPEN);
252 + rpc.append(MESSAGE_ID_STRING);
253 + rpc.append(EQUAL);
254 + rpc.append("\"");
255 + rpc.append(messageIdInteger.get());
256 + rpc.append("\" ");
257 + rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
258 + rpc.append(GET_OPEN).append(NEW_LINE);
259 + if (filterSchema != null) {
260 + rpc.append(FILTER_OPEN).append(NEW_LINE);
261 + rpc.append(filterSchema).append(NEW_LINE);
262 + rpc.append(FILTER_CLOSE).append(NEW_LINE);
263 + }
264 + if (withDefaultsMode != null) {
265 + rpc.append(WITH_DEFAULT_OPEN).append(NETCONF_WITH_DEFAULTS_NAMESPACE).append(">");
266 + rpc.append(withDefaultsMode).append(WITH_DEFAULT_CLOSE).append(NEW_LINE);
267 + }
268 + rpc.append(GET_CLOSE).append(NEW_LINE);
269 + rpc.append(RPC_CLOSE).append(NEW_LINE);
270 + rpc.append(ENDPATTERN);
271 + String reply = sendRequest(rpc.toString());
272 + checkReply(reply);
273 + return reply;
274 + }
275 +
276 + @Override
236 public String getConfig(String targetConfiguration) throws NetconfException { 277 public String getConfig(String targetConfiguration) throws NetconfException {
237 return getConfig(targetConfiguration, null); 278 return getConfig(targetConfiguration, null);
238 } 279 }
......