From: Oleksii Mozghovyi Date: Wed, 27 Jan 2021 12:37:19 +0000 (+0200) Subject: Add tool to measure southbound notification performance X-Git-Tag: v1.13.0~8 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F15%2F94915%2F7;p=netconf.git Add tool to measure southbound notification performance This is an updated version of the tool existed in coretutorials project, aligned with the latest API changes - Tool is packaged into a new feature odl-netconf-test-tools - For the testing purposes models from the original coretutorials project are used - Tool listens for mounted devices with prefix "perf-" - Notification counter is only applied for devices that end with the following pattern '*-notif-([0-9]+)', and the number after notif suffix indicates how many notifications should be counted - Once the mounted device is ready tool invokes create subscription request towards device, and counts incoming notifications JIRA: NETCONF-759 Change-Id: I5a584032dca9a40e90dec23186562543f8752bad Signed-off-by: Oleksii Mozghovyi Signed-off-by: Robert Varga --- diff --git a/artifacts/pom.xml b/artifacts/pom.xml index abc67088ae..44de193148 100644 --- a/artifacts/pom.xml +++ b/artifacts/pom.xml @@ -100,6 +100,11 @@ netconf-testtool ${project.version} + + ${project.groupId} + netconf-test-perf + ${project.version} + ${project.groupId} netconf-util @@ -565,6 +570,22 @@ xml features + + + + ${project.groupId} + features-netconf-testing + ${project.version} + xml + features + + + ${project.groupId} + odl-netconf-test-tools + ${project.version} + xml + features + diff --git a/features/netconf/features-netconf-testing/pom.xml b/features/netconf/features-netconf-testing/pom.xml new file mode 100644 index 0000000000..dd0089f06e --- /dev/null +++ b/features/netconf/features-netconf-testing/pom.xml @@ -0,0 +1,122 @@ + + + + 4.0.0 + + + org.opendaylight.odlparent + feature-repo-parent + 8.1.0 + + + + org.opendaylight.netconf + features-netconf-testing + 1.10.0-SNAPSHOT + feature + + + + + ${project.groupId} + netconf-artifacts + ${project.version} + import + pom + + + + + + + ${project.groupId} + odl-aaa-netconf-plugin + xml + features + + + ${project.groupId} + odl-aaa-netconf-plugin-no-cluster + xml + features + + + ${project.groupId} + odl-netconf-all + xml + features + + + ${project.groupId} + odl-netconf-api + xml + features + + + ${project.groupId} + odl-netconf-client + xml + features + + + ${project.groupId} + odl-netconf-impl + xml + features + + + ${project.groupId} + odl-netconf-mapping-api + xml + features + + + ${project.groupId} + odl-netconf-mdsal + xml + features + + + ${project.groupId} + odl-netconf-netty-util + xml + features + + + ${project.groupId} + odl-netconf-notifications-api + xml + features + + + ${project.groupId} + odl-netconf-notifications-impl + xml + features + + + ${project.groupId} + odl-netconf-ssh + xml + features + + + ${project.groupId} + odl-netconf-tcp + xml + features + + + ${project.groupId} + odl-netconf-util + xml + features + + + diff --git a/features/netconf/odl-netconf-test-tools/pom.xml b/features/netconf/odl-netconf-test-tools/pom.xml new file mode 100644 index 0000000000..82a41d6585 --- /dev/null +++ b/features/netconf/odl-netconf-test-tools/pom.xml @@ -0,0 +1,49 @@ + + + + + org.opendaylight.odlparent + single-feature-parent + 8.1.0 + + + 4.0.0 + + org.opendaylight.netconf + odl-netconf-test-tools + 1.10.0-SNAPSHOT + feature + + OpenDaylight :: NETCONF Test Tools :: Tools used for performance testing + + + + + ${project.groupId} + netconf-artifacts + 1.10.0-SNAPSHOT + pom + import + + + + + + + ${project.groupId} + odl-netconf-mdsal + xml + features + + + ${project.groupId} + netconf-test-perf + + + diff --git a/features/netconf/pom.xml b/features/netconf/pom.xml index 12ed3c76e6..bb26b9fc63 100644 --- a/features/netconf/pom.xml +++ b/features/netconf/pom.xml @@ -41,6 +41,10 @@ odl-netconf-ssh odl-netconf-tcp odl-netconf-util + + + features-netconf-testing + odl-netconf-test-tools diff --git a/karaf/pom.xml b/karaf/pom.xml index b6fe8dde18..c7517c234a 100644 --- a/karaf/pom.xml +++ b/karaf/pom.xml @@ -72,5 +72,12 @@ xml runtime + + org.opendaylight.netconf + features-netconf-testing + features + xml + runtime + diff --git a/netconf/tools/netconf-test-perf/pom.xml b/netconf/tools/netconf-test-perf/pom.xml new file mode 100644 index 0000000000..2b7637561f --- /dev/null +++ b/netconf/tools/netconf-test-perf/pom.xml @@ -0,0 +1,77 @@ + + + + org.opendaylight.netconf + netconf-parent + 1.10.0-SNAPSHOT + ../../../parent/pom.xml + + 4.0.0 + + netconf-test-perf + NETCONF performance test tools + bundle + + + + org.opendaylight.mdsal + mdsal-dom-api + + + org.opendaylight.mdsal + mdsal-dom-spi + + + org.opendaylight.mdsal + mdsal-binding-dom-codec-api + + + org.opendaylight.mdsal.model + ietf-topology + + + org.opendaylight.netconf + ietf-netconf-notifications + + + org.opendaylight.netconf + mdsal-netconf-notification + + + org.opendaylight.netconf + netconf-notifications-api + + + com.guicedee.services + javax.inject + true + + + javax.annotation + javax.annotation-api + provided + true + + + org.osgi + org.osgi.service.component.annotations + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + NETCONF performance test tools + + + + + + diff --git a/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/MountedDeviceListener.java b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/MountedDeviceListener.java new file mode 100644 index 0000000000..62682f83ff --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/MountedDeviceListener.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf; + +import static java.util.Objects.requireNonNull; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.Iterator; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.dom.api.DOMMountPoint; +import org.opendaylight.mdsal.dom.api.DOMMountPointListener; +import org.opendaylight.mdsal.dom.api.DOMMountPointService; +import org.opendaylight.mdsal.dom.api.DOMNotificationService; +import org.opendaylight.mdsal.dom.api.DOMRpcResult; +import org.opendaylight.mdsal.dom.api.DOMRpcService; +import org.opendaylight.netconf.test.perf.notifications.NotificationsCounter; +import org.opendaylight.netconf.test.perf.utils.TestUtils; +import org.opendaylight.yang.gen.v1.org.opendaylight.coretutorials.ncmount.example.notifications.rev150611.VrfRouteNotification; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +@Component(immediate = true) +public class MountedDeviceListener implements DOMMountPointListener { + private static final Logger LOG = LoggerFactory.getLogger(MountedDeviceListener.class); + private static final String TEST_NODE_PREFIX = "perf-"; + private static final String STREAM_DEFAULT_NAME = "STREAM-PERF-DEFAULT"; + private static final QName CREATE_SUBSCRIPTION_QNAME = QName.create(CreateSubscriptionInput.QNAME, + "create-subscription"); + + private final ConcurrentMap> listeners = new ConcurrentHashMap<>(); + private final DOMMountPointService mountPointService; + private final BindingNormalizedNodeSerializer serializer; + private final ListenerRegistration reg; + + @Inject + @Activate + public MountedDeviceListener(final @Reference DOMMountPointService mountPointService, + final @Reference BindingNormalizedNodeSerializer serializer) { + this.mountPointService = requireNonNull(mountPointService); + this.serializer = requireNonNull(serializer); + reg = mountPointService.registerProvisionListener(this); + } + + @PreDestroy + @Deactivate + public void stop() { + reg.close(); + final Iterator> it = listeners.values().iterator(); + while (it.hasNext()) { + it.next().close(); + it.remove(); + } + } + + @Override + public void onMountPointCreated(final YangInstanceIdentifier path) { + final Optional optNodeId = TestUtils.getNodeId(path); + if (optNodeId.isPresent() && optNodeId.get().startsWith(TEST_NODE_PREFIX)) { + LOG.info("Test node mounted: {}", optNodeId.get()); + trackNotificationsPerformance(path); + } + } + + @Override + public void onMountPointRemoved(final YangInstanceIdentifier path) { + final ListenerRegistration listener = listeners.remove(path); + if (listener != null) { + listener.close(); + } + } + + private void trackNotificationsPerformance(final YangInstanceIdentifier path) { + // 1. get nodeId from the path + final String nodeId = TestUtils.getNodeId(path).get(); + + // 2. extract needed services from the mount point + final DOMMountPoint mountPoint = mountPointService.getMountPoint(path) + .orElseThrow(() -> new RuntimeException("Unable to get mountpoint")); + final DOMRpcService rpcService = mountPoint.getService(DOMRpcService.class) + .orElseThrow(() -> new RuntimeException("Unable to get RPC Service from the mountpoint")); + final DOMNotificationService notificationService = mountPoint.getService(DOMNotificationService.class) + .orElseThrow(() -> new RuntimeException("Unable to get NotificationService from the mountpoint")); + + // 3. create a listener for the notifications + listeners.put(path, notificationService.registerNotificationListener( + new NotificationsCounter(nodeId, serializer), Absolute.of(VrfRouteNotification.QNAME))); + + // 4. send 'create-subscription' request to the device + final StreamNameType streamNameType = new StreamNameType(STREAM_DEFAULT_NAME); + final CreateSubscriptionInputBuilder subscriptionInputBuilder = new CreateSubscriptionInputBuilder(); + subscriptionInputBuilder.setStream(streamNameType); + final CreateSubscriptionInput input = subscriptionInputBuilder.build(); + final ContainerNode inputNode = serializer.toNormalizedNodeRpcData(input); + final ListenableFuture resultFuture = rpcService.invokeRpc(CREATE_SUBSCRIPTION_QNAME, + inputNode); + Futures.addCallback(resultFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable final DOMRpcResult rpcResult) { + LOG.info("Notification stream subscription succesfully completed"); + } + + @Override + public void onFailure(final Throwable throwable) { + LOG.error("Notification stream subscription failed"); + } + }, MoreExecutors.directExecutor()); + } +} diff --git a/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/notifications/NotificationsCounter.java b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/notifications/NotificationsCounter.java new file mode 100644 index 0000000000..38a3dbd4f6 --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/notifications/NotificationsCounter.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf.notifications; + +import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.mdsal.dom.api.DOMNotificationListener; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ip._static.cfg.rev130722.VRFPREFIXTABLE; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotificationsCounter implements DOMNotificationListener { + + private static final Logger LOG = LoggerFactory.getLogger(NotificationsCounter.class); + + /** + * Custom pattern to identify nodes where performance should be measured. + */ + private static final Pattern NOTIFICATION_NUMBER_PATTERN = Pattern.compile(".*-notif-([0-9]+)"); + + private final String nodeId; + private final BindingNormalizedNodeSerializer serializer; + private final AtomicLong notifCounter; + private final long expectedNotificationCount; + private Stopwatch stopWatch; + private long totalPrefixesReceived = 0; + + public NotificationsCounter(final String nodeId, final BindingNormalizedNodeSerializer serializer) { + this.nodeId = nodeId; + this.serializer = serializer; + final Matcher matcher = NOTIFICATION_NUMBER_PATTERN.matcher(nodeId); + Preconditions.checkArgument(matcher.matches()); + expectedNotificationCount = Long.parseLong(matcher.group(1)); + Preconditions.checkArgument(expectedNotificationCount > 0); + this.notifCounter = new AtomicLong(this.expectedNotificationCount); + } + + + @Override + public void onNotification(@NonNull DOMNotification domNotification) { + final long andDecrement = notifCounter.getAndDecrement(); + + if (andDecrement == expectedNotificationCount) { + this.stopWatch = Stopwatch.createStarted(); + LOG.info("First notification received at {}", stopWatch); + } + + LOG.debug("Notification received, {} to go.", andDecrement); + if (LOG.isTraceEnabled()) { + LOG.trace("Notification received: {}", domNotification); + } + + final Notification notification = serializer.fromNormalizedNodeNotification(domNotification.getType(), + domNotification.getBody()); + if (notification instanceof VRFPREFIXTABLE) { + totalPrefixesReceived += ((VRFPREFIXTABLE)notification).getVrfPrefixes().getVrfPrefix().size(); + } + + if (andDecrement == 1) { + this.stopWatch.stop(); + LOG.info("Last notification received at {}", stopWatch); + LOG.info("Elapsed ms for {} notifications: {}", expectedNotificationCount, + stopWatch.elapsed(TimeUnit.MILLISECONDS)); + LOG.info("Performance (notifications/second): {}", + (expectedNotificationCount * 1.0 / stopWatch.elapsed(TimeUnit.MILLISECONDS)) * 1000); + LOG.info("Performance (prefixes/second): {}", + (totalPrefixesReceived * 1.0 / stopWatch.elapsed(TimeUnit.MILLISECONDS)) * 1000); + } + } + +} diff --git a/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/utils/TestUtils.java b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/utils/TestUtils.java new file mode 100644 index 0000000000..4c339577a9 --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/java/org/opendaylight/netconf/test/perf/utils/TestUtils.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Pantheon Technologies, s.r.o. 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.netconf.test.perf.utils; + +import java.util.Optional; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; + +public final class TestUtils { + + private static final QName NODE_QNAME = QName.create(Node.QNAME, "node-id").intern(); + + private TestUtils() { + } + + public static Optional getNodeId(final YangInstanceIdentifier path) { + if (path.getLastPathArgument() instanceof NodeIdentifierWithPredicates) { + final NodeIdentifierWithPredicates nodeIId = ((NodeIdentifierWithPredicates) path.getLastPathArgument()); + return Optional.ofNullable(nodeIId.getValue(NODE_QNAME, String.class)); + } else { + return Optional.empty(); + } + } +} diff --git a/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-ip-static-cfg@2013-07-22.yang b/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-ip-static-cfg@2013-07-22.yang new file mode 100644 index 0000000000..ed778cb0e1 --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-ip-static-cfg@2013-07-22.yang @@ -0,0 +1,371 @@ +module Cisco-IOS-XR-ip-static-cfg { + + /*** NAMESPACE / PREFIX DEFINITION ***/ + + namespace "http://cisco.com/ns/yang/Cisco-IOS-XR-ip-static-cfg"; + + + prefix "ip-static-cfg"; + + /*** LINKAGE (IMPORTS / INCLUDES) ***/ + + import ietf-inet-types { prefix "inet"; } + + import Cisco-IOS-XR-types { prefix "xr"; } + + /*** META INFORMATION ***/ + + organization "Cisco Systems, Inc."; + + contact + "Cisco Systems, Inc. + Customer Service + + Postal: 170 West Tasman Drive + San Jose, CA 95134 + + Tel: +1 800 553-NETS + + E-mail: cs-yang@cisco.com"; + + description + "This module contains a collection of YANG definitions + for Cisco IOS-XR ip-static package configuration. + + This module contains definitions + for the following management objects: + router-static: This class represents router static + configuration + + Copyright (c) 2013 by Cisco Systems, Inc. + All rights reserved."; + + revision "2013-07-22" { + description + "Initial revision."; + } + + + grouping VRF-ROUTE { + description "Common node of vrf-prefix, vrf-prefix-topology"; + + container vrf-route { + xr:xr-xml-map "ip_static_cfg:VRFRoute"; + description "A connected or recursive static route"; + + container vrf-next-hops { + xr:xr-xml-map "ip_static_cfg:VRFNextHopTable"; + description + "A forwarding interface and/or the address of a + nexthop router for this route (one of these + must be specified)"; + + grouping VRF-NEXT-HOP-CONTENT { + description "Content grouping."; + leaf bfd-fast-detect { + xr:xr-xml-map "ip_static_cfg:BFDFastDetect"; + type boolean; + default "false"; + description "If set, bfd is enabled"; + } + leaf minimum-interval { + xr:xr-xml-map "ip_static_cfg:MinimumInterval"; + type uint32 { + range "3..30000"; + } + units "millisecond"; + default "100"; + description "BFD Hello interval in milliseconds"; + } + leaf detect-multiplier { + xr:xr-xml-map "ip_static_cfg:DetectMultiplier"; + type uint32 { + range "1..10"; + } + default "3"; + description "BFD Detect Multiplier"; + } + leaf metric { + xr:xr-xml-map "ip_static_cfg:Metric"; + type uint32 { + range "1..254"; + } + default "1"; + description "Distance metric for this path"; + } + leaf tag { + xr:xr-xml-map "ip_static_cfg:Tag"; + type uint32 { + range "1..4294967295"; + } + description "Tag for this path"; + } + leaf permanent { + xr:xr-xml-map "ip_static_cfg:Permanent"; + type boolean; + default "false"; + description "If set, path is permanent"; + } + leaf vrf-lable { + xr:xr-xml-map "ip_static_cfg:VRFLable"; + type uint32 { + range "0..4294967295"; + } + default "0"; + description "VRF LABEL"; + } + leaf tunnel-id { + xr:xr-xml-map "ip_static_cfg:TunnelID"; + type uint32 { + range "0..65535"; + } + default "0"; + description "Tunnel ID for this path"; + } + leaf object-name { + xr:xr-xml-map "ip_static_cfg:ObjectName"; + type xr:Cisco-ios-xr-string { + length "0..32"; + } + description "Name of the object to track"; + } + leaf description { + xr:xr-xml-map "ip_static_cfg:Description"; + type string; + description "Short Description of Static Route"; + } + } + + list interface-name-and-next-hop-address { + xr:xr-xml-map "ip_static_cfg:VRFNextHop"; + key "interface-name next-hop-address"; + description "keys: interface-name, next-hop-address"; + leaf interface-name { + xr:xr-xml-map "ip_static_cfg:InterfaceName"; + type xr:Interface-name; + description "Forwarding interface"; + } + leaf next-hop-address { + xr:xr-xml-map "ip_static_cfg:NextHopAddress"; + type inet:ip-address; + description "Next hop address"; + } + uses VRF-NEXT-HOP-CONTENT; + } + + list interface-name { + xr:xr-xml-map "ip_static_cfg:VRFNextHop"; + key "interface-name"; + description "keys: interface-name"; + leaf interface-name { + xr:xr-xml-map "ip_static_cfg:InterfaceName"; + type xr:Interface-name; + description "Forwarding interface"; + } + uses VRF-NEXT-HOP-CONTENT; + } + + list next-hop-address { + xr:xr-xml-map "ip_static_cfg:VRFNextHop"; + key "next-hop-address"; + description "keys: next-hop-address"; + leaf next-hop-address { + xr:xr-xml-map "ip_static_cfg:NextHopAddress"; + type inet:ip-address; + description "Next hop address"; + } + uses VRF-NEXT-HOP-CONTENT; + } + } + } + } + + grouping TOPOLOGY-TABLE { + description "Common node of vrf-unicast, vrf-multicast"; + + container topologies { + xr:xr-xml-map "ip_static_cfg:TopologyTable"; + description "Topology static configuration container"; + + list topology { + xr:xr-xml-map "ip_static_cfg:Topology"; + key "topology-name"; + description "Topology static configuration"; + leaf topology-name { + xr:xr-xml-map "ip_static_cfg:TopologyName"; + type xr:Cisco-ios-xr-string; + description "Topology name"; + } + uses VRF-PREFIX-TOPOLOGY-TABLE; + } + } + } + + grouping VRF-PREFIX-TABLE { + description "Common node of vrf-unicast, vrf-multicast"; + + container vrf-prefixes { + xr:xr-xml-map "ip_static_cfg:VRFPrefixTable"; + description "The set of all Static Topologies for this AFI."; + + list vrf-prefix { + xr:xr-xml-map "ip_static_cfg:VRFPrefix"; + key "prefix prefix-length"; + description "A static route"; + leaf prefix { + xr:xr-xml-map "ip_static_cfg:Prefix"; + type inet:ip-address; + description "Destination prefix"; + } + leaf prefix-length { + xr:xr-xml-map "ip_static_cfg:PrefixLength"; + type uint32 { + range "0..128"; + } + description "Destination prefix length"; + } + uses VRF-ROUTE; + } + } + } + + grouping ADDRESS-FAMILY { + description "Common node of default-vrf, vrf"; + + container address-family { + xr:xr-xml-map "ip_static_cfg:AddressFamily"; + description "Address family configuration"; + + container vrfipv4 { + xr:xr-xml-map "ip_static_cfg:VRFIPV4"; + description "IPv4 static configuration"; + uses VRF-UNICAST; + uses VRF-MULTICAST; + } + + container vrfipv6 { + xr:xr-xml-map "ip_static_cfg:VRFIPV6"; + description "IPv6 static configuration"; + uses VRF-UNICAST; + uses VRF-MULTICAST; + } + } + } + + grouping VRF-PREFIX-TOPOLOGY-TABLE { + description "Common node of default-topology, topology"; + + container vrf-prefix-topologies { + xr:xr-xml-map "ip_static_cfg:VRFPrefixTopologyTable"; + description "The set of all Static Topologies for this AFI."; + + list vrf-prefix-topology { + xr:xr-xml-map "ip_static_cfg:VRFPrefixTopology"; + key "prefix prefix-length"; + description "A static route"; + leaf prefix { + xr:xr-xml-map "ip_static_cfg:Prefix"; + type inet:ip-address; + description "Destination prefix"; + } + leaf prefix-length { + xr:xr-xml-map "ip_static_cfg:PrefixLength"; + type uint32 { + range "0..128"; + } + description "Destination prefix length"; + } + uses VRF-ROUTE; + } + } + } + + grouping DEFAULT-TOPOLOGY { + description "Common node of vrf-unicast, vrf-multicast"; + + container default-topology { + xr:xr-xml-map "ip_static_cfg:DefaultTopology"; + description "Default topology configuration"; + uses VRF-PREFIX-TOPOLOGY-TABLE; + } + } + + grouping VRF-UNICAST { + description "Common node of vrfipv4, vrfipv6"; + + container vrf-unicast { + xr:xr-xml-map "ip_static_cfg:VRFUnicast"; + description "Unicast static configuration"; + uses TOPOLOGY-TABLE; + uses VRF-PREFIX-TABLE; + uses DEFAULT-TOPOLOGY; + } + } + + grouping VRF-MULTICAST { + description "Common node of vrfipv4, vrfipv6"; + + container vrf-multicast { + xr:xr-xml-map "ip_static_cfg:VRFMulticast"; + description "Multicast static configuration"; + uses TOPOLOGY-TABLE; + uses VRF-PREFIX-TABLE; + uses DEFAULT-TOPOLOGY; + } + } + + container router-static { + xr:xr-xml-map "ip_static_cfg:RouterStatic"; + description "This class represents router static configuration"; + + container vrfs { + xr:xr-xml-map "ip_static_cfg:VRFTable"; + description "VRF static configuration container"; + + list vrf { + xr:xr-xml-map "ip_static_cfg:VRF"; + key "vrf-name"; + description "VRF static configuration"; + leaf vrf-name { + xr:xr-xml-map "ip_static_cfg:VRFName"; + type xr:Cisco-ios-xr-string; + description "VRF name"; + } + uses ADDRESS-FAMILY; + } + } + + container default-vrf { + xr:xr-xml-map "ip_static_cfg:DefaultVRF"; + description "Default VRF configuration"; + uses ADDRESS-FAMILY; + } + + container maximum-routes { + xr:xr-xml-map "ip_static_cfg:MaximumRoutes"; + description + "The maximum number of static routes that can be + configured."; + leaf ipv6-routes { + xr:xr-xml-map "ip_static_cfg:IPV6Routes"; + type uint32 { + range "1..140000"; + } + default "4000"; + description + "The maximum number of static routes that can be + configured for this AFI"; + } + leaf ipv4-routes { + xr:xr-xml-map "ip_static_cfg:IPV4Routes"; + type uint32 { + range "1..140000"; + } + default "4000"; + description + "The maximum number of static routes that can be + configured for this AFI"; + } + } + } +} \ No newline at end of file diff --git a/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-types@2015-01-19.yang b/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-types@2015-01-19.yang new file mode 100644 index 0000000000..d6dce98f35 --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/yang/Cisco-IOS-XR-types@2015-01-19.yang @@ -0,0 +1,391 @@ +module Cisco-IOS-XR-types { + + namespace "http://cisco.com/ns/yang/cisco-xr-types"; + prefix "xr"; + + organization "Cisco Systems, Inc."; + + contact + "Cisco Systems, Inc. + Customer Service + + Postal: 170 W Tasman Drive + San Jose, CA 95134 + + Tel: +1 1800 553-NETS + + E-mail: cs-yang@cisco.com"; + + + description + "This module contains a collection of IOS-XR derived YANG data + types. + + Copyright (c) 2013-2015 by Cisco Systems, Inc. + All rights reserved."; + + revision "2015-01-19" { + description + "This revision adds the following new data types: + - Bgp-ipv4-flowspec-address + - Bgp-ipv6-flowspec-address"; + } + + extension xr-cli-map { + argument "cli-command"; + description "The xr-cli-map statement takes as an argument + relevant CLI configuration command."; + } + + extension xr-xml-map { + argument "xr-xml-node"; + description "The xr-xml-map statement takes as an argument + relevant Cisco XML Schema node name."; + } + + typedef Route-dist { + type string { + pattern "[a-fA-F0-9]{16}"; + } + description "Route distinguisher in hexadecimal notation."; + } + + typedef Bgp-l2vpn-evpn-addrs { + type string { + pattern "[a-fA-F0-9]{58}"; + } + description "L2VPN EVPN Address in hexadecimal notation."; + } + + typedef Bgp-ls-addr { + type string { + pattern "[a-fA-F0-9]+"; + } + description "BGP link state unicast address in hexadecimal + notation."; + } + + typedef Bgp-ipv6-mvpn-addr { + type string { + pattern "[a-fA-F0-9]{104}"; + } + description "An IPV6 MVPN address in hexadecimal notation."; + } + + typedef Bgp-ipv4-mvpn-addr { + type string { + pattern "[a-fA-F0-9]{56}"; + } + description "An IPV4 MVPN address in hexadecimal notation."; + } + + typedef Bgp-rt-constrt-addr { + type string { + pattern "[a-fA-F0-9]{24}"; + } + description + "An IPV4 RTConstraint address in hexadecimal notation."; + } + + typedef Bgp-ipv4-mdt-addr { + type string { + pattern "(([a-f0-9]{16}-)(([1-9]?[0-9]|1[0-9][0-9]|2[0-4]"+ + "[0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]"+ + "|25[0-5]))"; + } + description "An IPV4 MDT address in dotted decimal notation. + An IPv4 MDT address should be of the form + 0000006400000065-129.29.83.45. This datatype + restricts the value of each field 16 digits in + hexadecimal for RD field and between 0 and 255 + for IPv4 address field, i.e. + [0000000000000000-ffffffffffffffff]- + [0-255].[0-255].[0-255].[0-255]."; + } + + typedef Bgp-ipv4-tunnel-addr { + type string { + pattern "((0:|[1-9][0-9]{0,4}:)"+ + "(([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}"+ + "([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))"; + } + description "An IPV4 tunnel address in dotted decimal notation. + An IPv4 tunnel address should be of the form + 65535:129.29.83.45. This datatype restricts the + value of each field between 0 and 65535 for prefix + field and 0 and 255 for IPv4 address field, i.e. + [0-65535]:[0-255].[0-255].[0-255].[0-255]"; + } + + typedef Cisco-ios-xr-port-number { + type uint16 { + range "1..65535"; + } + description "Port number of range from 1 to 65535"; + } + + typedef Interface-name { + type string { + pattern "(([a-zA-Z0-9_]*\d+/){3}\d+)|"+ + "(([a-zA-Z0-9_]*\d+/){4}\d+)|"+ + "(([a-zA-Z0-9_]*\d+/){3}\d+\.\d+)|"+ + "(([a-zA-Z0-9_]*\d+/){2}([a-zA-Z0-9_]*\d+))|"+ + "([a-zA-Z0-9_-]*\d+)|"+ + "([a-zA-Z0-9_-]*\d+\.\d+)|"+ + "(mpls)|(dwdm)"; + } + description "An interface name specifying an interface type and + instance. + Interface represents a string defining an interface + type and instance, e.g. MgmtEth0/4/CPU1/0 or + TenGigE0/2/0/0.2 or Bundle-Ether9 or + Bundle-Ether9.98"; + } + + typedef Cisco-ios-xr-string { + type string { + pattern "[\w\-\.:,_@#%$\+=\|;]+"; + } + description "Special characters are not allowed."; + } + + typedef Ipv4-prefix-length { + type uint8 { + range "0..32"; + } + description "An IPv4 address prefix length. + Must lie between 0 and 32 inclusive."; + } + + typedef Ipv6-prefix-length { + type uint8 { + range "0..128"; + } + description "An IPv6 address prefix length. + Must lie between 0 and 32 inclusive."; + } + + typedef Rack-id { + type string { + pattern "[a-zA-Z0-9_]*\d+"; + } + description "Names the rack portion of a NodeID + Rack/Slot/Instance triple"; + } + + typedef Slot-id { + type string { + pattern "[a-zA-Z0-9_]*\d+"; + } + description "Names the slot portion of a NodeID + Rack/Slot/Instance triple"; + } + + typedef Instance-id { + type string { + pattern "[a-zA-Z0-9_]*\d+"; + } + description "Names the instance portion of a NodeID + Rack/Slot/Instance triple"; + } + + typedef Sub-instance-id { + type string { + pattern "[a-zA-Z0-9_]*\d+"; + } + description "Names the sub-instance portion of an extended + NodeID Rack/Slot/Instance/SubInstance"; + } + + typedef Encryption-type { + type enumeration { + enum none { + value "0"; + description "The password string is clear text."; + } + enum md5 { + value "1"; + description "The password is encrypted to an MD5 digest."; + } + enum proprietary { + value "2"; + description "The password is encrypted using Cisco type 7 + password encryption."; + } + } + description "The type of encryption used on a password string."; + + } + + typedef Hex-integer { + type string { + pattern "[0-9a-fA-F]{1,8}"; + } + description "An unsigned 32-bit integer represented in + hexadecimal format."; + } + + typedef Osi-system-id { + type string { + pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}"; + } + description "An OSI system ID should be of the form + 0123.4567.89ab. This data type restricts each + character to a hex character."; + } + + typedef Osi-area-address { + type string { + pattern "[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){0,6}"; + } + description "An OSI area address should consist of an odd number + of octets, and be of the form 01 or 01.2345 etc up + to 01.2345.6789.abcd.ef01.2345.6789. This data type + restricts each character to a hex character."; + } + + typedef Isis-node-id { + type string { + pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}\.[a-fA-F0-9]{2}"; + } + description "An ISIS node ID should be of the form + 0123.4567.89ab.cd. This data type restricts each + character to a hex character."; + } + + typedef Isis-snpa { + type string { + pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}"; + } + description "String representation of a SNPA, 802.2 MAC address + in canonical format, e.g. 0123.4567.89ab"; + } + + typedef Isis-lsp-id { + type string { + pattern "[a-fA-F0-9]{4}(\.[a-fA-F0-9]{4}){2}\.[a-fA-F0-9]{2}"+ + "\-[a-fA-F0-9]{2}"; + } + description "An ISIS LSP ID should be of the form + 0123.4567.89ab.cd-ef. This data type restricts each + character to a hex character."; + } + + typedef Osi-net { + type string { + pattern + "[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}"; + } + description "An OSI NET should consist of an even number of + octets, and be of the form 01.2345.6789.abcd.ef etc + up to + 01.2345.6789.abcd.ef01.2345.6789.abcd.ef01.2345.67. + This data type restricts each character to a hex + character."; + } + + typedef String-identifier { + type string { + pattern "[a-zA-Z][\w\-]*"; + } + description "A string for specifying identifier."; + } + + typedef Extended-node-id { + type string { + pattern "([a-zA-Z0-9_]*\d+/){3}([a-zA-Z0-9_]*\d+)"; + } + description "A location used as value information and specified + as a Rack/Slot/Instance/SubInstance, e.g. + 0/1/CPU0/NPU0"; + } + + typedef Node-id { + type string { + pattern "([a-zA-Z0-9_]*\d+/){2}([a-zA-Z0-9_]*\d+)"; + } + description "A location used as value information and specified + as a Rack/Slot/Instance triple, e.g. F0/SC1/0."; + } + + typedef Pq-node-id { + type string { + pattern "((([a-zA-Z0-9_]*\d+)|(\*))/){2}(([a-zA-Z0-9_]*\d+)"+ + "|(\*))"; + } + description "Partially qualified location which is used for + wildcarding location specifications, e.g. 1/*/*"; + } + + typedef Md5-password { + type string { + pattern "(!.+)|([^!].+)"; + } + description + "The Md5-password type is used to store password using the MD5 + hash function. + When a clear text value is set to a leaf of this type, the + server calculates a password hash and stores the result + in the datastore. The password is never stored in clear text. + + When a leaf of this type is read, the stored password hash is + returned. + + A value of this type matches one of the forms: + + ! + + + The '!' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated. This value is stored in the configuration data + store. + + If a value starting without '!' is received, the server knows + that the value already represents a hashed value, and stores + it as is in the data store."; + } + + typedef Proprietary-password { + type string { + pattern "(!.+)|([^!].+)"; + } + description + "The Proprietary-password type is used to store password + using the Cisco proprietary hash function. + When a clear text value is set to a leaf of this type, the + server calculates a password hash and stores the result + in the datastore. The password is never stored in clear text. + + When a leaf of this type is read, the stored password hash is + returned. + + A value of this type matches one of the forms: + + ! + + + The '!' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated. This value is stored in the configuration data + store. + + If a value starting without '!' is received, the server knows + that the value already represents a hashed value, and stores + it as is in the data store."; + } + + typedef Bgp-ipv4-flowspec-address { + type string { + pattern "[a-fA-F0-9]{4096}"; + } + description "An IPV4 Flowspec address in hexadecimal notation."; + } + + typedef Bgp-ipv6-flowspec-address { + type string { + pattern "[a-fA-F0-9]{4096}"; + } + description "An IPV6 Flowspec address in hexadecimal notation."; + } +} diff --git a/netconf/tools/netconf-test-perf/src/main/yang/Example-notifications@2015-06-11.yang b/netconf/tools/netconf-test-perf/src/main/yang/Example-notifications@2015-06-11.yang new file mode 100644 index 0000000000..18412c255e --- /dev/null +++ b/netconf/tools/netconf-test-perf/src/main/yang/Example-notifications@2015-06-11.yang @@ -0,0 +1,24 @@ +module Example-notifications { + + namespace "org:opendaylight:coretutorials:ncmount:example:notifications"; + + prefix "ex-not"; + + import Cisco-IOS-XR-ip-static-cfg { prefix "ip-static-cfg"; } + + description + "Sample model used for notification utilization demonstration. + This model is not used by XR or any other netconf server."; + + revision "2015-06-11" { + description + "Initial revision."; + } + + notification vrf-route-notification { + uses ip-static-cfg:VRF-PREFIX-TABLE; + description "Artificial notification based on Cisco-IOS-XR-ip-static-cfg model"; + } + + +} \ No newline at end of file diff --git a/netconf/tools/pom.xml b/netconf/tools/pom.xml index 1f5d483f01..40069e31a1 100644 --- a/netconf/tools/pom.xml +++ b/netconf/tools/pom.xml @@ -28,6 +28,7 @@ + netconf-test-perf netconf-testtool