/* * Copyright (c) 2014, 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.sfc.sfc_test_consumer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; import org.opendaylight.controller.config.yang.config.sfc_test_consumer.impl.SfcTestConsumerRuntimeMXBean; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SftTypeName; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.DeleteServiceFunctionInputBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.PutServiceFunctionInputBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ReadServiceFunctionInputBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ReadServiceFunctionOutput; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionService; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocator; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocatorBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.PutServiceFunctionChainsInputBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChainService; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.IpBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Manually coded consumer implementation * according to example at https://wiki.opendaylight.org/view/OpenDaylight_Controller: * MD-SAL:Toaster_Step-By-Step#Define_the_KitchenService_implementation * How to Exercise these RPCs: * In order to to exercise these RPCs controller has to be started as: ./run –jmx * Then start jconsole from /bin inside your $JAVA_HOME. It will show a list of * running JVM processes, select "org.eclipse.equinox.launcher.Main –console –consoleLog" * (this is how it looks on Windows, maybe on Mac you will see some difference), or * type in "remote connections" localhost:1088 * Allow insecure connection if it asks. There will be the rightmost tab called * MBeans, with a folded tree of different components. * Go to org.opendaylight.controller -> Runtime bean -> test-consumer-impl (some times it * takes a little time until all those beans are initialized, they appear one by one), * then once again test-consumer-impl (on next level) -> Operations, and there they * are, all RPC from consumer YANG, mapped to their Java implementations. When you * select one, on the right panel there is a button to invoke that function. * * <p> * * @author Konstantin Blagov (blagov.sk@hotmail.com) * @author Reinaldo Penno (rapenno@gmail.com) * @version 0.1 * @since 2014-07-01 */ public class SfcTestConsumerImpl implements SfcTestConsumer, SfcTestConsumerRuntimeMXBean { private static final Logger LOG = LoggerFactory.getLogger(SfcTestConsumerImpl.class); private final ServiceFunctionService sfService; private final ServiceFunctionChainService sfcService; public SfcTestConsumerImpl(ServiceFunctionService sfService, ServiceFunctionChainService sfcService) { this.sfService = sfService; this.sfcService = sfcService; } /** * Local method used by JMX RPCs. This is the method that actually * sends RPC request to SFC Provider to create Service Functions * * @return Boolean */ @SuppressWarnings("checkstyle:IllegalCatch") private Boolean putSf(SfName name, SftTypeName type, String ipMgmt, String ipLocator, int portLocator) { // printTraceStart(LOG); // Build Locator Type (ip and port) IpAddress ipAddress = new IpAddress(ipLocator.toCharArray()); PortNumber portNumber = new PortNumber(portLocator); IpBuilder ipBuilder = new IpBuilder(); ipBuilder = ipBuilder.setIp(ipAddress).setPort(portNumber); // Build Data Plane Locator and populate with Locator Type SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder = new SfDataPlaneLocatorBuilder(); sfDataPlaneLocatorBuilder = sfDataPlaneLocatorBuilder.setLocatorType(ipBuilder.build()); List<SfDataPlaneLocator> sfDataPlaneLocatorList = new ArrayList<SfDataPlaneLocator>(); sfDataPlaneLocatorList.add(sfDataPlaneLocatorBuilder.build()); // Build ServiceFunctionBuilder and set all data constructed above PutServiceFunctionInputBuilder putServiceFunctionInputBuilder = new PutServiceFunctionInputBuilder(); putServiceFunctionInputBuilder = putServiceFunctionInputBuilder.setName(name) .setType(type) .setIpMgmtAddress(new IpAddress(ipMgmt.toCharArray())) .setSfDataPlaneLocator(sfDataPlaneLocatorList); try { Future<RpcResult<Void>> fr = sfService.putServiceFunction(putServiceFunctionInputBuilder.build()); RpcResult<Void> result = fr.get(); if (result != null) { LOG.info("\n####### {} result: {}", Thread.currentThread().getStackTrace()[1], result); if (result.isSuccessful()) { LOG.info("\n####### {}: successfully finished", Thread.currentThread().getStackTrace()[1]); } else { LOG.warn("\n####### {}: not successfully finished", Thread.currentThread().getStackTrace()[1]); } return result.isSuccessful(); } else { LOG.warn("\n####### {} result is NULL", Thread.currentThread().getStackTrace()[1]); return Boolean.FALSE; } } catch (Exception e) { LOG.warn("\n####### {} Error occurred: {}", Thread.currentThread().getStackTrace()[1], e); return Boolean.FALSE; } } /** * Puts an SFChain. * * @param name Name for new service function chain * @param sfList List of references to service functions (by names) * @return Boolean */ @SuppressWarnings("checkstyle:IllegalCatch") private Boolean putChain(SfcName name, List<SfcServiceFunction> sfList) { // printTraceStart(LOG); PutServiceFunctionChainsInputBuilder input = new PutServiceFunctionChainsInputBuilder(); ServiceFunctionChainBuilder sfcBuilder = new ServiceFunctionChainBuilder(); sfcBuilder.setName(name).setSfcServiceFunction(sfList); List<ServiceFunctionChain> list = new ArrayList<>(); list.add(sfcBuilder.build()); input.setServiceFunctionChain(list); try { Future<RpcResult<Void>> fr = sfcService.putServiceFunctionChains(input.build()); RpcResult<Void> result = fr.get(); if (result != null) { LOG.info("\n####### {} result: {}", Thread.currentThread().getStackTrace()[1], result); if (result.isSuccessful()) { LOG.info("\n####### {}: successfully finished", Thread.currentThread().getStackTrace()[1]); } else { LOG.warn("\n####### {}: not successfully finished", Thread.currentThread().getStackTrace()[1]); } return result.isSuccessful(); } else { LOG.error("\n####### {} result is NULL", Thread.currentThread().getStackTrace()[1]); return Boolean.FALSE; } } catch (Exception e) { LOG.warn("\n####### {} Error occurred: {}", Thread.currentThread().getStackTrace()[1], e); return Boolean.FALSE; } } /** * Function for JMX testing. * Creates a new sfService function with fixed parameters. * * @return Boolean */ @Override public Boolean testAPutSf() { // printTraceStart(LOG); return putSf(new SfName("firewall-test"), new SftTypeName("firewall"), "10.0.0.2", "192.168.0.2", 5050); } /** * Function for JMX testing. * Reads a sfService function by fixed name. * * @return Boolean */ @Override @SuppressWarnings("checkstyle:IllegalCatch") public Boolean testAReadSf() { // printTraceStart(LOG); ReadServiceFunctionInputBuilder input = new ReadServiceFunctionInputBuilder(); input.setName("firewall-test"); try { RpcResult<ReadServiceFunctionOutput> result = sfService.readServiceFunction(input.build()).get(); if (result.isSuccessful()) { LOG.info("testReadSf: successfully finished, result: ", result.getResult()); } else { LOG.warn("testReadSf: not successfully finished"); } return result.isSuccessful(); } catch (Exception e) { LOG.warn("Error occurred during testReadSf: " + e); } return false; } /** * Function for JMX testing. * Deletes a sfService function by fixed name. * * @return Boolean */ @Override @SuppressWarnings("checkstyle:IllegalCatch") public Boolean testADeleteSf() { // printTraceStart(LOG); DeleteServiceFunctionInputBuilder input = new DeleteServiceFunctionInputBuilder(); input.setName("firewall-test"); try { Future<RpcResult<Void>> fr = sfService.deleteServiceFunction(input.build()); RpcResult<Void> result = fr.get(); if (result != null) { if (result.isSuccessful()) { LOG.info("testDeleteSf: successfully finished"); } else { LOG.warn("testDeleteSf: not successfully finished"); } return result.isSuccessful(); } else { LOG.warn("*****\ntestDeleteSf result is NULL"); } } catch (Exception e) { LOG.warn("Error occurred during testDeleteSf: " + e.getMessage()); } return Boolean.FALSE; } /** * Function for JMX testing. * Creates multiple Service Functions with fixed parameters. * * @return Boolean */ @Override public Boolean testBPutSfs() { // printTraceStart(LOG); Boolean res = putSf(new SfName("firewall-testB"), new SftTypeName("firewall"), "10.0.0.101", "192.168.0.101", 5050); res = putSf(new SfName("dpi-testB"), new SftTypeName("dpi"), "10.0.0.102", "192.168.0.102", 5050) && res; res = putSf(new SfName("napt44-testB"), new SftTypeName("napt44"), "10.0.0.103", "192.168.0.102", 5050) && res; return res; } /** * Function for JMX testing. * Creates a Service Chain with fixed parameters. * * @return Boolean */ @Override @SuppressWarnings("checkstyle:IllegalCatch") public Boolean testBPutSfc() { // printTraceStart(LOG); List<SfcServiceFunction> sfcServiceFunctionArrayList = new ArrayList<>(); SfcServiceFunctionBuilder sfcServiceFunctionBuilder = new SfcServiceFunctionBuilder(); sfcServiceFunctionArrayList .add(sfcServiceFunctionBuilder.setName("napt44-testB").setType(new SftTypeName("napt44")).build()); sfcServiceFunctionArrayList .add(sfcServiceFunctionBuilder.setName("firewall-testB").setType(new SftTypeName("firewall")).build()); sfcServiceFunctionArrayList .add(sfcServiceFunctionBuilder.setName("dpi-testB").setType(new SftTypeName("dpi")).build()); // Now we add list function type list to Service Chain list. ServiceFunctionChainBuilder sfcbuilder = new ServiceFunctionChainBuilder(); List<ServiceFunctionChain> sfclist = new ArrayList<>(); sfclist .add(sfcbuilder.setName(new SfcName("Chain-1")).setSfcServiceFunction(sfcServiceFunctionArrayList).build()); // Put a service chain. We need to build a list of lists. PutServiceFunctionChainsInputBuilder putServiceFunctionChainsInputBuilder = new PutServiceFunctionChainsInputBuilder(); putServiceFunctionChainsInputBuilder = putServiceFunctionChainsInputBuilder.setServiceFunctionChain(sfclist); try { Future<RpcResult<Void>> fr = sfcService.putServiceFunctionChains(putServiceFunctionChainsInputBuilder.build()); RpcResult<Void> result = fr.get(); if (result != null) { LOG.info("\n####### {} result: {}", Thread.currentThread().getStackTrace()[1], result); if (result.isSuccessful()) { LOG.info("\n####### {}: successfully finished", Thread.currentThread().getStackTrace()[1]); } else { LOG.warn("\n####### {}: not successfully finished", Thread.currentThread().getStackTrace()[1]); } return result.isSuccessful(); } else { LOG.warn("\n####### {} result is NULL", Thread.currentThread().getStackTrace()[1]); return Boolean.FALSE; } } catch (Exception e) { LOG.warn("\n####### {} Error occurred: {}", Thread.currentThread().getStackTrace()[1], e.getMessage()); return Boolean.FALSE; } } @Override public Boolean testBReadSfc() { // printTraceStart(LOG); return null; } @Override public Boolean testBDeleteSfc() { // printTraceStart(LOG); return null; } @Override public Boolean testCPutData() { // printTraceStart(LOG); // Service Functions (real, not abstract) Boolean res = putSf(new SfName("firewall-101-1"), new SftTypeName("firewall"), "10.3.1.101", "10.3.1.101", 10001); res = putSf(new SfName("firewall-101-2"), new SftTypeName("firewall"), "10.3.1.101", "10.3.1.101", 10002) && res; res = putSf(new SfName("dpi-102-1"), new SftTypeName("dpi"), "10.3.1.102", "10.3.1.102", 10001) && res; res = putSf(new SfName("dpi-102-2"), new SftTypeName("dpi"), "10.3.1.102", "10.3.1.102", 10002) && res; res = putSf(new SfName("dpi-102-3"), new SftTypeName("dpi"), "10.3.1.102", "10.3.1.102", 10003) && res; res = putSf(new SfName("napt44-103-1"), new SftTypeName("napt44"), "10.3.1.103", "10.3.1.103", 10001) && res; res = putSf(new SfName("napt44-103-2"), new SftTypeName("napt44"), "10.3.1.103", "10.3.1.103", 10002) && res; res = putSf(new SfName("firewall-104"), new SftTypeName("firewall"), "10.3.1.104", "10.3.1.104", 10001) && res; res = putSf(new SfName("napt44-104"), new SftTypeName("napt44"), "10.3.1.104", "10.3.1.104", 10020) && res; // SFC1 List<SfcServiceFunction> sfRefList = new ArrayList<>(); SfcServiceFunctionBuilder sfBuilder = new SfcServiceFunctionBuilder(); sfRefList.add(sfBuilder.setName("firewall-abstract1").setType(new SftTypeName("firewall")).build()); sfRefList.add(sfBuilder.setName("dpi-abstract1").setType(new SftTypeName("dpi")).build()); sfRefList.add(sfBuilder.setName("napt44-abstract1").setType(new SftTypeName("napt44")).build()); res = putChain(new SfcName("SFC1"), sfRefList) && res; // SFC2 sfRefList.clear(); sfBuilder = new SfcServiceFunctionBuilder(); sfRefList.add(sfBuilder.setName("firewall-abstract2").setType(new SftTypeName("firewall")).build()); sfRefList.add(sfBuilder.setName("napt44-abstract2").setType(new SftTypeName("napt44")).build()); res = putChain(new SfcName("SFC2"), sfRefList) && res; // Nodes List<String> nodeList = new ArrayList<>(); nodeList.add("firewall-101-1"); nodeList.add("firewall-101-2"); return res; } }