Akihiro Yamanouchi
Committed by Gerrit Code Review

[ONOS-4795] NETCONF function for FUJITSU OLT #3

[Done]
- Add vOLT ponlink commands for FUJITSU OLT
- Add new implementation with respect to the commands
- Move those commands to Fujitsu drivers directory
- Modify BUCK to avoid an error

Change-Id: I7a61234e18367aa74445800dd09f98c10edc35c4
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.behaviour;
import org.onosproject.net.driver.HandlerBehaviour;
/**
* Device behaviour to obtain and set parameters of PON links in vOLT.
*/
public interface VoltPonLinkConfig extends HandlerBehaviour {
/**
* Obtain all GPON PON links or a specific PON link in the device.
*
* @param target input data in string
* @return response string
*/
String getPonLinks(String target);
/**
* Set a parameter value of PON link in the device.
*
* @param target input data in string
*
*/
void setPonLink(String target);
}
......@@ -2,6 +2,8 @@ COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//drivers/utilities:onos-drivers-utilities',
'//protocols/netconf/api:onos-protocols-netconf-api',
'//lib:org.apache.karaf.shell.console',
'//cli:onos-cli',
]
TEST_DEPS = [
......
......@@ -52,6 +52,16 @@
<artifactId>onos-drivers-utilities</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.fujitsu;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.VoltPonLinkConfig;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.netconf.NetconfController;
import org.slf4j.Logger;
import java.io.IOException;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.drivers.fujitsu.FujitsuVoltXmlUtility.*;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation to get and set parameters available in vOLT
* through the Netconf protocol.
*/
public class FujitsuVoltPonLinkConfig extends AbstractHandlerBehaviour
implements VoltPonLinkConfig {
private final Logger log = getLogger(FujitsuVoltPonLinkConfig.class);
private final Set<String> ponLinkParams = ImmutableSet.of(
"admin-state", "onu-discovery-mode", "onu-discovery-interval",
"dba-cycle-time", "mac-age-time", "lof-threshold",
"los-threshold", "pm-enable");
private static final String VOLT_PORTS = "volt-ports";
private static final String GPON_PONLINK_PORTS = "gpon-ponlink-ports";
private static final String GPON_PONLINK_PORT = "gpon-ponlink-port";
private int pon;
@Override
public String getPonLinks(String target) {
DriverHandler handler = handler();
NetconfController controller = handler.get(NetconfController.class);
MastershipService mastershipService = handler.get(MastershipService.class);
DeviceId ncDeviceId = handler.data().deviceId();
checkNotNull(controller, "Netconf controller is null");
String reply = null;
if (!mastershipService.isLocalMaster(ncDeviceId)) {
log.warn("Not master for {} Use {} to execute command",
ncDeviceId,
mastershipService.getMasterFor(ncDeviceId));
return reply;
}
try {
StringBuilder request = new StringBuilder();
request.append(VOLT_NE_OPEN).append(VOLT_NE_NAMESPACE);
request.append(ANGLE_RIGHT).append(NEW_LINE);
request.append(buildStartTag(VOLT_PORTS));
if (target != null) {
try {
pon = Integer.parseInt(target);
} catch (NumberFormatException e) {
log.error("Non-number input");
return reply;
}
request.append(buildStartTag(GPON_PONLINK_PORTS));
request.append(buildStartTag(GPON_PONLINK_PORT));
request.append(buildStartTag(PONLINK_ID, false));
request.append(target);
request.append(buildEndTag(PONLINK_ID));
request.append(buildEndTag(GPON_PONLINK_PORT));
request.append(buildEndTag(GPON_PONLINK_PORTS));
} else {
request.append(buildEmptyTag(GPON_PONLINK_PORTS));
}
request.append(buildEndTag(VOLT_PORTS));
request.append(VOLT_NE_CLOSE);
reply = controller.
getDevicesMap().get(ncDeviceId).getSession().
get(request.toString(), REPORT_ALL);
} catch (IOException e) {
log.error("Cannot communicate to device {} exception ", ncDeviceId, e);
}
return reply;
}
@Override
public void setPonLink(String target) {
DriverHandler handler = handler();
NetconfController controller = handler.get(NetconfController.class);
MastershipService mastershipService = handler.get(MastershipService.class);
DeviceId ncDeviceId = handler.data().deviceId();
checkNotNull(controller, "Netconf controller is null");
if (!mastershipService.isLocalMaster(ncDeviceId)) {
log.warn("Not master for {} Use {} to execute command",
ncDeviceId,
mastershipService.getMasterFor(ncDeviceId));
return;
}
String[] data = target.split(COLON);
if (data.length != 3) {
log.error("Invalid number of arguments");
return;
}
try {
pon = Integer.parseInt(data[0]);
} catch (NumberFormatException e) {
log.error("Non-number input");
return;
}
if (!ponLinkParams.contains(data[1])) {
log.error("Unsupported parameter: {} ", data[1]);
return;
}
try {
StringBuilder request = new StringBuilder();
request.append(VOLT_NE_OPEN).append(VOLT_NE_NAMESPACE);
request.append(ANGLE_RIGHT).append(NEW_LINE);
request.append(buildStartTag(VOLT_PORTS));
request.append(buildStartTag(GPON_PONLINK_PORTS));
request.append(buildStartTag(GPON_PONLINK_PORT));
request.append(buildStartTag(PONLINK_ID, false));
request.append(data[0]);
request.append(buildEndTag(PONLINK_ID));
request.append(buildStartTag(data[1], false));
request.append(data[2]);
request.append(buildEndTag(data[1]));
request.append(buildEndTag(GPON_PONLINK_PORT));
request.append(buildEndTag(GPON_PONLINK_PORTS));
request.append(buildEndTag(VOLT_PORTS));
request.append(VOLT_NE_CLOSE);
controller.getDevicesMap().get(ncDeviceId).getSession().
editConfig(RUNNING, null, request.toString());
} catch (IOException e) {
log.error("Cannot communicate to device {} exception ", ncDeviceId, e);
}
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.fujitsu;
/**
* Defines common XML constants and methods for Fujitsu vOLT.
*/
public final class FujitsuVoltXmlUtility {
public static final String COLON = ":";
public static final String HYPHEN = "-";
public static final String SLASH = "/";
public static final String SPACE = " ";
public static final String NEW_LINE = "\n";
public static final String ANGLE_LEFT = "<";
public static final String ANGLE_RIGHT = ">";
public static final String REPORT_ALL = "report-all";
public static final String EDIT_CONFIG = "edit-config";
public static final String RUNNING = "running";
public static final String VOLT_NE_NAMESPACE =
"xmlns=\"http://fujitsu.com/ns/volt/1.1\"";
public static final String VOLT_NE = "volt-ne";
public static final String PONLINK_ID = "ponlink-id";
public static final String ONU_ID = "onu-id";
public static final String VOLT_NE_OPEN = ANGLE_LEFT + VOLT_NE + SPACE;
public static final String VOLT_NE_CLOSE = ANGLE_LEFT + SLASH + VOLT_NE + ANGLE_RIGHT;
private FujitsuVoltXmlUtility() {
// Preventing any allocation
}
/**
* Builds XML start tag with name provided.
*
* @param name tag name
* @return string
*/
public static String buildStartTag(String name) {
return buildStartTag(name, true);
}
/**
* Builds XML end tag with name provided.
*
* @param name tag name
* @return string
*/
public static String buildEndTag(String name) {
return buildEndTag(name, true);
}
/**
* Builds XML empty tag with name provided.
*
* @param name tag name
* @return string
*/
public static String buildEmptyTag(String name) {
return buildEmptyTag(name, true);
}
/**
* Builds XML start tag with name provided.
*
* @param name tag name
* @param addNewLine option to add new line character after tag
* @return string
*/
public static String buildStartTag(String name, boolean addNewLine) {
if (addNewLine) {
return (ANGLE_LEFT + name + ANGLE_RIGHT + NEW_LINE);
} else {
return (ANGLE_LEFT + name + ANGLE_RIGHT);
}
}
/**
* Builds XML end tag with name provided.
*
* @param name tag name
* @param addNewLine option to add new line character after tag
* @return string
*/
public static String buildEndTag(String name, boolean addNewLine) {
if (addNewLine) {
return (ANGLE_LEFT + SLASH + name + ANGLE_RIGHT + NEW_LINE);
} else {
return (ANGLE_LEFT + SLASH + name + ANGLE_RIGHT);
}
}
/**
* Builds XML empty element tag with name provided.
*
* @param name tag name
* @param addNewLine option to add new line character after tag
* @return string
*/
public static String buildEmptyTag(String name, boolean addNewLine) {
if (addNewLine) {
return (ANGLE_LEFT + name + SLASH + ANGLE_RIGHT + NEW_LINE);
} else {
return (ANGLE_LEFT + name + SLASH + ANGLE_RIGHT);
}
}
}
/*
* Copyright 2016-present Open tworking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.fujitsu.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.VoltPonLinkConfig;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
/**
* Gets PON links in vOLT.
*/
@Command(scope = "onos", name = "volt-ponlinks",
description = "Gets PON links in vOLT")
public class VoltGetPonLinksCommand extends AbstractShellCommand {
@Argument(index = 0, name = "uri", description = "Device ID",
required = true, multiValued = false)
String uri = null;
@Argument(index = 1, name = "target", description = "PON link ID",
required = false, multiValued = false)
String target = null;
private DeviceId deviceId;
@Override
protected void execute() {
DriverService service = get(DriverService.class);
deviceId = DeviceId.deviceId(uri);
DriverHandler h = service.createHandler(deviceId);
VoltPonLinkConfig volt = h.behaviour(VoltPonLinkConfig.class);
String reply = volt.getPonLinks(target);
if (reply != null) {
print("%s", reply);
} else {
print("No replay from %s", deviceId.toString());
}
}
}
/*
* Copyright 2016-present Open tworking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.fujitsu.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.VoltPonLinkConfig;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
/**
* Sets a parameter of a PON link in vOLT.
*/
@Command(scope = "onos", name = "volt-setponlink",
description = "Sets a parameter of a PON link in vOLT")
public class VoltSetPonLinkCommand extends AbstractShellCommand {
@Argument(index = 0, name = "uri", description = "Device ID",
required = true, multiValued = false)
String uri = null;
@Argument(index = 1, name = "target", description = "PON link ID:parameter:value",
required = true, multiValued = false)
String target = null;
private DeviceId deviceId;
@Override
protected void execute() {
DriverService service = get(DriverService.class);
deviceId = DeviceId.deviceId(uri);
DriverHandler h = service.createHandler(deviceId);
VoltPonLinkConfig volt = h.behaviour(VoltPonLinkConfig.class);
volt.setPonLink(target);
}
}
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Administrative console command-line extensions for interacting with the
* network model - vOLT.
*/
package org.onosproject.drivers.fujitsu.cli;
<!--
~ Copyright 2016 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<!--volt commands -->
<command>
<action class="org.onosproject.drivers.fujitsu.cli.VoltGetPonLinksCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onosproject.drivers.fujitsu.cli.VoltSetPonLinkCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
</command-bundle>
<bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/>
</blueprint>
......@@ -24,5 +24,7 @@
<driver name="fujitsu-volt-netconf" manufacturer="Fujitsu" hwVersion="svkOLT" swVersion="v1.0">
<behaviour api="org.onosproject.net.behaviour.ControllerConfig"
impl="org.onosproject.drivers.fujitsu.FujitsuVoltControllerConfig"/>
<behaviour api="org.onosproject.net.behaviour.VoltPonLinkConfig"
impl="org.onosproject.drivers.fujitsu.FujitsuVoltPonLinkConfig"/>
</driver>
</drivers>
\ No newline at end of file
......
......@@ -64,8 +64,16 @@ public class NetconfSessionImpl implements NetconfSession {
private static final String GET_CLOSE = "</get>";
private static final String WITH_DEFAULT_OPEN = "<with-defaults ";
private static final String WITH_DEFAULT_CLOSE = "</with-defaults>";
private static final String DEFAULT_OPERATION_OPEN = "<default-operation>";
private static final String DEFAULT_OPERATION_CLOSE = "</default-operation>";
private static final String FILTER_OPEN = "<filter type=\"subtree\">";
private static final String FILTER_CLOSE = "</filter>";
private static final String EDIT_CONFIG_OPEN = "<edit-config>";
private static final String EDIT_CONFIG_CLOSE = "</edit-config>";
private static final String TARGET_OPEN = "<target>";
private static final String TARGET_CLOSE = "</target>";
private static final String CONFIG_OPEN = "<config>";
private static final String CONFIG_CLOSE = "</config>";
private static final String XML_HEADER =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
private static final String NETCONF_BASE_NAMESPACE =
......@@ -355,28 +363,31 @@ public class NetconfSessionImpl implements NetconfSession {
throws NetconfException {
newConfiguration = newConfiguration.trim();
StringBuilder rpc = new StringBuilder(XML_HEADER);
rpc.append("<rpc ");
rpc.append(RPC_OPEN);
rpc.append(MESSAGE_ID_STRING);
rpc.append(EQUAL);
rpc.append("\"");
rpc.append(messageIdInteger.get());
rpc.append("\" ");
rpc.append("xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
rpc.append("<edit-config>\n");
rpc.append("<target>");
rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
rpc.append(EDIT_CONFIG_OPEN).append("\n");
rpc.append(TARGET_OPEN);
rpc.append("<").append(targetConfiguration).append("/>");
rpc.append("</target>\n");
rpc.append("<default-operation>");
rpc.append(mode);
rpc.append("</default-operation>\n");
rpc.append("<config>\n");
rpc.append(TARGET_CLOSE).append("\n");
if (mode != null) {
rpc.append(DEFAULT_OPERATION_OPEN);
rpc.append(mode);
rpc.append(DEFAULT_OPERATION_CLOSE).append("\n");
}
rpc.append(CONFIG_OPEN).append("\n");
rpc.append(newConfiguration);
rpc.append("</config>\n");
rpc.append("</edit-config>\n");
rpc.append("</rpc>");
rpc.append(CONFIG_CLOSE).append("\n");
rpc.append(EDIT_CONFIG_CLOSE).append("\n");
rpc.append(RPC_CLOSE);
rpc.append(ENDPATTERN);
log.info(rpc.toString());
return checkReply(sendRequest(rpc.toString()));
String reply = sendRequest(rpc.toString());
return checkReply(reply);
}
@Override
......@@ -521,10 +532,12 @@ public class NetconfSessionImpl implements NetconfSession {
private boolean checkReply(String reply) throws NetconfException {
if (reply != null) {
if (!reply.contains("<rpc-error>")) {
log.debug("Device {} sent reply {}", deviceInfo, reply);
return true;
} else if (reply.contains("<ok/>")
|| (reply.contains("<rpc-error>")
&& reply.contains("warning"))) {
log.debug("Device {} sent reply {}", deviceInfo, reply);
return true;
}
}
......