blob: 500c0919b6d79870b2649444e9e58671439e8d3e [file] [log] [blame]
/*
* Copyright 2018-present Open Networking Foundation
*
* 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.juniper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.drivers.juniper.JuniperUtils.cliDeleteRequestBuilder;
import static org.onosproject.drivers.juniper.JuniperUtils.cliSetRequestBuilder;
import static org.onosproject.drivers.juniper.JuniperUtils.getOpenFlowControllersFromConfig;
import static org.slf4j.LoggerFactory.getLogger;
import com.google.common.collect.Lists;
import org.onosproject.drivers.utilities.XmlConfigParser;
import java.util.List;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerConfig;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;
import java.io.ByteArrayInputStream;
/**
* Set and get the openflow controller information via NETCONF for Juniper Switch. *
*/
public class ControllerConfigJuniperImpl extends AbstractHandlerBehaviour implements ControllerConfig {
private final Logger log = getLogger(getClass());
private static final String RPC_TAG_NETCONF_BASE = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
private static final String RPC_CLOSE_TAG = "</rpc>";
@Override
public List<ControllerInfo> getControllers() {
List<ControllerInfo> controllers = Lists.newArrayList();
String reply = retrieveResultCommand(buildRpcGetOpenFlowController());
if (reply == null || (reply != null && reply.isEmpty())) {
log.error("Cannot get the controllers from switch");
} else {
controllers = getOpenFlowControllersFromConfig(XmlConfigParser
.loadXml(new ByteArrayInputStream(reply.getBytes())));
log.debug("controllers {}", controllers);
}
return controllers;
}
@Override
public void setControllers(List<ControllerInfo> controllers) {
if (!requestCommand(buildRpcSetOpenFlowController(controllers))) {
log.error("Cannot set the controllers to switch");
}
}
@Override
public void removeControllers(List<ControllerInfo> controllers) {
if (!requestCommand(buildRpcRemoveOpenFlowController())) {
log.error("Cannot remove the controllers from switch");
}
}
private String buildRpcGetOpenFlowController() {
StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
rpc.append("<get-configuration>");
rpc.append("<configuration>");
rpc.append("<protocols>");
rpc.append("<openflow>");
rpc.append("<mode>");
rpc.append("<ofagent-mode>");
rpc.append("<controller>");
rpc.append("</controller>");
rpc.append("</ofagent-mode>");
rpc.append("</mode>");
rpc.append("</openflow>");
rpc.append("</protocols>");
rpc.append("</configuration>");
rpc.append("</get-configuration>");
rpc.append(RPC_CLOSE_TAG);
rpc.append("]]>]]>");
return rpc.toString();
}
private String buildRpcSetOpenFlowController(List<ControllerInfo> controllers) {
StringBuilder request = new StringBuilder();
request.append("<protocols>");
request.append("<openflow operation=\"delete\"/>");
request.append("</protocols>");
request.append("<protocols>");
request.append("<openflow>");
request.append("<mode>");
request.append("<ofagent-mode>");
request.append("<controller>");
for (int i = 0; i < controllers.size(); i++) {
request.append("<ip>");
request.append("<name>");
request.append(controllers.get(i).ip().toString());
request.append("</name>");
request.append("<protocol>");
request.append("<tcp>");
request.append("<port>");
request.append(Integer.toString(controllers.get(i).port()));
request.append("</port>");
request.append("</tcp>");
request.append("</protocol>");
request.append("</ip>");
}
request.append("</controller>");
request.append("</ofagent-mode>");
request.append("</mode>");
request.append("</openflow>");
request.append("</protocols>");
return cliSetRequestBuilder(request);
}
private String buildRpcRemoveOpenFlowController() {
StringBuilder request = new StringBuilder();
request.append("<protocols>");
request.append("<openflow>");
request.append("<mode>");
request.append("<ofagent-mode>");
request.append("<controller operation=\"delete\"/>");
request.append("</ofagent-mode>");
request.append("</mode>");
request.append("</openflow>");
request.append("</protocols>");
return cliDeleteRequestBuilder(request);
}
private String buildCommit() {
StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
rpc.append("<commit/>");
rpc.append(RPC_CLOSE_TAG);
rpc.append("]]>]]>");
return rpc.toString();
}
private String buildDiscardChanges() {
StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
rpc.append("<discard-changes/>");
rpc.append(RPC_CLOSE_TAG);
rpc.append("]]>]]>");
return rpc.toString();
}
private NetconfSession getSession() {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
DeviceId deviceId = handler().data().deviceId();
NetconfDevice device = controller.getDevicesMap().get(deviceId);
if (device == null) {
log.error("Cannot find the netconf device : {}", deviceId);
return null;
}
return device.getSession();
}
private String retrieveResultCommand(String command) {
NetconfSession session = getSession();
String reply;
if (session == null) {
log.error("Cannot get session : {}", command);
return null;
}
try {
reply = session.requestSync(command).trim();
log.debug(reply);
} catch (NetconfException e) {
log.debug(e.getMessage());
return null;
}
return reply;
}
private boolean requestCommand(String command) {
NetconfSession session = getSession();
if (session == null) {
log.error("Cannot get session : {}", command);
return false;
}
try {
String reply = session.requestSync(command).trim();
log.debug(reply);
if (!isOK(reply)) {
log.error("discard changes {}", reply);
session.requestSync(buildDiscardChanges());
return false;
}
reply = session.requestSync(buildCommit()).trim();
log.debug(reply);
} catch (NetconfException e) {
log.debug(e.getMessage());
return false;
}
return true;
}
private boolean isOK(String reply) {
if (reply != null && reply.indexOf("<ok/>") >= 0) {
return true;
}
return false;
}
}