Committed by
Gerrit Code Review
[ONOS-4654] NETCONF function for FUJITSU OLT #1
Change-Id: I3565d127252de732d249ed5dd919874d6438c2fa
Showing
4 changed files
with
197 additions
and
2 deletions
drivers/fujitsu/src/main/java/org/onosproject/drivers/fujitsu/FujitsuVoltControllerConfig.java
0 → 100644
| 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 | } | ... | ... |
-
Please register or login to post a comment