Initial import of CFM and SOAM api

Change-Id: Icf5cc2d5fb34b75460e80e8cced0d70265bcd33b
This commit is contained in:
Sean Condon 2017-03-21 14:23:19 +00:00
parent ae0f5dccee
commit 0e89bda7fc
237 changed files with 29098 additions and 209 deletions

28
apps/cfm/BUCK Normal file
View File

@ -0,0 +1,28 @@
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:javax.ws.rs-api',
'//utils/rest:onlab-rest',
'//lib:JACKSON',
'//cli:onos-cli',
'//lib:org.apache.karaf.shell.console',
'//incubator/api:onos-incubator-api'
]
TEST_DEPS = [
'//lib:TEST_REST',
'//utils/osgi:onlab-osgi-tests',
'//web/api:onos-rest-tests',
]
osgi_jar_with_tests (
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
web_context = '/onos/cfm',
)
onos_app (
title = 'Layer 2 Monitoring CFM Application',
category = 'default',
url = 'http://onosproject.org',
description = 'Layer 2 Monitoring Connectivity Fault Management App',
)

3
apps/cfm/README.md Normal file
View File

@ -0,0 +1,3 @@
# Layer 2 Monitoring with CFM and SOAM in ONOS
Please see the README.md file in the API at
incubator/api/src/main/java/org/onosproject/incubator/net/l2monitoring/README.md

96
apps/cfm/pom.xml Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ~ Copyright 2017 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.12.0-SNAPSHOT</version>
</parent>
<artifactId>onos-app-cfm</artifactId>
<packaging>bundle</packaging>
<version>1.12.0-SNAPSHOT</version>
<description>ONOS OSGi bundle archetype</description>
<url>http://onosproject.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<web.context>/onos/cfm</web.context>
<api.description>Layer 2 Monitoring CFM REST API</api.description>
<api.version>1.0.0</api.version>
<api.package>org.onosproject.cfm</api.package>
<api.title>Layer 2 Monitoring CFM REST API</api.title>
<onos.app.name>org.onosproject.cfm</onos.app.name>
<onos.app.title>Layer 2 Monitoring CFM App</onos.app.title>
<onos.app.origin>Microsemi Inc</onos.app.origin>
<onos.app.category>default</onos.app.category>
<onos.app.url>http://onosproject.org</onos.app.url>
<onos.app.readme>Layer 2 Monitoring Connectivity Fault Management App</onos.app.readme>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
</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>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_wab>src/main/webapp/</_wab>
<Include-Resource>WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
{maven-resources}</Include-Resource>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>*,org.glassfish.jersey.servlet</Import-Package>
<Web-ContextPath>${web.context}</Web-ContextPath>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,195 @@
/*
* Copyright 2017-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.cfm;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.VlanId;
import org.onosproject.cfm.web.ComponentCodec;
import org.onosproject.cfm.web.FngAddressCodec;
import org.onosproject.cfm.web.MaintenanceAssociationCodec;
import org.onosproject.cfm.web.MaintenanceDomainCodec;
import org.onosproject.cfm.web.MepCodec;
import org.onosproject.cfm.web.MepEntryCodec;
import org.onosproject.cfm.web.MepLbCreateCodec;
import org.onosproject.cfm.web.MepLbEntryCodec;
import org.onosproject.cfm.web.MepLtCreateCodec;
import org.onosproject.cfm.web.RemoteMepEntryCodec;
import org.onosproject.cfm.web.VidCodec;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.FngAddress;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.soam.StartTime;
import org.onosproject.incubator.net.l2monitoring.soam.StopTime;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStat;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStat;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStatHistory;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate.CounterOption;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStat;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatHistory;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementThreshold;
import org.onosproject.soam.web.DelayMeasurementStatCodec;
import org.onosproject.soam.web.DelayMeasurementStatCurrentCodec;
import org.onosproject.soam.web.DelayMeasurementStatHistoryCodec;
import org.onosproject.soam.web.DmCreateCodec;
import org.onosproject.soam.web.DmEntryCodec;
import org.onosproject.soam.web.DmMeasurementOptionCodec;
import org.onosproject.soam.web.LmCounterOptionCodec;
import org.onosproject.soam.web.LmCreateCodec;
import org.onosproject.soam.web.LmEntryCodec;
import org.onosproject.soam.web.LmThresholdOptionCodec;
import org.onosproject.soam.web.LossAvailabilityStatCodec;
import org.onosproject.soam.web.LossAvailabilityStatCurrentCodec;
import org.onosproject.soam.web.LossAvailabilityStatHistoryCodec;
import org.onosproject.soam.web.LossMeasurementStatCodec;
import org.onosproject.soam.web.LossMeasurementStatCurrentCodec;
import org.onosproject.soam.web.LossMeasurementStatHistoryCodec;
import org.onosproject.soam.web.LossMeasurementThresholdCodec;
import org.onosproject.soam.web.StartTimeCodec;
import org.onosproject.soam.web.StopTimeCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementThreshold.*;
/**
* Enables the CFM REST Web Service component at /onos/cfm.
* Each codec for the rest interfaces should be registered here.
*/
@Component(immediate = true)
public class CfmWebComponent {
private final Logger log = LoggerFactory.getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CodecService codecService;
@Activate
public void activate() {
codecService.registerCodec(MaintenanceDomain.class,
new MaintenanceDomainCodec());
codecService.registerCodec(MaintenanceAssociation.class,
new MaintenanceAssociationCodec());
codecService.registerCodec(org.onosproject.incubator.net.l2monitoring.cfm.Component.class,
new ComponentCodec());
codecService.registerCodec(VlanId.class, new VidCodec());
codecService.registerCodec(Mep.class, new MepCodec());
codecService.registerCodec(MepEntry.class, new MepEntryCodec());
codecService.registerCodec(MepLbCreate.class, new MepLbCreateCodec());
codecService.registerCodec(MepLbEntry.class, new MepLbEntryCodec());
codecService.registerCodec(MepLtCreate.class, new MepLtCreateCodec());
codecService.registerCodec(RemoteMepEntry.class, new RemoteMepEntryCodec());
codecService.registerCodec(FngAddress.class, new FngAddressCodec());
codecService.registerCodec(DelayMeasurementCreate.class,
new DmCreateCodec());
codecService.registerCodec(DelayMeasurementEntry.class,
new DmEntryCodec());
codecService.registerCodec(DelayMeasurementStat.class,
new DelayMeasurementStatCodec());
codecService.registerCodec(DelayMeasurementStatCurrent.class,
new DelayMeasurementStatCurrentCodec());
codecService.registerCodec(DelayMeasurementStatHistory.class,
new DelayMeasurementStatHistoryCodec());
codecService.registerCodec(MeasurementOption.class,
new DmMeasurementOptionCodec());
codecService.registerCodec(LossMeasurementCreate.class,
new LmCreateCodec());
codecService.registerCodec(LossMeasurementThreshold.class,
new LossMeasurementThresholdCodec());
codecService.registerCodec(LossMeasurementEntry.class,
new LmEntryCodec());
codecService.registerCodec(LossMeasurementStat.class,
new LossMeasurementStatCodec());
codecService.registerCodec(LossMeasurementStatCurrent.class,
new LossMeasurementStatCurrentCodec());
codecService.registerCodec(LossMeasurementStatHistory.class,
new LossMeasurementStatHistoryCodec());
codecService.registerCodec(LossAvailabilityStat.class,
new LossAvailabilityStatCodec());
codecService.registerCodec(LossAvailabilityStatCurrent.class,
new LossAvailabilityStatCurrentCodec());
codecService.registerCodec(LossAvailabilityStatHistory.class,
new LossAvailabilityStatHistoryCodec());
codecService.registerCodec(CounterOption.class,
new LmCounterOptionCodec());
codecService.registerCodec(ThresholdOption.class,
new LmThresholdOptionCodec());
codecService.registerCodec(StartTime.class, new StartTimeCodec());
codecService.registerCodec(StopTime.class, new StopTimeCodec());
log.info("CFM Web Component Started");
}
@Deactivate
public void deactivate() {
log.info("CFM Web Component Stopped");
codecService.unregisterCodec(MaintenanceDomain.class);
codecService.unregisterCodec(MaintenanceAssociation.class);
codecService.unregisterCodec(org.onosproject.incubator.net.l2monitoring.cfm.Component.class);
codecService.unregisterCodec(VlanId.class);
codecService.unregisterCodec(Mep.class);
codecService.unregisterCodec(MepEntry.class);
codecService.unregisterCodec(MepLbCreate.class);
codecService.unregisterCodec(MepLbEntry.class);
codecService.unregisterCodec(MepLtCreate.class);
codecService.unregisterCodec(RemoteMepEntry.class);
codecService.unregisterCodec(FngAddress.class);
codecService.unregisterCodec(DelayMeasurementCreate.class);
codecService.unregisterCodec(DelayMeasurementEntry.class);
codecService.unregisterCodec(DelayMeasurementStat.class);
codecService.unregisterCodec(DelayMeasurementStatCurrent.class);
codecService.unregisterCodec(DelayMeasurementStatHistory.class);
codecService.unregisterCodec(MeasurementOption.class);
codecService.unregisterCodec(StartTime.class);
codecService.unregisterCodec(StopTime.class);
codecService.unregisterCodec(LossMeasurementCreate.class);
codecService.unregisterCodec(LossMeasurementThreshold.class);
codecService.unregisterCodec(LossMeasurementEntry.class);
codecService.unregisterCodec(LossMeasurementStat.class);
codecService.unregisterCodec(LossMeasurementStatCurrent.class);
codecService.unregisterCodec(LossMeasurementStatHistory.class);
codecService.unregisterCodec(LossAvailabilityStat.class);
codecService.unregisterCodec(LossAvailabilityStatCurrent.class);
codecService.unregisterCodec(LossAvailabilityStatHistory.class);
codecService.unregisterCodec(CounterOption.class);
codecService.unregisterCodec(ThresholdOption.class);
}
}

View File

@ -0,0 +1,184 @@
/*
* Copyright 2017-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.cfm.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultComponent;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
/**
* Adds a Maintenance Association to a Maintenance Domain.
*/
@Command(scope = "onos", name = "cfm-ma-add",
description = "Add a CFM Maintenance Association to a Maintenance Domain.")
public class CfmMaAddCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name",
description = "Maintenance Domain name and type (in brackets)",
required = true, multiValued = false)
String mdName = null;
@Argument(index = 1, name = "name-type",
description = "Maintenance Assocation name type",
required = true, multiValued = false)
String nameType = null;
@Argument(index = 2, name = "name",
description = "Maintenance Assocation name. Restrictions apply depending " +
"on name-type",
required = true, multiValued = false)
String name = null;
@Argument(index = 3, name = "ccm-interval",
description = "CCM Interval values from list",
required = true, multiValued = false)
String ccmInterval = null;
@Argument(index = 4, name = "numeric-id",
description = "An optional numeric id for Maintenance Association [1-65535]",
required = false, multiValued = false)
short numericId = 0;
@Argument(index = 5, name = "component-id",
description = "An id for a Component in the Component List [1-65535]." +
"The CLI allows creation of only 1 component. If more are " +
"required use the REST interface",
required = false, multiValued = false)
short componentId = 0;
@Argument(index = 6, name = "component-tag-type",
description = "Tag Type value for the component",
required = false, multiValued = false)
String tagType = null;
@Argument(index = 7, name = "component-mhf-creation",
description = "MEP Half function creation type for the component",
required = false, multiValued = false)
String mhfCreationType = null;
@Argument(index = 8, name = "component-vid",
description = "A VID for the component [1-4095]. This CLI allows " +
"only the specification of 1 VID. If more are required use " +
"the REST interface",
required = false, multiValued = false)
short vid = 0;
@Argument(index = 9, name = "rmep",
description = "Remote Mep numeric identifier [1-8192]",
required = true, multiValued = true)
String[] rmepArray = null;
@Override
protected void execute() {
CfmMdService service = get(CfmMdService.class);
String[] mdNameParts = mdName.split("[()]");
if (mdNameParts.length != 2) {
throw new IllegalArgumentException("Invalid name format. " +
"Must be in the format of <identifier(name-type)>");
}
MdId mdId = null;
MdId.MdNameType mdNameTypeEnum = MdId.MdNameType.valueOf(mdNameParts[1]);
switch (mdNameTypeEnum) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(mdNameParts[0]);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(mdNameParts[0]);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(mdNameParts[0]);
}
MaIdShort maId = null;
MaIdShort.MaIdType maNameTypeEnum = MaIdShort.MaIdType.valueOf(nameType);
switch (maNameTypeEnum) {
case TWOOCTET:
maId = MaId2Octet.asMaId(name);
break;
case ICCY1731:
maId = MaIdIccY1731.asMaId(name);
break;
case PRIMARYVID:
maId = MaIdPrimaryVid.asMaId(name);
break;
case RFC2685VPNID:
maId = MaIdRfc2685VpnId.asMaIdHex(name);
break;
case CHARACTERSTRING:
default:
maId = MaIdCharStr.asMaId(name);
}
MaintenanceAssociation.MaBuilder builder = null;
try {
builder = DefaultMaintenanceAssociation.builder(maId, mdId.getNameLength());
if (ccmInterval != null && !ccmInterval.isEmpty()) {
builder = builder.ccmInterval(MaintenanceAssociation.CcmInterval.valueOf(ccmInterval));
}
for (String rmep:rmepArray) {
builder = builder.addToRemoteMepIdList(MepId.valueOf(Short.parseShort(rmep)));
}
if (numericId > 0) {
builder = builder.maNumericId(numericId);
}
if (componentId > 0) {
Component.ComponentBuilder compBuilder =
DefaultComponent.builder(componentId);
if (tagType != null && !tagType.isEmpty()) {
compBuilder = compBuilder.tagType(
Component.TagType.valueOf(tagType));
}
if (mhfCreationType != null && !mhfCreationType.isEmpty()) {
compBuilder = compBuilder.mhfCreationType(
Component.MhfCreationType.valueOf(mhfCreationType));
}
if (vid > 0) {
compBuilder = compBuilder.addToVidList(VlanId.vlanId(vid));
}
builder = builder.addToComponentList(compBuilder.build());
}
boolean created = service.createMaintenanceAssociation(mdId, builder.build());
print("Maintenance Association %s is successfully %s on MD %s",
maId, created ? "updated" : "created", mdId);
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright 2017-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.cfm.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
/**
* Delete a Maintenance Association from the existing list of a Maintenance Domain.
*/
@Command(scope = "onos", name = "cfm-ma-delete",
description = "Delete a CFM Maintenance Association and its children.")
public class CfmMaDeleteCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name",
description = "Maintenance Domain name and type (in brackets) " +
"and the Maintenance Association name and type (in brackets)",
required = true, multiValued = false)
String name = null;
@Override
protected void execute() {
CfmMdService service = get(CfmMdService.class);
String[] nameParts = name.split("[()]");
if (nameParts.length != 4) {
throw new IllegalArgumentException("Invalid name format. Must be in " +
"the format of <identifier(name-type)identifier(name-type)>");
}
MdId mdId = null;
MdId.MdNameType nameTypeEnum = MdId.MdNameType.valueOf(nameParts[1]);
switch (nameTypeEnum) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(nameParts[0]);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(nameParts[0]);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(nameParts[0]);
}
MaIdShort maId = null;
MaIdShort.MaIdType maNameTypeEnum = MaIdShort.MaIdType.valueOf(nameParts[3]);
switch (maNameTypeEnum) {
case TWOOCTET:
maId = MaId2Octet.asMaId(nameParts[2]);
break;
case ICCY1731:
maId = MaIdIccY1731.asMaId(nameParts[2]);
break;
case PRIMARYVID:
maId = MaIdPrimaryVid.asMaId(nameParts[2]);
break;
case RFC2685VPNID:
maId = MaIdRfc2685VpnId.asMaIdHex(nameParts[2]);
break;
case CHARACTERSTRING:
default:
maId = MaIdCharStr.asMaId(nameParts[2]);
}
try {
boolean deleted = service.deleteMaintenanceAssociation(mdId, maId);
print("Maintenance Association %s-%s is %ssuccessfully deleted.",
mdId, maId, deleted ? "" : "NOT ");
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017-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.cfm.cli;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Argument;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import java.util.Optional;
/**
* Adds a Maintenance Domain to the existing list.
*/
@Command(scope = "onos", name = "cfm-md-add",
description = "Add a CFM Maintenance Domain.")
public class CfmMdAddCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name-type",
description = "Maintenance Domain name type",
required = true, multiValued = false)
String nameType = null;
@Argument(index = 1, name = "name",
description = "Maintenance Domain name. Restrictions apply depending " +
"on name-type. Leave empty if name type is none",
required = true, multiValued = false)
String name = null;
@Argument(index = 2, name = "level",
description = "Maintenance Domain level LEVEL0-LEVEL7",
required = true, multiValued = false)
String level = null;
@Argument(index = 3, name = "numeric-id",
description = "An optional numeric id for Maintenance Domain [1-65535]",
required = false, multiValued = false)
short numericId = 0;
@Override
protected void execute() {
CfmMdService service = get(CfmMdService.class);
MdId mdId = null;
MdId.MdNameType nameTypeEnum = MdId.MdNameType.valueOf(nameType);
switch (nameTypeEnum) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(name);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(name);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(name);
}
MaintenanceDomain.MdLevel levelEnum =
MaintenanceDomain.MdLevel.valueOf(level);
Optional<Short> numericIdOpt = Optional.empty();
if (numericId > 0) {
numericIdOpt = Optional.of(numericId);
}
MaintenanceDomain.MdBuilder builder = null;
try {
builder = DefaultMaintenanceDomain.builder(mdId).mdLevel(levelEnum);
if (numericIdOpt.isPresent()) {
builder = builder.mdNumericId(numericIdOpt.get());
}
boolean created = service.createMaintenanceDomain(builder.build());
print("Maintenance Domain with id %s is successfully %s.",
mdId, created ? "updated" : "created");
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2017-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.cfm.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
/**
* Deletes a Maintenance Domain from the existing list.
*/
@Command(scope = "onos", name = "cfm-md-delete",
description = "Delete a CFM Maintenance Domain and its children.")
public class CfmMdDeleteCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name",
description = "Maintenance Domain name and type (in brackets)",
required = true, multiValued = false)
String name = null;
@Override
protected void execute() {
CfmMdService service = get(CfmMdService.class);
String[] nameParts = name.split("[()]");
if (nameParts.length != 2) {
throw new IllegalArgumentException("Invalid name format. " +
"Must be in the format of <identifier(name-type)>");
}
MdId mdId = null;
MdId.MdNameType nameTypeEnum = MdId.MdNameType.valueOf(nameParts[1]);
switch (nameTypeEnum) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(nameParts[0]);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(nameParts[0]);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(nameParts[0]);
}
try {
boolean deleted = service.deleteMaintenanceDomain(mdId);
print("Maintenance Domain %s is %ssuccessfully deleted.",
mdId, deleted ? "" : "NOT ");
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2017-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.cfm.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import java.util.Optional;
/**
* Lists a particular Maintenance Domain.
*/
@Command(scope = "onos", name = "cfm-md-list",
description = "Lists a single CFM Maintenance Domain or all if none specified.")
public class CfmMdListMdCommand extends AbstractShellCommand {
@Argument(index = 0, name = "name",
description = "Maintenance Domain name and type (in brackets)",
required = false, multiValued = false)
String name = null;
@Override
protected void execute() {
CfmMdService service = get(CfmMdService.class);
if (name != null) {
String[] nameParts = name.split("[()]");
if (nameParts.length != 2) {
throw new IllegalArgumentException("Invalid name format. " +
"Must be in the format of <identifier(name-type)>");
}
MdId mdId = null;
MdId.MdNameType nameTypeEnum = MdId.MdNameType.valueOf(nameParts[1]);
switch (nameTypeEnum) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(nameParts[0]);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(nameParts[0]);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(nameParts[0]);
}
print("Maintenance Domain:");
Optional<MaintenanceDomain> md = service.getMaintenanceDomain(mdId);
print(printMd(md));
md.get().maintenanceAssociationList().forEach(ma -> printMa(Optional.of(ma)));
} else {
service.getAllMaintenanceDomain().forEach(md -> {
print(printMd(Optional.of(md)));
});
}
}
public static String printMd(Optional<MaintenanceDomain> md) {
if (!md.isPresent()) {
return new String("MD not found");
} else {
StringBuffer sb = new StringBuffer("\tMD: ");
sb.append(md.get().mdId().mdName());
sb.append("(" + md.get().mdId().nameType());
sb.append(") Lvl:" + md.get().mdLevel().ordinal());
sb.append(", Num: " + md.get().mdNumericId());
md.get().maintenanceAssociationList().
forEach(ma -> sb.append(printMa(Optional.of(ma))));
return sb.toString();
}
}
public static String printMa(Optional<MaintenanceAssociation> ma) {
if (!ma.isPresent()) {
return "\n\tNo MA found";
}
StringBuilder sb = new StringBuilder("\n\t\tMA: ");
sb.append(ma.get().maId().maName());
sb.append("(");
sb.append(ma.get().maId().nameType());
sb.append(") CCM: ");
sb.append(ma.get().ccmInterval());
sb.append(" Num: ");
sb.append(ma.get().maNumericId());
ma.get().remoteMepIdList().forEach(rmep -> {
sb.append("\n\t\t\tRmep: ");
sb.append(rmep);
});
ma.get().componentList().forEach(comp -> {
sb.append("\n\t\t\tComponent: ");
sb.append(comp.componentId());
sb.append(" Perm: ");
sb.append(comp.idPermission());
sb.append(" MHF: ");
sb.append(comp.mhfCreationType());
sb.append(" Tag: ");
sb.append(comp.tagType());
comp.vidList().forEach(vid -> {
sb.append("\n\t\t\t\tVID: ");
sb.append(vid);
});
});
return sb.toString();
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import java.util.ArrayList;
import java.util.List;
/**
* CLI completer for Component MEP Half Function creation.
*/
public class CfmCompMhfCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
for (Component.MhfCreationType mhfCreationType: Component.MhfCreationType.values()) {
choices.add(String.valueOf(mhfCreationType.toString()));
}
return choices;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import java.util.ArrayList;
import java.util.List;
/**
* CLI completer for Component TagType creation.
*/
public class CfmCompTagTypeCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
for (Component.TagType tagType: Component.TagType.values()) {
choices.add(String.valueOf(tagType.toString()));
}
return choices;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import java.util.ArrayList;
import java.util.List;
/**
* CLI completer for Ccm Interval creation.
*/
public class CfmMaCcmIntervalCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
for (MaintenanceAssociation.CcmInterval ccmInterval: MaintenanceAssociation.CcmInterval.values()) {
choices.add(ccmInterval.toString());
}
return choices;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import java.util.ArrayList;
import java.util.List;
import static org.onosproject.cli.AbstractShellCommand.get;
/**
* CLI completer for MA Name creation.
*/
public class CfmMaNameCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
CfmMdService service = get(CfmMdService.class);
service.getAllMaintenanceDomain().forEach(md ->
md.maintenanceAssociationList().forEach(ma ->
choices.add(new StringBuilder(md.mdId().mdName())
.append("(")
.append(md.mdId().nameType())
.append(")")
.append(ma.maId().maName())
.append("(")
.append(ma.maId().nameType())
.append(")").toString())
)
);
return choices;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import java.util.List;
import java.util.SortedSet;
/**
* CLI completer for MA name type creation.
*/
public class CfmMaNameTypeCompleter implements Completer {
@Override
public int complete(String buffer, int cursor, List<String> candidates) {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
SortedSet<String> strings = delegate.getStrings();
for (MaIdShort.MaIdType nameType : MaIdShort.MaIdType.values()) {
strings.add(nameType.toString());
}
// Now let the completer do the work for figuring out what to offer.
return delegate.complete(buffer, cursor, candidates);
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import java.util.ArrayList;
import java.util.List;
/**
* CLI completer for MD Level creation.
*/
public class CfmMdLevelCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
for (MaintenanceDomain.MdLevel mdLevel:MaintenanceDomain.MdLevel.values()) {
choices.add(String.valueOf(mdLevel.toString()));
}
return choices;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.onosproject.cli.AbstractChoicesCompleter;
import static org.onosproject.cli.AbstractShellCommand.get;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import java.util.ArrayList;
import java.util.List;
/**
* CLI completer for MD Name creation.
*/
public class CfmMdNameCompleter extends AbstractChoicesCompleter {
@Override
public List<String> choices() {
List<String> choices = new ArrayList<>();
CfmMdService service = get(CfmMdService.class);
service.getAllMaintenanceDomain().forEach(md ->
choices.add(md.mdId().mdName() + "(" + md.mdId().nameType() + ")"));
return choices;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2017-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.cfm.cli.completer;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import java.util.List;
import java.util.SortedSet;
/**
* CLI completer for MD Name Type creation.
*/
public class CfmMdNameTypeCompleter implements Completer {
@Override
public int complete(String buffer, int cursor, List<String> candidates) {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
SortedSet<String> strings = delegate.getStrings();
for (MdId.MdNameType nameType : MdId.MdNameType.values()) {
strings.add(nameType.toString());
}
// Now let the completer do the work for figuring out what to offer.
return delegate.complete(buffer, cursor, candidates);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* Completion of Commands for creating and deleting Maintenance Domains and Maintenance Associations.
*/
package org.onosproject.cfm.cli.completer;

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* Commands for creating and deleting Maintenance Domains and Maintenance Associations.
*/
package org.onosproject.cfm.cli;

View File

@ -0,0 +1,38 @@
/*
* Copyright 2017-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.cfm.impl;
import java.util.Set;
import org.onlab.rest.AbstractWebApplication;
import org.onosproject.soam.impl.DmWebResource;
import org.onosproject.soam.impl.LmWebResource;
/**
* CFM REST API web application.
*/
public class CfmWebApplication extends AbstractWebApplication {
@Override
public Set<Class<?>> getClasses() {
return getClasses(
MdWebResource.class,
MaWebResource.class,
MepWebResource.class,
DmWebResource.class,
LmWebResource.class);
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright 2017-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.cfm.impl;
import java.io.InputStream;
import java.net.URI;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onosproject.cfm.web.MaintenanceAssociationCodec;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Layer 2 CFM Maintenance Association web resource.
*/
@Path("md/{md_name}/ma")
public class MaWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* Get Maintenance Association by MD and MA name.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @return 200 OK with details of MA or 500 on Error
*/
@GET
@Path("{ma_name}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getMa(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName) {
log.debug("GET called for MA {}/{}", mdName, maName);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MaintenanceAssociation ma = get(CfmMdService.class)
.getMaintenanceAssociation(mdId, maId)
.orElseThrow(() -> new IllegalArgumentException(
"MA " + maName + " not Found"));
ObjectNode node = mapper().createObjectNode();
node.set("ma", codec(MaintenanceAssociation.class).encode(ma, this));
return ok(node).build();
} catch (IllegalArgumentException e) {
log.error("Get MA {} failed", mdName + "/" + maName, e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Delete the Maintenance Association by MD and MA name.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @return 200 OK if removed, 304 if item was not found or 500 on Error
*/
@DELETE
@Path("{ma_name}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteMa(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName) {
log.debug("DELETE called for MA {}/{}", mdName, maName);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
boolean deleted = get(CfmMdService.class)
.deleteMaintenanceAssociation(mdId, maId);
if (!deleted) {
return Response.notModified(mdName + "/"
+ maName + " did not exist").build();
} else {
return ok("{ \"success\":\"deleted " + mdName
+ "/" + maName + "\" }").build();
}
} catch (CfmConfigException e) {
log.error("Delete Maintenance Association {} failed",
mdName + "/" + maName, e);
return Response.serverError().entity("{ \"failure\":\"" +
e.toString() + "\" }").build();
}
}
/**
* Create Maintenance Association by MD and MA name.
*
* @param mdName The name of a Maintenance Domain
* @param input A JSON formatted input stream specifying the MA parameters
* @return 200 OK or 500 on error
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createMaintenanceAssociation(@PathParam("md_name") String mdName,
InputStream input) {
log.debug("POST called to Create MA");
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaintenanceDomain md = get(CfmMdService.class)
.getMaintenanceDomain(mdId).get();
if (md == null) {
return Response.serverError().entity("{ \"failure\":\"md "
+ mdName + " does not exist\" }").build();
}
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<MaintenanceAssociation> maCodec =
codec(MaintenanceAssociation.class);
MaintenanceAssociation ma;
try {
ma = ((MaintenanceAssociationCodec) maCodec)
.decode((ObjectNode) cfg, this, mdId.getNameLength());
} catch (Exception e) {
log.error("Create MaintenanceAssociation on MD {} failed", mdName, e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
Boolean alreadyExists = get(CfmMdService.class)
.createMaintenanceAssociation(mdId, ma);
if (alreadyExists) {
return Response.notModified(mdName + "/" + ma.maId() +
" already exists").build();
}
return Response
.created(new URI("md/" + mdName + "/ma/" + ma.maId()))
.entity("{ \"success\":\"" + mdName + "/" + ma.maId() + " created\" }")
.build();
} catch (Exception | CfmConfigException e) {
log.error("Create MaintenanceAssociation on MD {} failed", mdName, e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
}
}

View File

@ -0,0 +1,156 @@
/*
* Copyright 2017-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.cfm.impl;
import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Layer 2 CFM Maintenance Domain web resource.
*/
@Path("md")
public class MdWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
public static final String JSON_NOT_NULL = "JsonNode can not be null";
/**
* Get all Maintenance Domains.
*
* @return 200 OK with a list of MDs and their children
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getMds() {
log.debug("GET called for all MDs");
Collection<MaintenanceDomain> mdMap =
get(CfmMdService.class).getAllMaintenanceDomain();
ArrayNode arrayNode = mapper().createArrayNode();
arrayNode.add(codec(MaintenanceDomain.class).encode(mdMap, this));
return ok(mapper().createObjectNode().set("mds", arrayNode)).build();
}
/**
* Get Maintenance Domain by name.
*
* @param mdName The name of a Maintenance Domain
* @return 200 OK with the details of the MD and its children or 500 on error
*/
@GET
@Path("{md_name}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getMd(@PathParam("md_name") String mdName) {
log.debug("GET called for MD {}", mdName);
try {
MaintenanceDomain md = get(CfmMdService.class)
.getMaintenanceDomain(MdIdCharStr.asMdId(mdName))
.orElseThrow(() -> new IllegalArgumentException(
"MD " + mdName + " not Found"));
ObjectNode result = mapper().createObjectNode();
result.set("md", codec(MaintenanceDomain.class).encode(md, this));
return ok(result.toString()).build();
} catch (IllegalArgumentException e) {
log.error("Get MD {} failed", mdName, e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Delete Maintenance Domain by name.
*
* @param mdName The name of a Maintenance Domain
* @return 200 OK, or 304 if not found or 500 on error
*/
@DELETE
@Path("{md_name}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteMd(@PathParam("md_name") String mdName) {
log.debug("DELETE called for MD {}", mdName);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
boolean deleted = get(CfmMdService.class).deleteMaintenanceDomain(mdId);
if (!deleted) {
return Response.notModified(mdName + " did not exist").build();
} else {
return ok("{ \"success\":\"deleted " + mdName + "\" }").build();
}
} catch (CfmConfigException e) {
log.error("Delete Maintenance Domain {} failed", mdName, e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Create Maintenance Domain.
*
* @param input A JSON formatted input stream specifying the MA parameters
* @return 200 OK, 304 if MD already exists or 500 on error
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createMaintenanceDomain(InputStream input) {
log.debug("POST called to Create MD");
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain md = codec(MaintenanceDomain.class).decode((ObjectNode) cfg, this);
if (get(CfmMdService.class).createMaintenanceDomain(md)) {
return Response.notModified(md.mdId().toString() + " already exists").build();
}
return Response
.created(new URI("md/" + md.mdId()))
.entity("{ \"success\":\"" + md.mdId() + " created\" }")
.build();
} catch (Exception | CfmConfigException e) {
log.error("Create MaintenanceDomain", e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
}
}

View File

@ -0,0 +1,343 @@
/*
* Copyright 2017-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.cfm.impl;
import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onosproject.cfm.web.MepCodec;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Layer 2 CFM Maintenance Association Endpoint (MEP) web resource.
*/
@Path("md/{md_name}/ma/{ma_name}/mep")
public class MepWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* Get all MEPs by MD name, MA name.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @return 200 OK with a list of MEPS or 500 on error
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getAllMepsForMa(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName) {
log.debug("GET all Meps called for MA {}", mdName + "/" + maName);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
Collection<MepEntry> mepCollection = get(CfmMepService.class).getAllMeps(mdId, maId);
ArrayNode an = mapper().createArrayNode();
an.add(codec(MepEntry.class).encode(mepCollection, this));
return ok(mapper().createObjectNode().set("meps", an)).build();
} catch (CfmConfigException e) {
log.error("Get all Meps on {} failed because of exception",
mdName + "/" + maName, e);
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Get MEP by MD name, MA name and Mep Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @return 200 OK with details of the MEP or 500 on error
*/
@GET
@Path("{mep_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getMep(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId) {
log.debug("GET called for MEP {}", mdName + "/" + maName + "/" + mepId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepEntry mepEntry = get(CfmMepService.class)
.getMep(mdId, maId, MepId.valueOf(mepId));
if (mepEntry == null) {
return Response.serverError().entity("{ \"failure\":\"MEP " +
mdName + "/" + maName + "/" + mepId + " not found\" }").build();
}
ObjectNode node = mapper().createObjectNode();
node.set("mep", codec(MepEntry.class).encode(mepEntry, this));
return ok(node).build();
} catch (CfmConfigException e) {
log.error("Get Mep {} failed because of exception",
mdName + "/" + maName + "/" + mepId, e);
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Delete MEP by MD name, MA name and Mep Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepIdShort The Id of the MEP
* @return 200 OK or 304 if not found, or 500 on error
*/
@DELETE
@Path("{mep_id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteMep(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepIdShort) {
log.debug("DELETE called for MEP " + mdName + "/" + maName + "/" + mepIdShort);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
boolean deleted = get(CfmMepService.class)
.deleteMep(mdId, maId, MepId.valueOf(mepIdShort));
if (!deleted) {
return Response.notModified(mdName + "/" + maName + "/" +
mepIdShort + " did not exist").build();
} else {
return ok("{ \"success\":\"deleted " + mdName + "/" + maName +
"/" + mepIdShort + "\" }").build();
}
} catch (CfmConfigException e) {
log.error("Delete Mep {} failed because of exception ",
mdName + "/" + maName + "/" + mepIdShort, e);
return Response.serverError().entity("{ \"failure\":\"" +
e.toString() + "\" }").build();
}
}
/**
* Create MEP with MD name, MA name and Mep Json.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param input A JSON formatted input stream specifying the Mep parameters
* @return 201 Created or 304 if already exists or 500 on error
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createMep(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName, InputStream input) {
log.debug("POST called to Create Mep");
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MaintenanceAssociation ma = get(CfmMdService.class).getMaintenanceAssociation(mdId, maId).get();
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<Mep> mepCodec = codec(Mep.class);
Mep mep = ((MepCodec) mepCodec).decode((ObjectNode) cfg, this, mdName, maName);
Boolean issuccess = get(CfmMepService.class).createMep(mdId, maId, mep);
if (!issuccess) {
return Response.notModified(mdName + "/" + ma.maId() + "/" + mep.mepId() +
" already exists").build();
}
return Response
.created(new URI("md/" + mdName + "/ma/" + ma.maId() + "/mep/" + mep.mepId()))
.entity("{ \"success\":\"mep " + mdName + "/" + ma.maId() + "/" + mep.mepId() + " created\" }")
.build();
} catch (Exception | CfmConfigException e) {
log.error("Create Mep on " + mdName + "/" + maName + " failed because of exception {}",
e.toString());
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
}
/**
* Transmit Loopback on MEP with MD name, MA name and Mep Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepIdShort The id of a MEP belonging to the MA
* @param input A JSON formatted input stream specifying the Mep parameters
* @return 202 Received with success message or 500 on error
*/
@PUT
@Path("{mep_id}/transmit-loopback")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response transmitLoopback(
@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepIdShort,
InputStream input) {
log.debug("PUT called to Transmit Loopback on Mep");
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
MaintenanceAssociation ma = get(CfmMdService.class)
.getMaintenanceAssociation(mdId, maId).get();
MepId mepId = MepId.valueOf(mepIdShort);
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<MepLbCreate> mepLbCreateCodec = codec(MepLbCreate.class);
MepLbCreate lbCreate = mepLbCreateCodec.decode((ObjectNode) cfg, this);
get(CfmMepService.class).transmitLoopback(md.mdId(), ma.maId(), mepId, lbCreate);
} catch (Exception | CfmConfigException e) {
log.error("Transmit Loopback on " + mdName + "/" + maName +
"/{} failed", String.valueOf(mepIdShort), e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
return Response.accepted()
.entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
+ mepId.id() + " started\" }").build();
}
/**
* Abort Loopback on MEP with MD name, MA name and Mep Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepIdShort The id of a MEP belonging to the MA
* @return 202 Received with success message or 500 on error
*/
@PUT
@Path("{mep_id}/abort-loopback")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response abortLoopback(
@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepIdShort) {
log.debug("PUT called to Abort Loopback on Mep");
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
MaintenanceAssociation ma = get(CfmMdService.class)
.getMaintenanceAssociation(mdId, maId).get();
MepId mepId = MepId.valueOf(mepIdShort);
try {
get(CfmMepService.class).abortLoopback(md.mdId(), ma.maId(), mepId);
} catch (CfmConfigException e) {
log.error("Abort Loopback on " + mdName + "/" + maName +
"/{} failed", String.valueOf(mepIdShort), e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
return Response.accepted()
.entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
+ mepId.id() + " aborted\" }").build();
}
/**
* Transmit Linktrace on MEP with MD name, MA name and Mep Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepIdShort The id of a MEP belonging to the MA
* @param input A JSON formatted input stream specifying the Linktrace parameters
* @return 202 Received with success message or 500 on error
*/
@PUT
@Path("{mep_id}/transmit-linktrace")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response transmitLinktrace(
@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepIdShort,
InputStream input) {
log.debug("PUT called to Transmit Linktrace on Mep");
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
MaintenanceAssociation ma = get(CfmMdService.class)
.getMaintenanceAssociation(mdId, maId).get();
MepId mepId = MepId.valueOf(mepIdShort);
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<MepLtCreate> mepLtCreateCodec = codec(MepLtCreate.class);
MepLtCreate ltCreate = mepLtCreateCodec.decode((ObjectNode) cfg, this);
get(CfmMepService.class).transmitLinktrace(md.mdId(), ma.maId(), mepId, ltCreate);
} catch (Exception | CfmConfigException e) {
log.error("Transmit Linktrace on " + mdName + "/" + maName +
"/{} failed", String.valueOf(mepIdShort), e);
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
return Response.accepted()
.entity("{ \"success\":\"Linktrace on MEP " + mdName + "/" + ma.maId() + "/"
+ mepId.id() + " started\" }").build();
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* REST Web Application for CFM.
*/
package org.onosproject.cfm.impl;

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* REST Web Component for CFM and SOAM.
*/
package org.onosproject.cfm;

View File

@ -0,0 +1,123 @@
/*
* Copyright 2017-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.cfm.web;
import static org.onlab.util.Tools.nullIsIllegal;
import java.util.ArrayList;
import java.util.List;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultComponent;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to Component object.
*/
public class ComponentCodec extends JsonCodec<Component> {
private static final String COMPONENT_ID = "component-id";
private static final String COMPONENT = "component";
private static final String VID_LIST = "vid-list";
private static final String TAG_TYPE = "tag-type";
private static final String MHF_CREATION_TYPE = "mhf-creation-type";
private static final String ID_PERMISSION = "id-permission";
@Override
public ObjectNode encode(Component component, CodecContext context) {
ObjectNode node = context.mapper().createObjectNode()
.put(COMPONENT_ID, component.componentId());
node.set(VID_LIST, new VidCodec().encode(component.vidList(), context));
if (component.mhfCreationType() != null) {
node.put(MHF_CREATION_TYPE, component.mhfCreationType().name());
}
if (component.idPermission() != null) {
node.put(ID_PERMISSION, component.idPermission().name());
}
if (component.tagType() != null) {
node.put(TAG_TYPE, component.tagType().name());
}
return (ObjectNode) context.mapper().createObjectNode().set(COMPONENT, node);
}
@Override
public ArrayNode encode(Iterable<Component> components, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
components.forEach(component -> {
an.add(encode(component, context));
});
return an;
}
@Override
public Component decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode componentNode = json.get(COMPONENT);
int componentId = nullIsIllegal(componentNode.get(COMPONENT_ID),
"component-id is required").asInt();
Component.ComponentBuilder componentBuilder =
DefaultComponent.builder(componentId);
List<VlanId> vidList = (new VidCodec()).decode((ArrayNode)
nullIsIllegal(componentNode.get(VID_LIST), "vid-list is required"), context);
if (vidList == null || vidList.size() < 1) {
throw new IllegalArgumentException("A least one VID is required in component: " + componentId);
}
for (VlanId vid:vidList) {
componentBuilder = componentBuilder.addToVidList(vid);
}
if (componentNode.get(TAG_TYPE) != null) {
componentBuilder = componentBuilder
.tagType(Component.TagType.valueOf(
componentNode.get(TAG_TYPE).asText()));
}
if (componentNode.get(MHF_CREATION_TYPE) != null) {
componentBuilder = componentBuilder
.mhfCreationType(Component.MhfCreationType.valueOf(
componentNode.get(MHF_CREATION_TYPE).asText()));
}
if (componentNode.get(ID_PERMISSION) != null) {
componentBuilder = componentBuilder
.idPermission(Component.IdPermissionType.valueOf(
componentNode.get(ID_PERMISSION).asText()));
}
return componentBuilder.build();
}
@Override
public List<Component> decode(ArrayNode json, CodecContext context) {
List<Component> componentList = new ArrayList<>();
json.forEach(node -> componentList.add(decode((ObjectNode) node, context)));
return componentList;
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2017-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.cfm.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.FngAddress;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
/**
* Encode and decode to/from JSON to FngAddress object.
*/
public class FngAddressCodec extends JsonCodec<FngAddress> {
@Override
public ObjectNode encode(FngAddress fngAddress, CodecContext context) {
checkNotNull(fngAddress, "FngAddress cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("address-type", fngAddress.addressType().name());
if (fngAddress.addressType().equals(Mep.FngAddressType.IPV4) ||
fngAddress.addressType().equals(Mep.FngAddressType.IPV6)) {
result.put("ip-address", fngAddress.ipAddress().toString());
}
return result;
}
@Override
public FngAddress decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode node = json.get("fng-address");
String addressType = nullIsIllegal(node.get("address-type"),
"address type is required").asText();
Mep.FngAddressType type = Mep.FngAddressType.valueOf(addressType.toUpperCase());
JsonNode ipAddressNode = node.get("ipAddress");
switch (type) {
case IPV4:
return FngAddress.ipV4Address(Ip4Address.valueOf(ipAddressNode.asText()));
case IPV6:
return FngAddress.ipV6Address(Ip6Address.valueOf(ipAddressNode.asText()));
case NOT_TRANSMITTED:
return FngAddress.notTransmitted(IpAddress.valueOf(ipAddressNode.asText()));
case NOT_SPECIFIED:
default:
return FngAddress.notSpecified();
}
}
}

View File

@ -0,0 +1,146 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import java.util.List;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation.CcmInterval;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation.MaBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to MaintenanceAssociation object.
*/
public class MaintenanceAssociationCodec extends JsonCodec<MaintenanceAssociation> {
private static final String MA_NAME_TYPE = "maNameType";
private static final String MA_NUMERIC_ID = "maNumericId";
private static final String MA_NAME = "maName";
private static final String CCM_INTERVAL = "ccm-interval";
private static final String COMPONENT_LIST = "component-list";
private static final String RMEP_LIST = "rmep-list";
private static final String MA = "ma";
@Override
public ObjectNode encode(MaintenanceAssociation ma, CodecContext context) {
checkNotNull(ma, "Maintenance Association cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(MA_NAME, ma.maId().toString())
.put(MA_NAME_TYPE, ma.maId().nameType().name());
if (ma.maNumericId() > 0) {
result = result.put(MA_NUMERIC_ID, ma.maNumericId());
}
if (ma.ccmInterval() != null) {
result = result.put(CCM_INTERVAL, ma.ccmInterval().name());
}
result.set(COMPONENT_LIST, new ComponentCodec().encode(ma.componentList(), context));
result.set(RMEP_LIST, new RMepCodec().encode(ma.remoteMepIdList(), context));
return result;
}
public MaintenanceAssociation decode(ObjectNode json, CodecContext context, int mdNameLen) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode maNode = json.get(MA);
String maName = nullIsIllegal(maNode.get(MA_NAME), "maName is required").asText();
String maNameType = MaIdShort.MaIdType.CHARACTERSTRING.name();
if (maNode.get(MA_NAME_TYPE) != null) {
maNameType = maNode.get(MA_NAME_TYPE).asText();
}
try {
MaIdShort maId = null;
MaIdShort.MaIdType maIdType = MaIdShort.MaIdType.valueOf(maNameType);
switch (maIdType) {
case PRIMARYVID:
maId = MaIdPrimaryVid.asMaId(maName);
break;
case TWOOCTET:
maId = MaId2Octet.asMaId(maName);
break;
case RFC2685VPNID:
maId = MaIdRfc2685VpnId.asMaIdHex(maName);
break;
case ICCY1731:
maId = MaIdIccY1731.asMaId(maName);
break;
case CHARACTERSTRING:
default:
maId = MaIdCharStr.asMaId(maName);
}
MaBuilder builder =
DefaultMaintenanceAssociation.builder(maId, mdNameLen);
JsonNode maNumericIdNode = maNode.get(MA_NUMERIC_ID);
if (maNumericIdNode != null) {
short mdNumericId = (short) maNumericIdNode.asInt();
builder = builder.maNumericId(mdNumericId);
}
if (maNode.get(CCM_INTERVAL) != null) {
builder.ccmInterval(CcmInterval.valueOf(maNode.get(CCM_INTERVAL).asText()));
}
List<Component> componentList = (new ComponentCodec()).decode((ArrayNode)
nullIsIllegal(maNode.get(COMPONENT_LIST),
"component-list is required"), context);
for (Component component:componentList) {
builder = builder.addToComponentList(component);
}
List<MepId> remoteMeps = (new RMepCodec()).decode(
(ArrayNode) nullIsIllegal(maNode.get(RMEP_LIST), "rmep-list is required"), context);
for (MepId remoteMep:remoteMeps) {
builder = builder.addToRemoteMepIdList(remoteMep);
}
return builder.build();
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public ArrayNode encode(Iterable<MaintenanceAssociation> maEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
maEntities.forEach(ma -> an.add(encode(ma, context)));
return an;
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain.MdLevel;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to MaintenanceDomain object.
*/
public class MaintenanceDomainCodec extends JsonCodec<MaintenanceDomain> {
private static final String MD_LEVEL = "mdLevel";
private static final String MD_NUMERIC_ID = "mdNumericId";
private static final String MD = "md";
private static final String MD_NAME = "mdName";
private static final String MD_NAME_TYPE = "mdNameType";
public MaintenanceDomainCodec() {
super();
}
@Override
public ObjectNode encode(MaintenanceDomain md, CodecContext context) {
checkNotNull(md, "Maintenance Domain cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(MD_NAME, md.mdId().toString())
.put(MD_NAME_TYPE, md.mdId().nameType().name())
.put(MD_LEVEL, md.mdLevel().name());
if (md.mdNumericId() > 0) {
result = result.put(MD_NUMERIC_ID, md.mdNumericId());
}
result.set("maList",
new MaintenanceAssociationCodec()
.encode(md.maintenanceAssociationList(), context));
return result;
}
@Override
public MaintenanceDomain decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode mdNode = json.get(MD);
String mdName = nullIsIllegal(mdNode.get(MD_NAME), "mdName is required").asText();
String mdNameType = MdId.MdNameType.CHARACTERSTRING.name();
if (mdNode.get(MD_NAME_TYPE) != null) {
mdNameType = mdNode.get(MD_NAME_TYPE).asText();
}
try {
MdId mdId = null;
MdId.MdNameType nameType =
MdId.MdNameType.valueOf(mdNameType);
switch (nameType) {
case DOMAINNAME:
mdId = MdIdDomainName.asMdId(mdName);
break;
case MACANDUINT:
mdId = MdIdMacUint.asMdId(mdName);
break;
case NONE:
mdId = MdIdNone.asMdId();
break;
case CHARACTERSTRING:
default:
mdId = MdIdCharStr.asMdId(mdName);
}
MaintenanceDomain.MdBuilder builder = DefaultMaintenanceDomain.builder(mdId);
JsonNode mdLevelNode = mdNode.get(MD_LEVEL);
if (mdLevelNode != null) {
MdLevel mdLevel = MdLevel.valueOf(mdLevelNode.asText());
builder = builder.mdLevel(mdLevel);
}
JsonNode mdNumericIdNode = mdNode.get(MD_NUMERIC_ID);
if (mdNumericIdNode != null) {
short mdNumericId = (short) mdNumericIdNode.asInt();
builder = builder.mdNumericId(mdNumericId);
}
return builder.build();
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public ArrayNode encode(Iterable<MaintenanceDomain> mdEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
mdEntities.forEach(md -> an.add(encode(md, context)));
return an;
}
}

View File

@ -0,0 +1,163 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepDirection;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.time.Duration;
/**
* Encode and decode to/from JSON to Mep object.
*/
public class MepCodec extends JsonCodec<Mep> {
private static final String ADMINISTRATIVE_STATE = "administrative-state";
private static final String PRIMARY_VID = "primary-vid";
private static final String CCM_LTM_PRIORITY = "ccm-ltm-priority";
private static final String CCI_ENABLED = "cci-enabled";
private static final String FNG_ADDRESS = "fng-address";
private static final String LOWEST_FAULT_PRIORITY_DEFECT = "lowest-fault-priority-defect";
private static final String DEFECT_PRESENT_TIME = "defect-present-time";
private static final String DEFECT_ABSENT_TIME = "defect-absent-time";
public Mep decode(ObjectNode json, CodecContext context, String
mdName, String maName) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode mepNode = json.get("mep");
int mepId = Integer.parseInt(
nullIsIllegal(mepNode.get("mepId"), "mepId is required").asText());
DeviceId deviceId = DeviceId.deviceId(
nullIsIllegal(mepNode.get("deviceId"), "deviceId is required")
.asText());
PortNumber port = PortNumber
.portNumber(Long.parseLong(
nullIsIllegal(mepNode.get("port"), "port is required")
.asText()));
MepDirection direction = MepDirection.valueOf(
nullIsIllegal(mepNode.get("direction"), "direction is required").
asText());
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepBuilder mepBuilder = DefaultMep
.builder(MepId.valueOf((short) mepId),
deviceId, port, direction, mdId, maId);
if (mepNode.get(PRIMARY_VID) != null) {
mepBuilder.primaryVid(VlanId.vlanId(
(short) mepNode.get(PRIMARY_VID).asInt(0)));
}
if (mepNode.get(ADMINISTRATIVE_STATE) != null) {
mepBuilder.administrativeState(mepNode.get(ADMINISTRATIVE_STATE)
.asBoolean());
}
if (mepNode.get(CCM_LTM_PRIORITY) != null) {
mepBuilder.ccmLtmPriority(
Priority.values()[mepNode.get(CCM_LTM_PRIORITY).asInt(0)]);
}
if (mepNode.get(CCI_ENABLED) != null) {
mepBuilder.cciEnabled(mepNode.get(CCI_ENABLED).asBoolean());
}
if (mepNode.get(LOWEST_FAULT_PRIORITY_DEFECT) != null) {
mepBuilder.lowestFaultPriorityDefect(
Mep.LowestFaultDefect.values()[mepNode.get(LOWEST_FAULT_PRIORITY_DEFECT).asInt()]);
}
if (mepNode.get(DEFECT_ABSENT_TIME) != null) {
mepBuilder.defectAbsentTime(
Duration.parse(mepNode.get(DEFECT_ABSENT_TIME).asText()));
}
if (mepNode.get(DEFECT_PRESENT_TIME) != null) {
mepBuilder.defectPresentTime(
Duration.parse(mepNode.get(DEFECT_PRESENT_TIME).asText()));
}
if (mepNode.get(FNG_ADDRESS) != null) {
mepBuilder.fngAddress((new FngAddressCodec())
.decode((ObjectNode) mepNode, context));
}
return mepBuilder.build();
} catch (CfmConfigException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public ObjectNode encode(Mep mep, CodecContext context) {
checkNotNull(mep, "Mep cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("mepId", mep.mepId().id())
.put("deviceId", mep.deviceId().toString())
.put("port", mep.port().toLong())
.put("direction", mep.direction().name())
.put("mdName", mep.mdId().toString())
.put("maName", mep.maId().toString())
.put(ADMINISTRATIVE_STATE, mep.administrativeState())
.put(CCI_ENABLED, mep.cciEnabled());
if (mep.ccmLtmPriority() != null) {
result.put(CCM_LTM_PRIORITY, mep.ccmLtmPriority().ordinal());
}
if (mep.primaryVid() != null) {
result.put(PRIMARY_VID, mep.primaryVid().toShort());
}
if (mep.fngAddress() != null) {
result.put(FNG_ADDRESS, new FngAddressCodec().encode(mep.fngAddress(), context));
}
if (mep.lowestFaultPriorityDefect() != null) {
result.put(LOWEST_FAULT_PRIORITY_DEFECT, mep.lowestFaultPriorityDefect().ordinal());
}
if (mep.defectPresentTime() != null) {
result.put(DEFECT_PRESENT_TIME, mep.defectPresentTime().toString());
}
if (mep.defectAbsentTime() != null) {
result.put(DEFECT_ABSENT_TIME, mep.defectAbsentTime().toString());
}
return result;
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Iterator;
import java.util.Map.Entry;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to MepEntry object.
*/
public class MepEntryCodec extends JsonCodec<MepEntry> {
@Override
public ObjectNode encode(MepEntry mepEntry, CodecContext context) {
checkNotNull(mepEntry, "Mep cannot be null");
ObjectNode result = context.mapper().createObjectNode();
//Get the common attributes
Mep mep = (Mep) mepEntry;
ObjectNode mepAttrs = new MepCodec().encode(mep, context);
Iterator<Entry<String, JsonNode>> elements = mepAttrs.fields();
while (elements.hasNext()) {
Entry<String, JsonNode> element = elements.next();
result.set(element.getKey(), element.getValue());
}
if (mepEntry.macAddress() != null) {
result.put("macAddress", mepEntry.macAddress().toString());
}
if (mepEntry.loopbackAttributes() != null) {
result.set("loopback", new MepLbEntryCodec()
.encode(mepEntry.loopbackAttributes(), context));
}
if (mepEntry.activeRemoteMepList() != null) {
result.set("remoteMeps", new RemoteMepEntryCodec()
.encode(mepEntry.activeRemoteMepList(), context));
}
if (mepEntry.activeErrorCcmDefect()) {
result.put("activeErrorCcmDefect", true);
}
if (mepEntry.activeMacStatusDefect()) {
result.put("activeMacStatusDefect", true);
}
if (mepEntry.activeRdiCcmDefect()) {
result.put("activeRdiCcmDefect", true);
}
if (mepEntry.activeRemoteCcmDefect()) {
result.put("activeRemoteCcmDefect", true);
}
if (mepEntry.activeXconCcmDefect()) {
result.put("activeXconCcmDefect", true);
}
return result;
}
@Override
public ArrayNode encode(Iterable<MepEntry> mepEntryEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
if (mepEntryEntities != null) {
mepEntryEntities.forEach(mepEntry -> an.add(encode(mepEntry, context)));
}
return an;
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright 2017-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.cfm.web;
import org.onlab.packet.MacAddress;
import org.onlab.util.HexString;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to MepLbCreate object.
*/
public class MepLbCreateCodec extends JsonCodec<MepLbCreate> {
public static final String NUMBER_MESSAGES = "numberMessages";
public static final String REMOTE_MEP_ID = "remoteMepId";
public static final String REMOTE_MEP_MAC = "remoteMepMac";
public static final String DATA_TLV_HEX = "dataTlvHex";
public static final String VLAN_DROP_ELIGIBLE = "vlanDropEligible";
public static final String VLAN_PRIORITY = "vlanPriority";
public static final String LOOPBACK = "loopback";
@Override
public ObjectNode encode(MepLbCreate mepLbCreate, CodecContext context) {
checkNotNull(mepLbCreate, "Mep Lb Create cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(NUMBER_MESSAGES, mepLbCreate.numberMessages());
if (mepLbCreate.remoteMepId() != null) {
result.put(REMOTE_MEP_ID, mepLbCreate.remoteMepId().value());
} else {
result.put(REMOTE_MEP_MAC, mepLbCreate.remoteMepAddress().toString());
}
if (mepLbCreate.dataTlvHex() != null) {
result.put(DATA_TLV_HEX, mepLbCreate.dataTlvHex());
}
if (mepLbCreate.vlanDropEligible() != null) {
result.put(VLAN_DROP_ELIGIBLE, mepLbCreate.vlanDropEligible());
}
if (mepLbCreate.vlanPriority() != null) {
result.put(VLAN_PRIORITY, mepLbCreate.vlanPriority().ordinal());
}
return result;
}
@Override
public MepLbCreate decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode loopbackNode = json.get(LOOPBACK);
JsonNode remoteMepIdNode = loopbackNode.get(REMOTE_MEP_ID);
JsonNode remoteMepMacNode = loopbackNode.get(REMOTE_MEP_MAC);
MepLbCreate.MepLbCreateBuilder lbCreateBuilder = null;
if (remoteMepIdNode != null) {
MepId remoteMepId = MepId.valueOf((short) remoteMepIdNode.asInt());
lbCreateBuilder = DefaultMepLbCreate.builder(remoteMepId);
} else if (remoteMepMacNode != null) {
MacAddress remoteMepMac = MacAddress.valueOf(
remoteMepMacNode.asText());
lbCreateBuilder = DefaultMepLbCreate.builder(remoteMepMac);
} else {
throw new IllegalArgumentException(
"Either a remoteMepId or a remoteMepMac");
}
JsonNode numMessagesNode = loopbackNode.get(NUMBER_MESSAGES);
if (numMessagesNode != null) {
int numMessages = numMessagesNode.asInt();
lbCreateBuilder.numberMessages(numMessages);
}
JsonNode vlanDropEligibleNode = loopbackNode.get(VLAN_DROP_ELIGIBLE);
if (vlanDropEligibleNode != null) {
boolean vlanDropEligible = vlanDropEligibleNode.asBoolean();
lbCreateBuilder.vlanDropEligible(vlanDropEligible);
}
JsonNode vlanPriorityNode = loopbackNode.get(VLAN_PRIORITY);
if (vlanPriorityNode != null) {
short vlanPriority = (short) vlanPriorityNode.asInt();
lbCreateBuilder.vlanPriority(Priority.values()[vlanPriority]);
}
JsonNode dataTlvHexNode = loopbackNode.get(DATA_TLV_HEX);
if (dataTlvHexNode != null) {
String dataTlvHex = loopbackNode.get(DATA_TLV_HEX).asText();
if (!dataTlvHex.isEmpty()) {
lbCreateBuilder.dataTlv(HexString.fromHexString(dataTlvHex));
}
}
return lbCreateBuilder.build();
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to MepLbEntry object.
*/
public class MepLbEntryCodec extends JsonCodec<MepLbEntry> {
@Override
public ObjectNode encode(MepLbEntry mepLbEntry, CodecContext context) {
checkNotNull(mepLbEntry, "Mep Lb Entry cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("nextLbmIdentifier", mepLbEntry.nextLbmIdentifier())
.put("countLbrTransmitted", mepLbEntry.countLbrTransmitted())
.put("countLbrReceived", mepLbEntry.countLbrReceived())
.put("countLbrValidInOrder", mepLbEntry.countLbrValidInOrder())
.put("countLbrValidOutOfOrder", mepLbEntry.countLbrValidOutOfOrder())
.put("countLbrMacMisMatch", mepLbEntry.countLbrMacMisMatch());
return result;
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright 2017-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.cfm.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.MacAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import java.util.BitSet;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to MepLtCreate object.
*/
public class MepLtCreateCodec extends JsonCodec<MepLtCreate> {
private static final String REMOTE_MEP_ID = "remoteMepId";
private static final String REMOTE_MEP_MAC = "remoteMepMac";
private static final String DEFAULT_TTL = "defaultTtl";
private static final String TRANSMIT_LTM_FLAGS = "transmitLtmFlags";
private static final String LINKTRACE = "linktrace";
private static final String USE_FDB_ONLY = "use-fdb-only";
@Override
public ObjectNode encode(MepLtCreate mepLtCreate, CodecContext context) {
checkNotNull(mepLtCreate, "Mep Lt Create cannot be null");
ObjectNode result = context.mapper().createObjectNode();
if (mepLtCreate.remoteMepId() != null) {
result.put(REMOTE_MEP_ID, mepLtCreate.remoteMepId().value());
} else {
result.put(REMOTE_MEP_MAC, mepLtCreate.remoteMepAddress().toString());
}
if (mepLtCreate.defaultTtl() != null) {
result.put(DEFAULT_TTL, mepLtCreate.defaultTtl());
}
if (mepLtCreate.transmitLtmFlags() != null) {
result.put(TRANSMIT_LTM_FLAGS,
mepLtCreate.transmitLtmFlags().get(0) ? USE_FDB_ONLY : "");
}
return result;
}
@Override
public MepLtCreate decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode linktraceNode = json.get(LINKTRACE);
JsonNode remoteMepIdNode = linktraceNode.get(REMOTE_MEP_ID);
JsonNode remoteMepMacNode = linktraceNode.get(REMOTE_MEP_MAC);
MepLtCreate.MepLtCreateBuilder ltCreateBuilder = null;
if (remoteMepIdNode != null) {
MepId remoteMepId = MepId.valueOf((short) remoteMepIdNode.asInt());
ltCreateBuilder = DefaultMepLtCreate.builder(remoteMepId);
} else if (remoteMepMacNode != null) {
MacAddress remoteMepMac = MacAddress.valueOf(
remoteMepMacNode.asText());
ltCreateBuilder = DefaultMepLtCreate.builder(remoteMepMac);
} else {
throw new IllegalArgumentException(
"Either a remoteMepId or a remoteMepMac");
}
JsonNode defaultTtlNode = linktraceNode.get(DEFAULT_TTL);
if (defaultTtlNode != null) {
short defaultTtl = (short) defaultTtlNode.asInt();
ltCreateBuilder.defaultTtl(defaultTtl);
}
JsonNode transmitLtmFlagsNode = linktraceNode.get(TRANSMIT_LTM_FLAGS);
if (transmitLtmFlagsNode != null) {
if (transmitLtmFlagsNode.asText().isEmpty()) {
ltCreateBuilder.transmitLtmFlags(BitSet.valueOf(new long[]{0}));
} else if (transmitLtmFlagsNode.asText().equals(USE_FDB_ONLY)) {
ltCreateBuilder.transmitLtmFlags(BitSet.valueOf(new long[]{1}));
} else {
throw new IllegalArgumentException("Expecting value 'use-fdb-only' " +
"or '' for " + TRANSMIT_LTM_FLAGS);
}
}
return ltCreateBuilder.build();
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2017-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.cfm.web;
import static org.onlab.util.Tools.nullIsIllegal;
import java.util.ArrayList;
import java.util.List;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to RMep object.
*/
public class RMepCodec extends JsonCodec<MepId> {
@Override
public ObjectNode encode(MepId rmep, CodecContext context) {
return context.mapper().createObjectNode().put("rmep", rmep.id());
}
@Override
public ArrayNode encode(Iterable<MepId> rmeps, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
rmeps.forEach(rmep -> {
an.add(encode(rmep, context));
});
return an;
}
@Override
public MepId decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode vidNode = json.get("rmep");
return MepId.valueOf(
nullIsIllegal((short) vidNode.asInt(), "rmep is required"));
}
@Override
public List<MepId> decode(ArrayNode json, CodecContext context) {
List<MepId> rmepList = new ArrayList<>();
json.forEach(node -> rmepList.add(decode((ObjectNode) node, context)));
return rmepList;
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2017-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.cfm.web;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to RemoteMepEntry object.
*/
public class RemoteMepEntryCodec extends JsonCodec<RemoteMepEntry> {
@Override
public ObjectNode encode(RemoteMepEntry remoteMepEntry, CodecContext context) {
checkNotNull(remoteMepEntry, "Mep cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("remoteMepId", remoteMepEntry.remoteMepId().toString())
.put("remoteMepState", remoteMepEntry.state().name())
.put("rdi", remoteMepEntry.rdi());
if (remoteMepEntry.failedOrOkTime() != null) {
result = result.put("failedOrOkTime",
remoteMepEntry.failedOrOkTime().toString());
}
if (remoteMepEntry.macAddress() != null) {
result = result.put("macAddress", remoteMepEntry.macAddress().toString());
}
if (remoteMepEntry.portStatusTlvType() != null) {
result = result.put("portStatusTlvType",
remoteMepEntry.portStatusTlvType().name());
}
if (remoteMepEntry.interfaceStatusTlvType() != null) {
result = result.put("interfaceStatusTlvType",
remoteMepEntry.interfaceStatusTlvType().name());
}
if (remoteMepEntry.senderIdTlvType() != null) {
result = result.put("senderIdTlvType",
remoteMepEntry.senderIdTlvType().name());
}
return result;
}
@Override
public ArrayNode encode(Iterable<RemoteMepEntry> remoteMepEntries,
CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
remoteMepEntries.forEach(remoteMepEntry ->
an.add(encode(remoteMepEntry, context)));
return an;
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright 2017-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.cfm.web;
import static org.onlab.util.Tools.nullIsIllegal;
import java.util.ArrayList;
import java.util.List;
import org.onlab.packet.VlanId;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to Vid object.
*/
public class VidCodec extends JsonCodec<VlanId> {
@Override
public ObjectNode encode(VlanId vid, CodecContext context) {
return context.mapper().createObjectNode().put("vid", vid.toString());
}
@Override
public ArrayNode encode(Iterable<VlanId> vids, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
vids.forEach(vid -> {
an.add(encode(vid, context));
});
return an;
}
@Override
public VlanId decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode vidNode = json.get("vid");
int vid = (nullIsIllegal(vidNode.asInt(), "vid is required"));
if (vid < 0 || vid > 4095) {
throw new IllegalArgumentException("VID values must be between 0 and 4095");
}
return VlanId.vlanId((short) vid);
}
@Override
public List<VlanId> decode(ArrayNode json, CodecContext context) {
List<VlanId> vidList = new ArrayList<>();
json.forEach(node -> vidList.add(decode((ObjectNode) node, context)));
return vidList;
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* Codecs for converting CFM objects to and from JSON.
*/
package org.onosproject.cfm.web;

View File

@ -0,0 +1,257 @@
/*
* Copyright 2017-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.soam.impl;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Layer 2 SOAM Delay Measurement web resource.
*/
@Path("md/{md_name}/ma/{ma_name}/mep/{mep_id}/dm")
public class DmWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* Get all DMs for a Mep.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The ID of a Mep belonging to the MA
* @return 200 OK with a list of DMs or 500 on error
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getAllDmsForMep(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId) {
log.debug("GET all DMs called for MEP {}", mdName + "/" + maName + "/" + mepId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
Collection<DelayMeasurementEntry> dmCollection =
get(SoamService.class).getAllDms(mdId, maId, mepIdObj);
ArrayNode an = mapper().createArrayNode();
an.add(codec(DelayMeasurementEntry.class).encode(dmCollection, this));
return ok(mapper().createObjectNode().set("dms", an)).build();
} catch (CfmConfigException | SoamConfigException e) {
log.error("Get DM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Get DM by MD name, MA name, Mep Id and Dm id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param dmId The Id of the DM
* @return 200 OK with details of the DM or 500 on error
*/
@GET
@Path("{dm_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getDm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId, @PathParam("dm_id") int dmId) {
log.debug("GET called for DM {}", mdName + "/" + maName + "/" + mepId + "/" + dmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId dmIdObj = SoamId.valueOf(dmId);
DelayMeasurementEntry dm = get(SoamService.class)
.getDm(mdId, maId, mepIdObj, dmIdObj);
if (dm == null) {
return Response.serverError().entity("{ \"failure\":\"DM " +
mdName + "/" + maName + "/" + mepId + "/" + dmId + " not found\" }").build();
}
ObjectNode node = mapper().createObjectNode();
node.set("dm", codec(DelayMeasurementEntry.class).encode(dm, this));
return ok(node).build();
} catch (CfmConfigException | SoamConfigException e) {
log.error("Get DM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + dmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Abort DM by MD name, MA name, Mep Id and DM Id.
* In the API the measurement is aborted, and not truly deleted. It still
* remains so that its results may be read. Depending on the device it will
* get overwritten on the creation of subsequent measurements.
* Use clear stats to delete old results
* measurements.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param dmId The Id of the DM
* @return 200 OK or 304 if not found, or 500 on error
*/
@DELETE
@Path("{dm_id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response abortDm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId,
@PathParam("dm_id") int dmId) {
log.debug("DELETE called for DM {}", mdName + "/" + maName + "/" + mepId + "/" + dmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId dmIdObj = SoamId.valueOf(dmId);
get(SoamService.class).abortDm(mdId, maId, mepIdObj, dmIdObj);
return ok("{ \"success\":\"deleted (aborted) " + mdName + "/" + maName +
"/" + mepId + "/" + dmId + "\" }").build();
} catch (CfmConfigException e) {
log.error("Delete (abort) DM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + dmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Create DM with MD name, MA name, Mep id and DM Json.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP belonging to the MEP
* @param input A JSON formatted input stream specifying the DM parameters
* @return 201 Created or 304 if already exists or 500 on error
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createDm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId, InputStream input) {
log.debug("POST called to Create Dm");
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
Mep mep = get(CfmMepService.class).getMep(mdId, maId, mepIdObj);
if (mep == null) {
return Response.serverError().entity("{ \"failure\":\"mep " +
mdName + "/" + maName + "/" + mepId + " does not exist\" }").build();
}
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<DelayMeasurementCreate> dmCodec = codec(DelayMeasurementCreate.class);
DelayMeasurementCreate dm = dmCodec.decode((ObjectNode) cfg, this);
get(SoamService.class).createDm(mdId, maId, mepIdObj, dm);
return Response
.created(new URI("md/" + mdName + "/ma/" + maName + "/mep/" +
mepId + "/dm"))
.entity("{ \"success\":\"dm " + mdName + "/" + maName + "/" +
mepId + " created\" }")
.build();
} catch (CfmConfigException | SoamConfigException | IllegalArgumentException |
IOException | URISyntaxException e) {
log.error("Create DM on " + mdName + "/" + maName + "/" + mepId +
" failed because of exception {}", e.toString());
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
}
/**
* Clear DM history stats by MD name, MA name, Mep Id and DM Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param dmId The Id of the DM
* @return 200 OK or 304 if not found, or 500 on error
*/
@PUT
@Path("{dm_id}/clear-history")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response clearDmHistory(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId,
@PathParam("dm_id") int dmId) {
log.debug("clear-history called for DM {}", mdName + "/" + maName +
"/" + mepId + "/" + dmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId dmIdObj = SoamId.valueOf(dmId);
get(SoamService.class).clearDelayHistoryStats(mdId, maId, mepIdObj, dmIdObj);
return ok("{ \"success\":\"cleared DM history stats for " +
mdName + "/" + maName + "/" + mepId + "/" + dmId + "\" }").build();
} catch (CfmConfigException e) {
log.error("Clear history stats for DM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + dmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" +
e.toString() + "\" }").build();
}
}
}

View File

@ -0,0 +1,256 @@
/*
* Copyright 2017-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.soam.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
/**
* Layer 2 SOAM Loss Measurement web resource.
*/
@Path("md/{md_name}/ma/{ma_name}/mep/{mep_id}/lm")
public class LmWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* Get all LMs for a Mep.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The ID of a Mep belonging to the MA
* @return 200 OK with a list of LMs or 500 on error
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getAllLmsForMep(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId) {
log.debug("GET all LMs called for MEP {}", mdName + "/" + maName + "/" + mepId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
Collection<LossMeasurementEntry> lmCollection =
get(SoamService.class).getAllLms(mdId, maId, mepIdObj);
ArrayNode an = mapper().createArrayNode();
an.add(codec(LossMeasurementEntry.class).encode(lmCollection, this));
return ok(mapper().createObjectNode().set("lms", an)).build();
} catch (CfmConfigException | SoamConfigException e) {
log.error("Get LM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Get LM by MD name, MA name, Mep Id and Dm id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param lmId The Id of the LM
* @return 200 OK with details of the LM or 500 on error
*/
@GET
@Path("{lm_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response getLm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId, @PathParam("lm_id") int lmId) {
log.debug("GET called for LM {}", mdName + "/" + maName + "/" + mepId + "/" + lmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId lmIdObj = SoamId.valueOf(lmId);
LossMeasurementEntry lm = get(SoamService.class)
.getLm(mdId, maId, mepIdObj, lmIdObj);
if (lm == null) {
return Response.serverError().entity("{ \"failure\":\"LM " +
mdName + "/" + maName + "/" + mepId + "/" + lmId + " not found\" }").build();
}
ObjectNode node = mapper().createObjectNode();
node.set("lm", codec(LossMeasurementEntry.class).encode(lm, this));
return ok(node).build();
} catch (CfmConfigException | SoamConfigException e) {
log.error("Get LM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + lmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Abort LM by MD name, MA name, Mep Id and LM Id.
* In the API the measurement is aborted, and not truly deleted. It still
* remains so that its results may be read. Depending on the device it will
* get overwritten on the creation of subsequent measurements.
* Use clear stats to delete old results measurements.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param lmId The Id of the LM
* @return 200 OK or 304 if not found, or 500 on error
*/
@DELETE
@Path("{lm_id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response abortLm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId,
@PathParam("lm_id") int lmId) {
log.debug("DELETE called for LM {}", mdName + "/" + maName + "/" + mepId + "/" + lmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId lmIdObj = SoamId.valueOf(lmId);
get(SoamService.class).abortLm(mdId, maId, mepIdObj, lmIdObj);
return ok("{ \"success\":\"deleted (aborted) " + mdName + "/" + maName +
"/" + mepId + "/" + lmId + "\" }").build();
} catch (CfmConfigException e) {
log.error("Delete (abort) LM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + lmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
}
}
/**
* Create LM with MD name, MA name, Mep id and LM Json.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP belonging to the MEP
* @param input A JSON formatted input stream specifying the LM parameters
* @return 201 Created or 304 if already exists or 500 on error
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createLm(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId, InputStream input) {
log.debug("POST called to Create Lm");
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
Mep mep = get(CfmMepService.class).getMep(mdId, maId, mepIdObj);
if (mep == null) {
return Response.serverError().entity("{ \"failure\":\"mep " +
mdName + "/" + maName + "/" + mepId + " does not exist\" }").build();
}
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonCodec<LossMeasurementCreate> lmCodec = codec(LossMeasurementCreate.class);
LossMeasurementCreate lm = lmCodec.decode((ObjectNode) cfg, this);
get(SoamService.class).createLm(mdId, maId, mepIdObj, lm);
return Response
.created(new URI("md/" + mdName + "/ma/" + maName + "/mep/" +
mepId + "/lm"))
.entity("{ \"success\":\"lm " + mdName + "/" + maName + "/" +
mepId + " created\" }")
.build();
} catch (CfmConfigException | SoamConfigException | IllegalArgumentException |
IOException | URISyntaxException e) {
log.error("Create LM on " + mdName + "/" + maName + "/" + mepId +
" failed because of exception {}", e.toString());
return Response.serverError()
.entity("{ \"failure\":\"" + e.toString() + "\" }")
.build();
}
}
/**
* Clear LM history stats by MD name, MA name, Mep Id and LM Id.
*
* @param mdName The name of a Maintenance Domain
* @param maName The name of a Maintenance Association belonging to the MD
* @param mepId The Id of the MEP
* @param lmId The Id of the LM
* @return 200 OK or 304 if not found, or 500 on error
*/
@PUT
@Path("{lm_id}/clear-history")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response clearLmHistory(@PathParam("md_name") String mdName,
@PathParam("ma_name") String maName,
@PathParam("mep_id") short mepId,
@PathParam("lm_id") int lmId) {
log.debug("clear-history called for LM {}", mdName + "/" + maName +
"/" + mepId + "/" + lmId);
try {
MdId mdId = MdIdCharStr.asMdId(mdName);
MaIdShort maId = MaIdCharStr.asMaId(maName);
MepId mepIdObj = MepId.valueOf(mepId);
SoamId lmIdObj = SoamId.valueOf(lmId);
get(SoamService.class).clearDelayHistoryStats(mdId, maId, mepIdObj, lmIdObj);
return ok("{ \"success\":\"cleared LM history stats for " +
mdName + "/" + maName + "/" + mepId + "/" + lmId + "\" }").build();
} catch (CfmConfigException e) {
log.error("Clear history stats for LM {} failed because of exception {}",
mdName + "/" + maName + "/" + mepId + "/" + lmId, e.toString());
return Response.serverError().entity("{ \"failure\":\"" +
e.toString() + "\" }").build();
}
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* REST Web Application for SOAM.
*/
package org.onosproject.soam.impl;

View File

@ -0,0 +1,205 @@
/*
* Copyright 2017-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.soam.web;
import static com.google.common.base.Preconditions.checkNotNull;
import java.time.Duration;
import java.util.Map;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStat;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to DelayMeasurementStat object.
*/
public class DelayMeasurementStatCodec extends JsonCodec<DelayMeasurementStat> {
private static final String LOWER_LIMIT = "lowerLimit";
private static final String COUNT = "count";
private static final String BINS = "bins";
private static final String SOAM_PDUS_SENT = "soamPdusSent";
private static final String SOAM_PDUS_RECEIVED = "soamPdusReceived";
@Override
public ObjectNode encode(DelayMeasurementStat dmStat, CodecContext context) {
checkNotNull(dmStat, "DM stat cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("elapsedTime", dmStat.elapsedTime().toString())
.put("suspectStatus", String.valueOf(dmStat.suspectStatus()));
if (dmStat.frameDelayTwoWayMin() != null) {
result = result.put("frameDelayTwoWayMin",
dmStat.frameDelayTwoWayMin().toString());
}
if (dmStat.frameDelayTwoWayMax() != null) {
result = result.put("frameDelayTwoWayMax",
dmStat.frameDelayTwoWayMax().toString());
}
if (dmStat.frameDelayTwoWayAvg() != null) {
result = result.put("frameDelayTwoWayAvg",
dmStat.frameDelayTwoWayAvg().toString());
}
if (dmStat.frameDelayTwoWayBins() != null) {
result = (ObjectNode) result.set("frameDelayTwoWayBins",
encode(dmStat.frameDelayTwoWayBins(), context));
}
if (dmStat.frameDelayForwardMin() != null) {
result = result.put("frameDelayForwardMin",
dmStat.frameDelayForwardMin().toString());
}
if (dmStat.frameDelayForwardMax() != null) {
result = result.put("frameDelayForwardMax",
dmStat.frameDelayForwardMax().toString());
}
if (dmStat.frameDelayForwardAvg() != null) {
result = result.put("frameDelayForwardAvg",
dmStat.frameDelayForwardAvg().toString());
}
if (dmStat.frameDelayForwardBins() != null) {
result = (ObjectNode) result.set("frameDelayForwardBins",
encode(dmStat.frameDelayForwardBins(), context));
}
if (dmStat.frameDelayBackwardMin() != null) {
result = result.put("frameDelayBackwardMin",
dmStat.frameDelayBackwardMin().toString());
}
if (dmStat.frameDelayBackwardMax() != null) {
result = result.put("frameDelayBackwardMax",
dmStat.frameDelayBackwardMax().toString());
}
if (dmStat.frameDelayBackwardAvg() != null) {
result = result.put("frameDelayBackwardAvg",
dmStat.frameDelayBackwardAvg().toString());
}
if (dmStat.frameDelayBackwardBins() != null) {
result = (ObjectNode) result.set("frameDelayBackwardBins",
encode(dmStat.frameDelayBackwardBins(), context));
}
if (dmStat.interFrameDelayVariationTwoWayMin() != null) {
result = result.put("interFrameDelayVariationTwoWayMin",
dmStat.interFrameDelayVariationTwoWayMin().toString());
}
if (dmStat.interFrameDelayVariationTwoWayMax() != null) {
result.put("interFrameDelayVariationTwoWayMax",
dmStat.interFrameDelayVariationTwoWayMax().toString());
}
if (dmStat.interFrameDelayVariationTwoWayAvg() != null) {
result.put("interFrameDelayVariationTwoWayAvg",
dmStat.interFrameDelayVariationTwoWayAvg().toString());
}
if (dmStat.interFrameDelayVariationTwoWayBins() != null) {
result = (ObjectNode) result.set("interFrameDelayVariationTwoWayBins",
encode(dmStat.interFrameDelayVariationTwoWayBins(), context));
}
if (dmStat.interFrameDelayVariationForwardMin() != null) {
result = result.put("interFrameDelayVariationForwardMin",
dmStat.interFrameDelayVariationForwardMin().toString());
}
if (dmStat.interFrameDelayVariationForwardMax() != null) {
result = result.put("interFrameDelayVariationForwardMax",
dmStat.interFrameDelayVariationForwardMax().toString());
}
if (dmStat.interFrameDelayVariationForwardAvg() != null) {
result = result.put("interFrameDelayVariationForwardAvg",
dmStat.interFrameDelayVariationForwardAvg().toString());
}
if (dmStat.interFrameDelayVariationForwardBins() != null) {
result = (ObjectNode) result.set("interFrameDelayVariationForwardBins",
encode(dmStat.interFrameDelayVariationForwardBins(), context));
}
if (dmStat.interFrameDelayVariationBackwardMin() != null) {
result = result.put("interFrameDelayVariationBackwardMin",
dmStat.interFrameDelayVariationBackwardMin().toString());
}
if (dmStat.interFrameDelayVariationBackwardMax() != null) {
result = result.put("interFrameDelayVariationBackwardMax",
dmStat.interFrameDelayVariationBackwardMax().toString());
}
if (dmStat.interFrameDelayVariationBackwardAvg() != null) {
result = result.put("interFrameDelayVariationBackwardAvg",
dmStat.interFrameDelayVariationBackwardAvg().toString());
}
if (dmStat.interFrameDelayVariationBackwardBins() != null) {
result = (ObjectNode) result.set("interFrameDelayVariationBackwardBins",
encode(dmStat.interFrameDelayVariationBackwardBins(), context));
}
if (dmStat.frameDelayRangeTwoWayMax() != null) {
result = result.put("frameDelayRangeTwoWayMax",
dmStat.frameDelayRangeTwoWayMax().toString());
}
if (dmStat.frameDelayRangeTwoWayAvg() != null) {
result = result.put("frameDelayRangeTwoWayAvg",
dmStat.frameDelayRangeTwoWayAvg().toString());
}
if (dmStat.frameDelayRangeTwoWayBins() != null) {
result = (ObjectNode) result.set("frameDelayRangeTwoWayBins",
encode(dmStat.frameDelayRangeTwoWayBins(), context));
}
if (dmStat.frameDelayRangeForwardMax() != null) {
result = result.put("frameDelayRangeForwardMax",
dmStat.frameDelayRangeForwardMax().toString());
}
if (dmStat.frameDelayRangeForwardAvg() != null) {
result = result.put("frameDelayRangeForwardAvg",
dmStat.frameDelayRangeForwardAvg().toString());
}
if (dmStat.frameDelayRangeForwardBins() != null) {
result = (ObjectNode) result.set("frameDelayRangeForwardBins",
encode(dmStat.frameDelayRangeForwardBins(), context));
}
if (dmStat.frameDelayRangeBackwardMax() != null) {
result = result.put("frameDelayRangeBackwardMax",
dmStat.frameDelayRangeBackwardMax().toString());
}
if (dmStat.frameDelayRangeBackwardAvg() != null) {
result = result.put("frameDelayRangeBackwardAvg",
dmStat.frameDelayRangeBackwardAvg().toString());
}
if (dmStat.frameDelayRangeBackwardBins() != null) {
result = (ObjectNode) result.set("frameDelayRangeBackwardBins",
encode(dmStat.frameDelayRangeBackwardBins(), context));
}
if (dmStat.soamPdusReceived() != null) {
result = result.put(SOAM_PDUS_RECEIVED, dmStat.soamPdusReceived().toString());
}
if (dmStat.soamPdusSent() != null) {
result = result.put(SOAM_PDUS_SENT, dmStat.soamPdusSent().toString());
}
return result;
}
private ObjectNode encode(Map<Duration, Integer> bins, CodecContext context) {
checkNotNull(bins, "Bins cannot be null");
ArrayNode binsResult = context.mapper().createArrayNode();
bins.keySet().forEach(lwrLimit -> binsResult.add(encode(lwrLimit, bins.get(lwrLimit), context)));
return (ObjectNode) context.mapper().createObjectNode().set(BINS, binsResult);
}
private ObjectNode encode(Duration duration, Integer count, CodecContext context) {
return context.mapper().createObjectNode()
.put(LOWER_LIMIT, duration.toString())
.put(COUNT, count);
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2017-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.soam.web;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to DelayMeasurementStatCurrent object.
*/
public class DelayMeasurementStatCurrentCodec extends JsonCodec<DelayMeasurementStatCurrent> {
@Override
public ObjectNode encode(DelayMeasurementStatCurrent dmCurrent, CodecContext context) {
checkNotNull(dmCurrent, "DM current cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("startTime", dmCurrent.startTime().toString())
.put("elapsedTime", dmCurrent.elapsedTime().toString());
ObjectNode resultAbstract = new DelayMeasurementStatCodec().encode(dmCurrent, context);
result.setAll(resultAbstract);
return result;
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2017-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.soam.web;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to DelayMeasurementStatHistory object.
*/
public class DelayMeasurementStatHistoryCodec extends JsonCodec<DelayMeasurementStatHistory> {
@Override
public ObjectNode encode(DelayMeasurementStatHistory dmHistory, CodecContext context) {
checkNotNull(dmHistory, "DM history cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("historyId", String.valueOf(dmHistory.historyStatsId()))
.put("endTime", dmHistory.endTime().toString());
ObjectNode resultAbstract = new DelayMeasurementStatCodec().encode(dmHistory, context);
result.setAll(resultAbstract);
return result;
}
@Override
public ArrayNode encode(Iterable<DelayMeasurementStatHistory> historyEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
historyEntities.forEach(history -> an.add(encode(history, context)));
return an;
}
}

View File

@ -0,0 +1,174 @@
/*
* Copyright 2017-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.soam.web;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import java.time.Duration;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.StartTime;
import org.onosproject.incubator.net.l2monitoring.soam.StopTime;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmCreateBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmType;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.Version;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to DelayMeasurementCreate object.
*/
public class DmCreateCodec extends JsonCodec<DelayMeasurementCreate> {
private static final String VERSION = "version";
private static final String DM = "dm";
private static final String DM_CFG_TYPE = "dmCfgType";
private static final String DMDMM = "DMDMM";
private static final String REMOTE_MEP_ID = "remoteMepId";
private static final String PRIORITY = "priority";
private static final String MEASUREMENTS_ENABLED = "measurementsEnabled";
private static final String BINS_PER_FD_INTERVAL = "binsPerFdInterval";
private static final String BINS_PER_IFDV_INTERVAL = "binsPerIfdvInterval";
private static final String IFDV_SELECTION_OFFSET = "ifdvSelectionOffset";
private static final String BINS_PER_FDR_INTERVAL = "binsPerFdrInterval";
private static final String FRAME_SIZE = "frameSize";
private static final String MESSAGE_PERIOD_MS = "messagePeriodMs";
private static final String MEASUREMENT_INTERVAL_MINS = "measurementIntervalMins";
private static final String ALIGN_MEASUREMENT_INTERVALS = "alignMeasurementIntervals";
private static final String ALIGN_MEASUREMENT_OFFSET_MINS = "alignMeasurementOffsetMins";
private static final String START_TIME = "startTime";
private static final String STOP_TIME = "stopTime";
@Override
public DelayMeasurementCreate decode(ObjectNode json,
CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode dmNode = json.get(DM);
Version version = Version.Y17312011;
if (dmNode.get(VERSION) != null) {
version = Version.valueOf(dmNode.get(VERSION).asText());
}
DmType dmCfgType = DmType.DMDMM;
if (dmNode.get(DM_CFG_TYPE) != null) {
dmCfgType = DmType.valueOf(dmNode.get(DM_CFG_TYPE).asText(DMDMM));
}
MepId remoteMepId = MepId.valueOf(
nullIsIllegal(dmNode.get(REMOTE_MEP_ID), REMOTE_MEP_ID + " is required")
.shortValue());
Priority prio = Priority.valueOf(nullIsIllegal(dmNode.get(PRIORITY),
PRIORITY + " is required in the format 'PRIOn'").asText());
try {
DmCreateBuilder builder = DefaultDelayMeasurementCreate
.builder(dmCfgType, version, remoteMepId, prio);
if (dmNode.get(MEASUREMENTS_ENABLED) != null) {
context.codec(MeasurementOption.class)
.decode((ArrayNode) (dmNode.get(MEASUREMENTS_ENABLED)), context)
.forEach(builder::addToMeasurementsEnabled);
}
if (dmNode.get(BINS_PER_FD_INTERVAL) != null) {
builder = builder.binsPerFdInterval(
(short) dmNode.get(BINS_PER_FD_INTERVAL).asInt());
}
if (dmNode.get(BINS_PER_IFDV_INTERVAL) != null) {
builder = builder.binsPerIfdvInterval(
(short) dmNode.get(BINS_PER_IFDV_INTERVAL).asInt());
}
if (dmNode.get(IFDV_SELECTION_OFFSET) != null) {
builder = builder.ifdvSelectionOffset(
(short) dmNode.get(IFDV_SELECTION_OFFSET).asInt());
}
if (dmNode.get(BINS_PER_FDR_INTERVAL) != null) {
builder = builder.binsPerFdrInterval(
(short) dmNode.get(BINS_PER_FDR_INTERVAL).asInt());
}
if (dmNode.get(FRAME_SIZE) != null) {
builder = (DmCreateBuilder) builder.frameSize(
(short) dmNode.get(FRAME_SIZE).asInt());
}
if (dmNode.get(MESSAGE_PERIOD_MS) != null) {
builder = (DmCreateBuilder) builder.messagePeriod(Duration.ofMillis(
dmNode.get(MESSAGE_PERIOD_MS).asInt()));
}
if (dmNode.get(MEASUREMENT_INTERVAL_MINS) != null) {
builder = (DmCreateBuilder) builder.measurementInterval(
Duration.ofMinutes(
dmNode.get(MEASUREMENT_INTERVAL_MINS).asInt()));
}
if (dmNode.get(ALIGN_MEASUREMENT_INTERVALS) != null) {
builder = (DmCreateBuilder) builder.alignMeasurementIntervals(
dmNode.get(ALIGN_MEASUREMENT_INTERVALS).asBoolean());
}
if (dmNode.get(ALIGN_MEASUREMENT_OFFSET_MINS) != null) {
builder = (DmCreateBuilder) builder.alignMeasurementOffset(Duration.ofMinutes(
dmNode.get(ALIGN_MEASUREMENT_OFFSET_MINS).asInt()));
}
if (dmNode.get(START_TIME) != null) {
builder = (DmCreateBuilder) builder.startTime(context.codec(StartTime.class)
.decode((ObjectNode) dmNode.get(START_TIME), context));
}
if (dmNode.get(STOP_TIME) != null) {
builder = (DmCreateBuilder) builder.stopTime(context.codec(StopTime.class)
.decode((ObjectNode) dmNode.get(STOP_TIME), context));
}
return builder.build();
} catch (SoamConfigException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public ObjectNode encode(DelayMeasurementCreate dm, CodecContext context) {
checkNotNull(dm, "DM cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(DM_CFG_TYPE, dm.dmCfgType().name())
.put(VERSION, dm.version().name())
.put(REMOTE_MEP_ID, dm.remoteMepId().id())
.put(PRIORITY, dm.priority().name());
if (dm.measurementsEnabled() != null) {
result.set(MEASUREMENTS_ENABLED, new DmMeasurementOptionCodec()
.encode(dm.measurementsEnabled(), context));
}
if (dm.messagePeriod() != null) {
result.put(MESSAGE_PERIOD_MS, dm.messagePeriod().toMillis());
}
if (dm.frameSize() != null) {
result.put(FRAME_SIZE, dm.frameSize());
}
return result;
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2017-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.soam.web;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Iterator;
import java.util.Map.Entry;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to DelayMeasurementEntry object.
*/
public class DmEntryCodec extends JsonCodec<DelayMeasurementEntry> {
private static final String DM_ID = "dmId";
private static final String SESSION_STATUS = "sessionStatus";
private static final String FRAME_DELAY_TWO_WAY = "frameDelayTwoWay";
private static final String FRAME_DELAY_FORWARD = "frameDelayForward";
private static final String FRAME_DELAY_BACKWARD = "frameDelayBackward";
private static final String INTER_FRAME_DELAY_VARIATION_TWO_WAY = "interFrameDelayVariationTwoWay";
private static final String INTER_FRAME_DELAY_VARIATION_FORWARD = "interFrameDelayVariationForward";
private static final String INTER_FRAME_DELAY_VARIATION_BACKWARD = "interFrameDelayVariationBackward";
private static final String CURRENT = "current";
private static final String HISTORIC = "historic";
@Override
public ObjectNode encode(DelayMeasurementEntry dm, CodecContext context) {
checkNotNull(dm, "DM cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(DM_ID, dm.dmId().toString());
if (dm.sessionStatus() != null) {
result.put(SESSION_STATUS, dm.sessionStatus().name());
}
if (dm.frameDelayTwoWay() != null) {
result.put(FRAME_DELAY_TWO_WAY, dm.frameDelayTwoWay().toString());
}
if (dm.frameDelayForward() != null) {
result.put(FRAME_DELAY_FORWARD, dm.frameDelayForward().toString());
}
if (dm.frameDelayBackward() != null) {
result.put(FRAME_DELAY_BACKWARD, dm.frameDelayBackward().toString());
}
if (dm.interFrameDelayVariationTwoWay() != null) {
result.put(INTER_FRAME_DELAY_VARIATION_TWO_WAY,
dm.interFrameDelayVariationTwoWay().toString());
}
if (dm.interFrameDelayVariationForward() != null) {
result.put(INTER_FRAME_DELAY_VARIATION_FORWARD,
dm.interFrameDelayVariationForward().toString());
}
if (dm.interFrameDelayVariationBackward() != null) {
result.put(INTER_FRAME_DELAY_VARIATION_BACKWARD,
dm.interFrameDelayVariationBackward().toString());
}
ObjectNode dmAttrs = new DmCreateCodec().encode(dm, context);
Iterator<Entry<String, JsonNode>> elements = dmAttrs.fields();
while (elements.hasNext()) {
Entry<String, JsonNode> element = elements.next();
result.set(element.getKey(), element.getValue());
}
if (dm.currentResult() != null) {
result.set(CURRENT, new DelayMeasurementStatCurrentCodec()
.encode(dm.currentResult(), context));
}
if (dm.historicalResults() != null) {
result.set(HISTORIC, new DelayMeasurementStatHistoryCodec()
.encode(dm.historicalResults(), context));
}
return result;
}
@Override
public ArrayNode encode(Iterable<DelayMeasurementEntry> dmEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
dmEntities.forEach(dm -> an.add(encode(dm, context)));
return an;
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2017-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.soam.web;
import java.util.ArrayList;
import java.util.List;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import com.fasterxml.jackson.databind.node.ArrayNode;
/**
* Encode and decode to/from JSON to MeasurementOption object.
*/
public class DmMeasurementOptionCodec extends JsonCodec<MeasurementOption> {
@Override
public ArrayNode encode(Iterable<MeasurementOption> entities,
CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
entities.forEach(node -> an.add(node.name()));
return an;
}
@Override
public List<MeasurementOption> decode(ArrayNode json,
CodecContext context) {
if (json == null) {
return null;
}
List<MeasurementOption> moList = new ArrayList<>();
json.forEach(node -> moList.add(MeasurementOption.valueOf(node.asText())));
return moList;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate.CounterOption;
import java.util.ArrayList;
import java.util.List;
/**
* Encode and decode to/from JSON to CounterOption object.
*/
public class LmCounterOptionCodec extends JsonCodec<CounterOption> {
@Override
public ArrayNode encode(Iterable<CounterOption> entities,
CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
entities.forEach(node -> an.add(node.name()));
return an;
}
@Override
public List<CounterOption> decode(ArrayNode json,
CodecContext context) {
if (json == null) {
return null;
}
List<CounterOption> moList = new ArrayList<>();
json.forEach(node -> moList.add(CounterOption.valueOf(node.asText())));
return moList;
}
}

View File

@ -0,0 +1,196 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.MilliPct;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.StartTime;
import org.onosproject.incubator.net.l2monitoring.soam.StopTime;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.Version;
import org.onosproject.incubator.net.l2monitoring.soam.loss.DefaultLmCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementThreshold;
import java.time.Duration;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import static org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate.CounterOption;
import static org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate.LmType;
import static org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate.LmCreateBuilder;
/**
* Encode and decode to/from JSON to LossMeasurementCreate object.
*/
public class LmCreateCodec extends JsonCodec<LossMeasurementCreate> {
public static final String LM = "lm";
public static final String VERSION = "version";
public static final String LM_CFG_TYPE = "lmCfgType";
public static final String LMLMM = "LMLMM";
public static final String REMOTE_MEP_ID = "remoteMepId";
public static final String PRIORITY = "priority";
public static final String COUNTERS_ENABLED = "countersEnabled";
public static final String THRESHOLDS = "thresholds";
public static final String AVAILABILITY_MEASUREMENT_INTERVAL_MINS =
"availabilityMeasurementIntervalMins";
public static final String AVAILABILITY_NUMBER_CONSECUTIVE_FLR_MEASUREMENTS =
"availabilityNumberConsecutiveFlrMeasurements";
public static final String AVAILABILITY_FLR_THRESHOLD_PCT =
"availabilityFlrThresholdPct";
public static final String AVAILABILITY_NUMBER_CONSECUTIVE_INTERVALS =
"availabilityNumberConsecutiveIntervals";
public static final String AVAILABILITY_NUMBER_CONSECUTIVE_HIGH_FLR =
"availabilityNumberConsecutiveHighFlr";
public static final String FRAME_SIZE = "frameSize";
public static final String MESSAGE_PERIOD_MS = "messagePeriodMs";
public static final String MEASUREMENT_INTERVAL_MINS =
"measurementIntervalMins";
public static final String ALIGN_MEASUREMENT_INTERVALS =
"alignMeasurementIntervals";
public static final String ALIGN_MEASUREMENT_OFFSET_MINS =
"alignMeasurementOffsetMins";
public static final String START_TIME = "startTime";
public static final String STOP_TIME = "stopTime";
@Override
public LossMeasurementCreate decode(ObjectNode json,
CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode lmNode = json.get(LM);
Version version = Version.Y17312011;
if (lmNode.get(VERSION) != null) {
version = Version.valueOf(lmNode.get(VERSION).asText());
}
LmType lmCfgType = LmType.LMLMM;
if (lmNode.get(LM_CFG_TYPE) != null) {
lmCfgType = LmType.valueOf(lmNode.get(LM_CFG_TYPE).asText(LMLMM));
}
MepId remoteMepId = MepId.valueOf(
nullIsIllegal(lmNode.get(REMOTE_MEP_ID), REMOTE_MEP_ID + " is required")
.shortValue());
Priority prio = Priority.valueOf(nullIsIllegal(lmNode.get(PRIORITY),
PRIORITY + " is required in the format 'PRIOn'").asText());
try {
LmCreateBuilder builder = DefaultLmCreate
.builder(version, remoteMepId, prio, lmCfgType);
if (lmNode.get(COUNTERS_ENABLED) != null) {
context.codec(CounterOption.class)
.decode((ArrayNode) (lmNode.get(COUNTERS_ENABLED)), context)
.forEach(builder::addToCountersEnabled);
}
if (lmNode.get(THRESHOLDS) != null) {
context.codec(LossMeasurementThreshold.class)
.decode((ArrayNode) (lmNode.get(THRESHOLDS)), context)
.forEach(builder::addToLossMeasurementThreshold);
}
if (lmNode.get(AVAILABILITY_MEASUREMENT_INTERVAL_MINS) != null) {
builder = builder.availabilityMeasurementInterval(
Duration.ofMinutes(lmNode.get(AVAILABILITY_MEASUREMENT_INTERVAL_MINS).asInt()));
}
if (lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_FLR_MEASUREMENTS) != null) {
builder = builder.availabilityNumberConsecutiveFlrMeasurements(
lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_FLR_MEASUREMENTS).asInt());
}
if (lmNode.get(AVAILABILITY_FLR_THRESHOLD_PCT) != null) {
builder = builder.availabilityFlrThreshold(
MilliPct.ofPercent((float) lmNode.get(AVAILABILITY_FLR_THRESHOLD_PCT).asDouble()));
}
if (lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_INTERVALS) != null) {
builder = builder.availabilityNumberConsecutiveIntervals(
(short) lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_INTERVALS).asInt());
}
if (lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_HIGH_FLR) != null) {
builder = builder.availabilityNumberConsecutiveHighFlr(
(short) lmNode.get(AVAILABILITY_NUMBER_CONSECUTIVE_HIGH_FLR).asInt());
}
if (lmNode.get(FRAME_SIZE) != null) {
builder = (LmCreateBuilder) builder.frameSize(
(short) lmNode.get(FRAME_SIZE).asInt());
}
if (lmNode.get(MESSAGE_PERIOD_MS) != null) {
builder = (LmCreateBuilder) builder.messagePeriod(Duration.ofMillis(
lmNode.get(MESSAGE_PERIOD_MS).asInt()));
}
if (lmNode.get(MEASUREMENT_INTERVAL_MINS) != null) {
builder = (LmCreateBuilder) builder.measurementInterval(
Duration.ofMinutes(
lmNode.get(MEASUREMENT_INTERVAL_MINS).asInt()));
}
if (lmNode.get(ALIGN_MEASUREMENT_INTERVALS) != null) {
builder = (LmCreateBuilder) builder.alignMeasurementIntervals(
lmNode.get(ALIGN_MEASUREMENT_INTERVALS).asBoolean());
}
if (lmNode.get(ALIGN_MEASUREMENT_OFFSET_MINS) != null) {
builder = (LmCreateBuilder) builder.alignMeasurementOffset(Duration.ofMinutes(
lmNode.get(ALIGN_MEASUREMENT_OFFSET_MINS).asInt()));
}
if (lmNode.get(START_TIME) != null) {
builder = (LmCreateBuilder) builder.startTime(context.codec(StartTime.class)
.decode((ObjectNode) lmNode.get(START_TIME), context));
}
if (lmNode.get(STOP_TIME) != null) {
builder = (LmCreateBuilder) builder.stopTime(context.codec(StopTime.class)
.decode((ObjectNode) lmNode.get(STOP_TIME), context));
}
return builder.build();
} catch (SoamConfigException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public ObjectNode encode(LossMeasurementCreate lm, CodecContext context) {
checkNotNull(lm, "LM cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put(LM_CFG_TYPE, lm.lmCfgType().name())
.put(VERSION, lm.version().name())
.put(REMOTE_MEP_ID, lm.remoteMepId().id())
.put(PRIORITY, lm.priority().name());
if (lm.countersEnabled() != null) {
result.set(COUNTERS_ENABLED, new LmCounterOptionCodec()
.encode(lm.countersEnabled(), context));
}
if (lm.messagePeriod() != null) {
result.put(MESSAGE_PERIOD_MS, lm.messagePeriod().toMillis());
}
if (lm.frameSize() != null) {
result.put(FRAME_SIZE, lm.frameSize());
}
return result;
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
import java.util.Iterator;
import java.util.Map.Entry;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossMeasurementEntry object.
*/
public class LmEntryCodec extends JsonCodec<LossMeasurementEntry> {
@Override
public ObjectNode encode(LossMeasurementEntry lm, CodecContext context) {
checkNotNull(lm, "LM cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("lmId", lm.lmId().toString());
if (lm.measuredForwardFlr() != null) {
result.put("measuredForwardFlr", lm.measuredForwardFlr().percentValue());
}
if (lm.measuredBackwardFlr() != null) {
result.put("measuredBackwardFlr", lm.measuredBackwardFlr().percentValue());
}
if (lm.measuredAvailabilityForwardStatus() != null) {
result.put("measuredAvailabilityForwardStatus",
lm.measuredAvailabilityForwardStatus().name());
}
if (lm.measuredAvailabilityBackwardStatus() != null) {
result.put("measuredAvailabilityBackwardStatus",
lm.measuredAvailabilityBackwardStatus().name());
}
if (lm.measuredForwardLastTransitionTime() != null) {
result.put("measuredForwardLastTransitionTime",
lm.measuredForwardLastTransitionTime().toString());
}
if (lm.measuredBackwardLastTransitionTime() != null) {
result.put("measuredBackwardLastTransitionTime",
lm.measuredBackwardLastTransitionTime().toString());
}
ObjectNode lmAttrs = new LmCreateCodec().encode(lm, context);
Iterator<Entry<String, JsonNode>> elements = lmAttrs.fields();
while (elements.hasNext()) {
Entry<String, JsonNode> element = elements.next();
result.set(element.getKey(), element.getValue());
}
if (lm.measurementCurrent() != null) {
result.set("measurementCurrent", new LossMeasurementStatCurrentCodec()
.encode(lm.measurementCurrent(), context));
}
if (lm.measurementHistories() != null) {
result.set("measurementHistories", new LossMeasurementStatHistoryCodec()
.encode(lm.measurementHistories(), context));
}
if (lm.availabilityCurrent() != null) {
result.set("availabilityCurrent", new LossAvailabilityStatCurrentCodec()
.encode(lm.availabilityCurrent(), context));
}
if (lm.availabilityHistories() != null) {
result.set("availabilityHistories", new LossAvailabilityStatHistoryCodec()
.encode(lm.availabilityHistories(), context));
}
return result;
}
@Override
public ArrayNode encode(Iterable<LossMeasurementEntry> lmEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
lmEntities.forEach(dm -> an.add(encode(dm, context)));
return an;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementThreshold.ThresholdOption;
import java.util.ArrayList;
import java.util.List;
/**
* Encode and decode to/from JSON to ThresholdOption object.
*/
public class LmThresholdOptionCodec extends JsonCodec<ThresholdOption> {
@Override
public ArrayNode encode(Iterable<ThresholdOption> entities,
CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
entities.forEach(node -> an.add(node.name()));
return an;
}
@Override
public List<ThresholdOption> decode(ArrayNode json,
CodecContext context) {
if (json == null) {
return null;
}
List<ThresholdOption> moList = new ArrayList<>();
json.forEach(node -> moList.add(ThresholdOption.valueOf(node.asText())));
return moList;
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStat;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossAvailabilityStat object.
*/
public class LossAvailabilityStatCodec extends JsonCodec<LossAvailabilityStat> {
@Override
public ObjectNode encode(LossAvailabilityStat laStat, CodecContext context) {
checkNotNull(laStat, "LA stat cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("elapsedTime", laStat.elapsedTime().toString())
.put("suspectStatus", String.valueOf(laStat.suspectStatus()));
if (laStat.forwardHighLoss() != null) {
result = result.put("forwardHighLoss",
laStat.forwardHighLoss().toString());
}
if (laStat.backwardHighLoss() != null) {
result = result.put("backwardHighLoss",
laStat.backwardHighLoss().toString());
}
if (laStat.forwardConsecutiveHighLoss() != null) {
result = result.put("forwardConsecutiveHighLoss",
laStat.forwardConsecutiveHighLoss().toString());
}
if (laStat.backwardConsecutiveHighLoss() != null) {
result = result.put("backwardConsecutiveHighLoss",
laStat.backwardConsecutiveHighLoss().toString());
}
if (laStat.forwardAvailable() != null) {
result = result.put("forwardAvailable",
laStat.forwardAvailable().toString());
}
if (laStat.backwardAvailable() != null) {
result = result.put("backwardAvailable",
laStat.backwardAvailable().toString());
}
if (laStat.forwardUnavailable() != null) {
result = result.put("forwardUnavailable",
laStat.forwardUnavailable().toString());
}
if (laStat.backwardUnavailable() != null) {
result = result.put("backwardUnavailable",
laStat.backwardUnavailable().toString());
}
if (laStat.backwardMinFrameLossRatio() != null) {
result = result.put("backwardMinFrameLossRatio",
laStat.backwardMinFrameLossRatio().toString());
}
if (laStat.backwardMaxFrameLossRatio() != null) {
result = result.put("backwardMaxFrameLossRatio",
laStat.backwardMaxFrameLossRatio().toString());
}
if (laStat.backwardAverageFrameLossRatio() != null) {
result = result.put("backwardAverageFrameLossRatio",
laStat.backwardAverageFrameLossRatio().toString());
}
if (laStat.forwardMinFrameLossRatio() != null) {
result = result.put("forwardMinFrameLossRatio",
laStat.forwardMinFrameLossRatio().toString());
}
if (laStat.forwardMaxFrameLossRatio() != null) {
result = result.put("forwardMaxFrameLossRatio",
laStat.forwardMaxFrameLossRatio().toString());
}
if (laStat.forwardAverageFrameLossRatio() != null) {
result = result.put("forwardAverageFrameLossRatio",
laStat.forwardAverageFrameLossRatio().toString());
}
return result;
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStatCurrent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossAvailabilityStatCurrent object.
*/
public class LossAvailabilityStatCurrentCodec extends JsonCodec<LossAvailabilityStatCurrent> {
@Override
public ObjectNode encode(LossAvailabilityStatCurrent laCurrent, CodecContext context) {
checkNotNull(laCurrent, "LA current cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("startTime", laCurrent.startTime().toString())
.put("elapsedTime", laCurrent.elapsedTime().toString());
ObjectNode resultAbstract = new LossAvailabilityStatCodec().encode(laCurrent, context);
result.setAll(resultAbstract);
return result;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossAvailabilityStatHistory;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossAvailabilityStatHistory object.
*/
public class LossAvailabilityStatHistoryCodec extends JsonCodec<LossAvailabilityStatHistory> {
@Override
public ObjectNode encode(LossAvailabilityStatHistory laHistory, CodecContext context) {
checkNotNull(laHistory, "LA history cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("historyId", String.valueOf(laHistory.historyStatsId()))
.put("endTime", laHistory.endTime().toString());
ObjectNode resultAbstract = new LossAvailabilityStatCodec().encode(laHistory, context);
result.setAll(resultAbstract);
return result;
}
@Override
public ArrayNode encode(Iterable<LossAvailabilityStatHistory> historyEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
historyEntities.forEach(history -> an.add(encode(history, context)));
return an;
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStat;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossMeasurementStat object.
*/
public class LossMeasurementStatCodec extends JsonCodec<LossMeasurementStat> {
@Override
public ObjectNode encode(LossMeasurementStat lmStat, CodecContext context) {
checkNotNull(lmStat, "LM stat cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("elapsedTime", lmStat.elapsedTime().toString())
.put("suspectStatus", String.valueOf(lmStat.suspectStatus()));
if (lmStat.forwardTransmittedFrames() != null) {
result = result.put("forwardTransmittedFrames",
lmStat.forwardTransmittedFrames().toString());
}
if (lmStat.forwardReceivedFrames() != null) {
result = result.put("forwardReceivedFrames",
lmStat.forwardReceivedFrames().toString());
}
if (lmStat.forwardMinFrameLossRatio() != null) {
result = result.put("forwardMinFrameLossRatio",
lmStat.forwardMinFrameLossRatio().toString());
}
if (lmStat.forwardMaxFrameLossRatio() != null) {
result = result.put("forwardMaxFrameLossRatio",
lmStat.forwardMaxFrameLossRatio().toString());
}
if (lmStat.forwardAverageFrameLossRatio() != null) {
result = result.put("forwardAverageFrameLossRatio",
lmStat.forwardAverageFrameLossRatio().toString());
}
if (lmStat.backwardTransmittedFrames() != null) {
result = result.put("backwardTransmittedFrames",
lmStat.backwardTransmittedFrames().toString());
}
if (lmStat.backwardReceivedFrames() != null) {
result = result.put("backwardReceivedFrames",
lmStat.backwardReceivedFrames().toString());
}
if (lmStat.backwardMinFrameLossRatio() != null) {
result = result.put("backwardMinFrameLossRatio",
lmStat.backwardMinFrameLossRatio().toString());
}
if (lmStat.backwardMaxFrameLossRatio() != null) {
result = result.put("backwardMaxFrameLossRatio",
lmStat.backwardMaxFrameLossRatio().toString());
}
if (lmStat.backwardAverageFrameLossRatio() != null) {
result = result.put("backwardAverageFrameLossRatio",
lmStat.backwardAverageFrameLossRatio().toString());
}
if (lmStat.soamPdusSent() != null) {
result = result.put("soamPdusSent",
lmStat.soamPdusSent().toString());
}
if (lmStat.soamPdusReceived() != null) {
result.put("soamPdusReceived",
lmStat.soamPdusReceived().toString());
}
return result;
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatCurrent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossMeasurementStatCurrent object.
*/
public class LossMeasurementStatCurrentCodec extends JsonCodec<LossMeasurementStatCurrent> {
@Override
public ObjectNode encode(LossMeasurementStatCurrent lmCurrent, CodecContext context) {
checkNotNull(lmCurrent, "LM current cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("startTime", lmCurrent.startTime().toString())
.put("elapsedTime", lmCurrent.elapsedTime().toString());
ObjectNode resultAbstract = new LossMeasurementStatCodec().encode(lmCurrent, context);
result.setAll(resultAbstract);
return result;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatHistory;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Encode and decode to/from JSON to LossMeasurementStatHistory object.
*/
public class LossMeasurementStatHistoryCodec extends JsonCodec<LossMeasurementStatHistory> {
@Override
public ObjectNode encode(LossMeasurementStatHistory lmHistory, CodecContext context) {
checkNotNull(lmHistory, "LM history cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("historyId", String.valueOf(lmHistory.historyStatsId()))
.put("endTime", lmHistory.endTime().toString());
ObjectNode resultAbstract = new LossMeasurementStatCodec().encode(lmHistory, context);
result.setAll(resultAbstract);
return result;
}
@Override
public ArrayNode encode(Iterable<LossMeasurementStatHistory> historyEntities, CodecContext context) {
ArrayNode an = context.mapper().createArrayNode();
historyEntities.forEach(history -> an.add(encode(history, context)));
return an;
}
}

View File

@ -0,0 +1,192 @@
/*
* Copyright 2017-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.soam.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.MilliPct;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementThreshold;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import static org.onosproject.incubator.net.l2monitoring.soam.loss.DefaultLmThreshold.*;
/**
* Encode and decode to/from JSON to LossMeasurementThreshold object.
*/
public class LossMeasurementThresholdCodec extends JsonCodec<LossMeasurementThreshold> {
static final String MEASUREDFLRFORWARD = "measuredFlrForward";
static final String MAXFLRFORWARD = "maxFlrForward";
static final String AVERAGEFLRFORWARD = "averageFlrForward";
static final String MEASUREDFLRBACKWARD = "measuredFlrBackward";
static final String MAXFLRBACKWARD = "maxFlrBackward";
static final String AVERAGEFLRBACKWARD = "averageFlrBackward";
static final String FORWARDHIGHLOSS = "forwardHighLoss";
static final String FORWARDCONSECUTIVEHIGHLOSS = "forwardConsecutiveHighLoss";
static final String BACKWARDHIGHLOSS = "backwardHighLoss";
static final String BACKWARDCONSECUTIVEHIGHLOSS = "backwardConsecutiveHighLoss";
static final String FORWARDUNAVAILABLECOUNT = "forwardUnavailableCount";
static final String FORWARDAVAILABLERATIO = "forwardAvailableRatio";
static final String BACKWARDUNAVAILABLECOUNT = "backwardUnavailableCount";
static final String BACKWARDAVAILABLERATIO = "backwardAvailableRatio";
static final String THRESHOLDOPTIONS = "thresholdOptions";
@Override
public ObjectNode encode(LossMeasurementThreshold lmt, CodecContext context) {
checkNotNull(lmt, "LM thresholds cannot be null");
ObjectNode result = context.mapper().createObjectNode()
.put("id", lmt.thresholdId().value());
if (lmt.thresholds() != null) {
result.set(THRESHOLDOPTIONS, new LmThresholdOptionCodec()
.encode(lmt.thresholds(), context));
}
if (lmt.measuredFlrForward() != null) {
result.put(MEASUREDFLRFORWARD, lmt.measuredFlrForward().percentValue());
}
if (lmt.maxFlrForward() != null) {
result.put(MAXFLRFORWARD, lmt.maxFlrForward().percentValue());
}
if (lmt.averageFlrForward() != null) {
result.put(AVERAGEFLRFORWARD, lmt.averageFlrForward().percentValue());
}
if (lmt.measuredFlrBackward() != null) {
result.put(MEASUREDFLRBACKWARD, lmt.measuredFlrBackward().percentValue());
}
if (lmt.maxFlrBackward() != null) {
result.put(MAXFLRBACKWARD, lmt.maxFlrBackward().percentValue());
}
if (lmt.averageFlrBackward() != null) {
result.put(AVERAGEFLRBACKWARD, lmt.averageFlrBackward().percentValue());
}
if (lmt.forwardHighLoss() != null) {
result.put(FORWARDHIGHLOSS, lmt.forwardHighLoss().longValue());
}
if (lmt.forwardConsecutiveHighLoss() != null) {
result.put(FORWARDCONSECUTIVEHIGHLOSS, lmt.measuredFlrForward().longValue());
}
if (lmt.backwardHighLoss() != null) {
result.put(BACKWARDHIGHLOSS, lmt.backwardHighLoss().longValue());
}
if (lmt.backwardConsecutiveHighLoss() != null) {
result.put(BACKWARDCONSECUTIVEHIGHLOSS, lmt.backwardConsecutiveHighLoss().longValue());
}
if (lmt.forwardUnavailableCount() != null) {
result.put(FORWARDUNAVAILABLECOUNT, lmt.forwardUnavailableCount().longValue());
}
if (lmt.forwardAvailableRatio() != null) {
result.put(FORWARDAVAILABLERATIO, lmt.forwardAvailableRatio().percentValue());
}
if (lmt.backwardUnavailableCount() != null) {
result.put(BACKWARDUNAVAILABLECOUNT, lmt.backwardUnavailableCount().longValue());
}
if (lmt.backwardAvailableRatio() != null) {
result.put(BACKWARDAVAILABLERATIO, lmt.backwardAvailableRatio().percentValue());
}
return result;
}
@Override
public List<LossMeasurementThreshold> decode(ArrayNode json, CodecContext context) {
if (json == null) {
return null;
}
List<LossMeasurementThreshold> thrList = new ArrayList<>();
json.forEach(node -> thrList.add(decode((ObjectNode) node, context)));
return thrList;
}
@Override
public LossMeasurementThreshold decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
JsonNode thrNode = json.get("threshold");
SoamId thresholdId = SoamId.valueOf(nullIsIllegal(thrNode.get("id"),
"thresholdId must not be null").asInt());
LossMeasurementThreshold.LmThresholdBuilder builder = builder(thresholdId);
if (thrNode.get("thresholds") != null) {
context.codec(ThresholdOption.class)
.decode((ArrayNode) (thrNode.get("thresholds")), context)
.forEach(builder::addToThreshold);
}
if (thrNode.get(MEASUREDFLRFORWARD) != null) {
builder.measuredFlrForward(MilliPct.ofPercent(
(float) thrNode.get(MEASUREDFLRFORWARD).asDouble()));
}
if (thrNode.get(MAXFLRFORWARD) != null) {
builder.maxFlrForward(MilliPct.ofPercent(
(float) thrNode.get(MAXFLRFORWARD).asDouble()));
}
if (thrNode.get(AVERAGEFLRFORWARD) != null) {
builder.averageFlrForward(MilliPct.ofPercent(
(float) thrNode.get(AVERAGEFLRFORWARD).asDouble()));
}
if (thrNode.get(MEASUREDFLRBACKWARD) != null) {
builder.measuredFlrBackward(MilliPct.ofPercent(
(float) thrNode.get(MEASUREDFLRBACKWARD).asDouble()));
}
if (thrNode.get(MAXFLRBACKWARD) != null) {
builder.maxFlrBackward(MilliPct.ofPercent(
(float) thrNode.get(MAXFLRBACKWARD).asDouble()));
}
if (thrNode.get(AVERAGEFLRBACKWARD) != null) {
builder.averageFlrBackward(MilliPct.ofPercent(
(float) thrNode.get(AVERAGEFLRBACKWARD).asDouble()));
}
if (thrNode.get(FORWARDHIGHLOSS) != null) {
builder.forwardHighLoss(thrNode.get(FORWARDHIGHLOSS).asLong());
}
if (thrNode.get(FORWARDCONSECUTIVEHIGHLOSS) != null) {
builder.forwardConsecutiveHighLoss(thrNode.get(FORWARDCONSECUTIVEHIGHLOSS).asLong());
}
if (thrNode.get(BACKWARDHIGHLOSS) != null) {
builder.backwardHighLoss(thrNode.get(BACKWARDHIGHLOSS).asLong());
}
if (thrNode.get(BACKWARDCONSECUTIVEHIGHLOSS) != null) {
builder.backwardConsecutiveHighLoss(thrNode.get(BACKWARDCONSECUTIVEHIGHLOSS).asLong());
}
if (thrNode.get(FORWARDUNAVAILABLECOUNT) != null) {
builder.forwardUnavailableCount(thrNode.get(FORWARDUNAVAILABLECOUNT).asLong());
}
if (thrNode.get(FORWARDAVAILABLERATIO) != null) {
builder.forwardAvailableRatio(MilliPct.ofPercent(
(float) thrNode.get(FORWARDAVAILABLERATIO).asDouble()));
}
if (thrNode.get(BACKWARDUNAVAILABLECOUNT) != null) {
builder.backwardUnavailableCount(thrNode.get(BACKWARDUNAVAILABLECOUNT).asLong());
}
if (thrNode.get(BACKWARDAVAILABLERATIO) != null) {
builder.backwardAvailableRatio(MilliPct.ofPercent(
(float) thrNode.get(BACKWARDAVAILABLERATIO).asDouble()));
}
return builder.build();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2017-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.soam.web;
import java.time.Duration;
import java.time.OffsetDateTime;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.StartTime;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to StartTime object.
*/
public class StartTimeCodec extends JsonCodec<StartTime> {
@Override
public StartTime decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
if (json.get("immediate") != null) {
return StartTime.immediate();
} else if (json.get("absolute") != null) {
if (json.get("absolute").get("start-time") != null) {
return StartTime.absolute(OffsetDateTime
.parse(json.get("absolute").get("start-time").asText())
.toInstant());
}
throw new IllegalArgumentException("StartTime absolute must contain "
+ "a start-time in date-time format with offset");
} else if (json.get("relative") != null) {
if (json.get("relative").get("start-time") != null) {
return StartTime.relative(Duration.parse(json.get("relative").get("start-time").asText()));
}
throw new IllegalArgumentException("StartTime relative must contain a start-time duration");
} else {
throw new IllegalArgumentException("StartTime must be either immediate, absolute or relative");
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2017-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.soam.web;
import java.time.Duration;
import java.time.OffsetDateTime;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.incubator.net.l2monitoring.soam.StopTime;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Encode and decode to/from JSON to StopTime object.
*/
public class StopTimeCodec extends JsonCodec<StopTime> {
@Override
public StopTime decode(ObjectNode json, CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
if (json.get("none") != null) {
return StopTime.none();
} else if (json.get("absolute") != null) {
if (json.get("absolute").get("stop-time") != null) {
return StopTime.absolute(OffsetDateTime
.parse(json.get("absolute").get("stop-time").asText())
.toInstant());
}
throw new IllegalArgumentException("StopTime absolute must contain "
+ "a stop-time in date-time format with offset");
} else if (json.get("relative") != null) {
if (json.get("relative").get("stop-time") != null) {
return StopTime.relative(Duration.parse(json.get("relative").get("stop-time").asText()));
}
throw new IllegalArgumentException("StopTime relative must contain a stop-time duration");
} else {
throw new IllegalArgumentException("StopTime must be either none, absolute or relative");
}
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2017-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.
*/
/**
* Codecs for converting SOAM objects to and from JSON.
*/
package org.onosproject.soam.web;

View File

@ -0,0 +1,74 @@
<!--
~ Copyright 2017-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.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.cfm.cli.CfmMdAddCommand"/>
<completers>
<ref component-id="mdNameTypeCompleter"/>
<ref component-id="placeholderCompleter"/>
<ref component-id="mdLevelCompleter"/>
<ref component-id="placeholderCompleter"/>
</completers>
</command>
<command>
<action class="org.onosproject.cfm.cli.CfmMdDeleteCommand"/>
<completers>
<ref component-id="mdNameCompleter"/>
</completers>
</command>
<command>
<action class="org.onosproject.cfm.cli.CfmMdListMdCommand"/>
<completers>
<ref component-id="mdNameCompleter"/>
</completers>
</command>
<command>
<action class="org.onosproject.cfm.cli.CfmMaAddCommand"/>
<completers>
<ref component-id="mdNameCompleter"/>
<ref component-id="maNameTypeCompleter"/>
<ref component-id="placeholderCompleter"/>
<ref component-id="maCcmIntervalCompleter"/>
<ref component-id="placeholderCompleter"/>
<ref component-id="placeholderCompleter"/>
<ref component-id="compTagTypeCompleter"/>
<ref component-id="compMhfCompleter"/>
<ref component-id="placeholderCompleter"/>
</completers>
</command>
<command>
<action class="org.onosproject.cfm.cli.CfmMaDeleteCommand"/>
<completers>
<ref component-id="maNameCompleter"/>
</completers>
</command>
</command-bundle>
<bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
<bean id="mdNameTypeCompleter" class="org.onosproject.cfm.cli.completer.CfmMdNameTypeCompleter"/>
<bean id="maNameTypeCompleter" class="org.onosproject.cfm.cli.completer.CfmMaNameTypeCompleter"/>
<bean id="mdNameCompleter" class="org.onosproject.cfm.cli.completer.CfmMdNameCompleter"/>
<bean id="maNameCompleter" class="org.onosproject.cfm.cli.completer.CfmMaNameCompleter"/>
<bean id="mdLevelCompleter" class="org.onosproject.cfm.cli.completer.CfmMdLevelCompleter"/>
<bean id="maCcmIntervalCompleter" class="org.onosproject.cfm.cli.completer.CfmMaCcmIntervalCompleter"/>
<bean id="compTagTypeCompleter" class="org.onosproject.cfm.cli.completer.CfmCompTagTypeCompleter"/>
<bean id="compMhfCompleter" class="org.onosproject.cfm.cli.completer.CfmCompMhfCompleter"/>
</blueprint>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2017-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.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="ONOS" version="2.5">
<display-name>Layer 2 Cfm REST API v1.0</display-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>Secured</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>admin</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>karaf</realm-name>
</login-config>
<servlet>
<servlet-name>JAX-RS Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.onosproject.cfm.impl.CfmWebApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -0,0 +1,66 @@
/*
* Copyright 2017-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.cfm;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.JsonCodec;
import org.onosproject.codec.impl.CodecManager;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Mock codec context for use in codec unit tests.
*/
public class CfmCodecContext implements CodecContext {
private final ObjectMapper mapper = new ObjectMapper();
private final CodecManager codecManager = new CodecManager();
private final CfmWebComponent manager = new CfmWebComponent();
/**
* Constructs a new mock codec context.
*/
public CfmCodecContext() {
codecManager.activate();
manager.codecService = codecManager;
manager.activate();
}
@Override
public ObjectMapper mapper() {
return mapper;
}
@Override
public <T> T getService(Class<T> serviceClass) {
return null;
}
@Override
public <T> JsonCodec<T> codec(Class<T> entityClass) {
return codecManager.getCodec(entityClass);
}
/**
* Get the codec manager.
*
* @return instance of codec manager
*/
public CodecService codecManager() {
return codecManager;
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2017-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.cfm.impl;
import org.glassfish.jersey.server.ResourceConfig;
import org.onosproject.rest.resources.ResourceTest;
/**
* Base class for CFM REST API tests. Performs common configuration operations.
*/
public class CfmResourceTest extends ResourceTest {
/**
* Creates a new web-resource test.
*/
public CfmResourceTest() {
super(ResourceConfig.forApplicationClass(CfmWebApplication.class));
}
}

View File

@ -0,0 +1,199 @@
/*
* Copyright 2017-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.cfm.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.VlanId;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultComponent;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Optional;
import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class MaWebResourceTest extends CfmResourceTest {
private final CfmMdService mdService = createMock(CfmMdService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
private MaintenanceAssociation ma1;
@Before
public void setUpTest() throws CfmConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMdService.class, mdService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength())
.addToRemoteMepIdList(MepId.valueOf((short) 101))
.addToRemoteMepIdList(MepId.valueOf((short) 102))
.ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_3MS)
.maNumericId((short) 1)
.addToComponentList(
DefaultComponent.builder(1)
.tagType(Component.TagType.VLAN_STAG)
.mhfCreationType(Component.MhfCreationType.NONE)
.idPermission(Component.IdPermissionType.MANAGE)
.addToVidList(VlanId.vlanId((short) 1010))
.build())
.build();
}
@Test
public void testGetMa() {
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName()
+ "/ma/" + MANAME1.maName()).request().get(String.class);
assertThat(response, is("{\"ma\":" +
"{\"maName\":\"ma-1-1\"," +
"\"maNameType\":\"CHARACTERSTRING\"," +
"\"maNumericId\":1," +
"\"ccm-interval\":\"INTERVAL_3MS\"," +
"\"component-list\":[{\"component\":" +
"{\"component-id\":1," +
"\"vid-list\":[{\"vid\":\"1010\"}]," +
"\"mhf-creation-type\":\"NONE\"," +
"\"id-permission\":\"MANAGE\"," +
"\"tag-type\":\"VLAN_STAG\"}}]," +
"\"rmep-list\":" +
"[{\"rmep\":101}," +
"{\"rmep\":102}]}}"));
}
@Test
public void testGetMaEmpty() throws IOException {
MaIdShort maId2 = MaIdCharStr.asMaId("ma-2");
expect(mdService
.getMaintenanceAssociation(MDNAME1, maId2))
.andReturn(Optional.empty()).anyTimes();
replay(mdService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + MDNAME1.mdName()
+ "/ma/" + maId2.maName()).request().get(String.class);
fail("Expected InternalServerErrorException, as MA is unknown");
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertThat(sb.toString(), is("{ \"failure\":" +
"\"java.lang.IllegalArgumentException: MA ma-2 not Found\" }"));
}
}
@Test
public void testDeleteMa() throws CfmConfigException {
expect(mdService.deleteMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(true).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName()
+ "/ma/" + MANAME1.maName()).request().delete();
assertEquals(200, response.getStatus());
}
@Test
public void testDeleteMaEmpty() throws CfmConfigException {
MaIdShort maId2 = MaIdCharStr.asMaId("ma-2");
expect(mdService.deleteMaintenanceAssociation(MDNAME1, maId2))
.andReturn(false).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName()
+ "/ma/" + maId2.maName()).request().delete();
assertEquals(304, response.getStatus());
}
@Test
public void testCreateMa() throws CfmConfigException {
MaintenanceDomain md1 = DefaultMaintenanceDomain
.builder(MDNAME1).mdLevel(MaintenanceDomain.MdLevel.LEVEL2).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.createMaintenanceAssociation(MDNAME1, ma1))
.andReturn(false).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class)
.encode(ma1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName()
+ "/ma").request().post(Entity.json(node.toString()));
assertEquals(201, response.getStatus());
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright 2017-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.cfm.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class MdWebResourceTest extends CfmResourceTest {
private final CfmMdService mdService = createMock(CfmMdService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MdId MDNAME2 = MdIdCharStr.asMdId("md-2");
private List<MaintenanceDomain> mdList;
@Before
public void setUpTest() throws CfmConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMdService.class, mdService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
mdList = new ArrayList<>();
mdList.add(DefaultMaintenanceDomain.builder(MDNAME1)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL1).build());
mdList.add(DefaultMaintenanceDomain.builder(MDNAME2)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL2).build());
}
@Test
public void testGetMds() {
expect(mdService.getAllMaintenanceDomain()).andReturn(mdList).anyTimes();
replay(mdService);
final WebTarget wt = target();
final String response = wt.path("md").request().get(String.class);
assertThat(response, is("{\"mds\":[[" +
"{\"mdName\":\"md-1\",\"mdNameType\":\"CHARACTERSTRING\"," +
"\"mdLevel\":\"LEVEL1\",\"maList\":[]}," +
"{\"mdName\":\"md-2\",\"mdNameType\":\"CHARACTERSTRING\"," +
"\"mdLevel\":\"LEVEL2\",\"maList\":[]}]]}"));
}
@Test
public void testGetMdsEmpty() {
expect(mdService.getAllMaintenanceDomain())
.andReturn(new ArrayList<>()).anyTimes();
replay(mdService);
final WebTarget wt = target();
final String response = wt.path("md").request().get(String.class);
assertThat(response, is("{\"mds\":[[]]}"));
}
@Test
public void testGetMd() {
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(mdList.get(0))).anyTimes();
replay(mdService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1).request().get(String.class);
assertThat(response, is("{\"md\":" +
"{\"mdName\":\"md-1\",\"mdNameType\":\"CHARACTERSTRING\"," +
"\"mdLevel\":\"LEVEL1\",\"maList\":[]}}"));
}
@Test
public void testGetMdEmpty() throws IOException {
final MdId mdName3 = MdIdCharStr.asMdId("md-3");
expect(mdService.getMaintenanceDomain(mdName3))
.andReturn(Optional.empty()).anyTimes();
replay(mdService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + mdName3).request().get(String.class);
fail("Expected InternalServerErrorException, as MD is unknown");
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertThat(sb.toString(), is("{ \"failure\":" +
"\"java.lang.IllegalArgumentException: MD md-3 not Found\" }"));
}
}
@Test
public void testDeleteMd() throws CfmConfigException {
expect(mdService.deleteMaintenanceDomain(MDNAME1))
.andReturn(true).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1).request().delete();
assertEquals(200, response.getStatus());
}
@Test
public void testDeleteMdNotPresent() throws CfmConfigException {
expect(mdService.deleteMaintenanceDomain(MDNAME1))
.andReturn(false).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1).request().delete();
assertEquals(304, response.getStatus());
}
@Test
public void testCreateMd() throws CfmConfigException {
MaintenanceDomain md3 = DefaultMaintenanceDomain
.builder(MdIdCharStr.asMdId("md-3"))
.mdLevel(MaintenanceDomain.MdLevel.LEVEL3)
.mdNumericId((short) 3)
.build();
expect(mdService.createMaintenanceDomain(mdList.get(1)))
.andReturn(false).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("md", context.codec(MaintenanceDomain.class)
.encode(mdList.get(1), context));
final WebTarget wt = target();
final Response response = wt.path("md")
.request().post(Entity.json(node.toString()));
assertEquals(201, response.getStatus());
}
}

View File

@ -0,0 +1,378 @@
/*
* Copyright 2017-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.cfm.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.VlanId;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Optional;
import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class MepWebResourceTest extends CfmResourceTest {
private final CfmMepService mepService = createMock(CfmMepService.class);
private final CfmMdService mdService = createMock(CfmMdService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
private static final MepId MEPID1 = MepId.valueOf((short) 1);
private MepEntry mepEntry1 = null;
@Before
public void setUpTest() throws CfmConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMepService.class, mepService)
.add(CfmMdService.class, mdService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
mepEntry1 = DefaultMepEntry.builder(
MEPID1,
DeviceId.deviceId("netconf:1.2.3.4:830"),
PortNumber.portNumber(1),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
.buildEntry();
}
@Test
public void testGetAllMepsForMaEmpty() throws CfmConfigException {
expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(null).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep").request().get(String.class);
assertThat(response, is("{\"meps\":[[]]}"));
}
@Test
public void testGetAllMepsForMa1Mep() throws CfmConfigException {
Collection<MepEntry> meps = new ArrayList<>();
meps.add(mepEntry1);
expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(meps).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep").request().get(String.class);
assertThat(response, is("{\"meps\":" +
"[[{" +
"\"mepId\":" + MEPID1.value() + "," +
"\"deviceId\":\"netconf:1.2.3.4:830\"," +
"\"port\":1," +
"\"direction\":\"UP_MEP\"," +
"\"mdName\":\"" + MDNAME1.mdName() + "\"," +
"\"maName\":\"" + MANAME1.maName() + "\"," +
"\"administrative-state\":false," +
"\"cci-enabled\":false," +
"\"remoteMeps\":[]}]]}"));
}
@Test
public void testGetMepValid() throws CfmConfigException {
expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
.andReturn(mepEntry1).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value()).request().get(String.class);
assertThat(response, is("{\"mep\":" +
"{" +
"\"mepId\":" + MEPID1.value() + "," +
"\"deviceId\":\"netconf:1.2.3.4:830\"," +
"\"port\":1," +
"\"direction\":\"UP_MEP\"," +
"\"mdName\":\"" + MDNAME1.mdName() + "\"," +
"\"maName\":\"" + MANAME1.maName() + "\"," +
"\"administrative-state\":false," +
"\"cci-enabled\":false," +
"\"remoteMeps\":[]}}"));
}
@Test
public void testGetMepNotFound() throws CfmConfigException, IOException {
expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
.andReturn(null).anyTimes();
replay(mepService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + 2).request().get(String.class);
fail("Expected exception to be thrown");
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertEquals("{ \"failure\":\"MEP md-1/ma-1-1/2 not found\" }", sb.toString());
}
}
@Test
public void testDeleteMepValid() throws CfmConfigException {
expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
.andReturn(true).anyTimes();
replay(mepService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value()).request().delete();
assertEquals("Expecting 200", 200, response.getStatus());
}
@Test
public void testDeleteMepNotFound() throws CfmConfigException {
expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
.andReturn(false).anyTimes();
replay(mepService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/2").request().delete();
assertEquals("Expecting 304", 304, response.getStatus());
}
@Test
public void testCreateMep() throws CfmConfigException, IOException {
MepId mepId2 = MepId.valueOf((short) 2);
Mep mep2 = DefaultMep.builder(
mepId2,
DeviceId.deviceId("netconf:2.2.3.4:830"),
PortNumber.portNumber(2),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
expect(mepService.createMep(MDNAME1, MANAME1, mep2))
.andReturn(true).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(Mep.class).encode(mep2, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep")
.request()
.post(Entity.json(node.toString()));
assertEquals("Expecting 201", 201, response.getStatus());
}
@Test
public void testCreateMepAlreadyExists() throws CfmConfigException, IOException {
MepId mepId3 = MepId.valueOf((short) 3);
Mep mep3 = DefaultMep.builder(
mepId3,
DeviceId.deviceId("netconf:3.2.3.4:830"),
PortNumber.portNumber(3),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
.cciEnabled(true)
.ccmLtmPriority(Mep.Priority.PRIO3)
.administrativeState(false)
.primaryVid(VlanId.vlanId((short) 3))
.defectAbsentTime(Duration.ofMinutes(2))
.defectPresentTime(Duration.ofMinutes(3))
.fngAddress(Mep.FngAddress.notSpecified())
.lowestFaultPriorityDefect(Mep.LowestFaultDefect.ALL_DEFECTS)
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
expect(mepService.createMep(MDNAME1, MANAME1, mep3))
.andReturn(false).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(Mep.class).encode(mep3, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep")
.request()
.post(Entity.json(node.toString()));
assertEquals("Expecting 304", 304, response.getStatus());
}
@Test
public void testTransmitLoopback() throws CfmConfigException {
MepLbCreate mepLbCreate1 = DefaultMepLbCreate
.builder(MEPID1)
.numberMessages(20)
.dataTlvHex("AA:BB:CC:DD")
.vlanDropEligible(true)
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("loopback", context.codec(MepLbCreate.class).encode(mepLbCreate1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-loopback")
.request()
.put(Entity.json(node.toString()));
assertEquals("Expecting 202", 202, response.getStatus());
}
@Test
public void testAbortLoopback() throws CfmConfigException {
MepLbCreate mepLbCreate1 = DefaultMepLbCreate.builder(MEPID1).build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/abort-loopback")
.request()
.put(Entity.json(""));
assertEquals("Expecting 202", 202, response.getStatus());
}
@Test
public void testTransmitLinktrace() throws CfmConfigException {
MepLtCreate mepLtCreate1 = DefaultMepLtCreate
.builder(MEPID1)
.defaultTtl((short) 20)
.transmitLtmFlags(BitSet.valueOf(new byte[]{1}))
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("linktrace", context.codec(MepLtCreate.class).encode(mepLtCreate1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-linktrace")
.request()
.put(Entity.json(node.toString()));
assertEquals("Expecting 202", 202, response.getStatus());
}
}

View File

@ -0,0 +1,248 @@
/*
* Copyright 2017-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.cfm.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import static org.junit.Assert.assertEquals;
/**
* Test that the MaintenanceAssociationCodec can successfully parse Json in to a MaintenanceAssociation.
*/
public class MaintenanceAssociationCodecTest {
private static final MaIdShort MAID1_CHAR = MaIdCharStr.asMaId("ma-1");
private static final MaIdShort MAID2_VID = MaIdPrimaryVid.asMaId(1234);
private static final MaIdShort MAID3_OCTET = MaId2Octet.asMaId(12467);
private static final MaIdShort MAID4_RFC = MaIdRfc2685VpnId.asMaIdHex("aa:bb:cc:dd:ee:ff:99");
private static final MaIdShort MAID5_Y1731 = MaIdIccY1731.asMaId("abc", "defghij");
private ObjectMapper mapper;
private CfmCodecContext context;
@Before
public void setUp() throws Exception, CfmConfigException {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testDecodeMa1() throws IOException {
String mdString = "{\"ma\": { \"maName\": \"ma-1\"," +
"\"maNameType\": \"CHARACTERSTRING\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 1}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode1 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID1_CHAR, maDecode1.maId());
assertEquals(1, maDecode1.maNumericId());
}
@Test
public void testDecodeMa1NoTypeGiven() throws IOException {
String mdString = "{\"ma\": { \"maName\": \"ma-1\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 1}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode1 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID1_CHAR, maDecode1.maId());
assertEquals(1, maDecode1.maNumericId());
}
@Test
public void testDecodeMa2() throws IOException {
String mdString = "{\"ma\": { \"maName\": 1234," +
"\"maNameType\": \"PRIMARYVID\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 2}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode2 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID2_VID, maDecode2.maId());
}
@Test
public void testDecodeMa3() throws IOException {
String mdString = "{\"ma\": { \"maName\": 12467," +
"\"maNameType\": \"TWOOCTET\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 3}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode3 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID3_OCTET, maDecode3.maId());
}
@Test
public void testDecodeMa4() throws IOException {
String mdString = "{\"ma\": { \"maName\": \"aa:bb:cc:dd:ee:ff:99\"," +
"\"maNameType\": \"RFC2685VPNID\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 4}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode4 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID4_RFC, maDecode4.maId());
}
@Test
public void testDecodeMa5() throws IOException {
String mdString = "{\"ma\": { \"maName\": \"abc:defghij\"," +
"\"maNameType\": \"ICCY1731\"," +
"\"component-list\": [], " +
"\"rmep-list\": [], " +
"\"maNumericId\": 5}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceAssociation maDecode5 = ((MaintenanceAssociationCodec) context
.codec(MaintenanceAssociation.class))
.decode((ObjectNode) cfg, context, 10);
assertEquals(MAID5_Y1731, maDecode5.maId());
}
@Test
public void testEncodeMa1() throws CfmConfigException {
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation.builder(MAID1_CHAR, 10)
.maNumericId((short) 1)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class).encode(ma1, context));
assertEquals("{\"ma\":{" +
"\"maName\":\"ma-1\"," +
"\"maNameType\":\"CHARACTERSTRING\"," +
"\"maNumericId\":1," +
"\"component-list\":[]," +
"\"rmep-list\":[]}}", node.toString());
}
@Test
public void testEncodeMa2() throws CfmConfigException {
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation.builder(MAID2_VID, 10)
.maNumericId((short) 2)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class).encode(ma1, context));
assertEquals("{\"ma\":{" +
"\"maName\":\"1234\"," +
"\"maNameType\":\"PRIMARYVID\"," +
"\"maNumericId\":2," +
"\"component-list\":[]," +
"\"rmep-list\":[]}}", node.toString());
}
@Test
public void testEncodeMa3() throws CfmConfigException {
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation.builder(MAID3_OCTET, 10)
.maNumericId((short) 3)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class).encode(ma1, context));
assertEquals("{\"ma\":{" +
"\"maName\":\"12467\"," +
"\"maNameType\":\"TWOOCTET\"," +
"\"maNumericId\":3," +
"\"component-list\":[]," +
"\"rmep-list\":[]}}", node.toString());
}
@Test
public void testEncodeMa4() throws CfmConfigException {
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation.builder(MAID4_RFC, 10)
.maNumericId((short) 4)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class).encode(ma1, context));
assertEquals("{\"ma\":{" +
"\"maName\":\"aa:bb:cc:dd:ee:ff:99\"," +
"\"maNameType\":\"RFC2685VPNID\"," +
"\"maNumericId\":4," +
"\"component-list\":[]," +
"\"rmep-list\":[]}}", node.toString());
}
@Test
public void testEncodeMa5() throws CfmConfigException {
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation.builder(MAID5_Y1731, 10)
.maNumericId((short) 5)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("ma", context.codec(MaintenanceAssociation.class).encode(ma1, context));
assertEquals("{\"ma\":{" +
"\"maName\":\"abc:defghij\"," +
"\"maNameType\":\"ICCY1731\"," +
"\"maNumericId\":5," +
"\"component-list\":[]," +
"\"rmep-list\":[]}}", node.toString());
}
}

View File

@ -0,0 +1,197 @@
/*
* Copyright 2017-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.cfm.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.net.InternetDomainName;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.MacAddress;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import static org.junit.Assert.assertEquals;
/**
* Test that the MaintenanceDomainCodec can successfully parse Json in to a MaintenanceDomain.
*/
public class MaintenanceDomainCodecTest {
private static final MdId MDID1_CHAR = MdIdCharStr.asMdId("test-1");
private static final MdId MDID2_DOMAIN = MdIdDomainName.asMdId(
InternetDomainName.from("test.opennetworking.org"));
private static final MdId MDID3_MACUINT =
MdIdMacUint.asMdId(MacAddress.valueOf("aa:bb:cc:dd:ee:ff"), 181);
private static final MdId MDID4_NONE = MdIdNone.asMdId();
private ObjectMapper mapper;
private CfmCodecContext context;
@Before
public void setUp() throws Exception, CfmConfigException {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testDecodeMd1() throws IOException {
String mdString = "{\"md\": { \"mdName\": \"test-1\"," +
"\"mdNameType\": \"CHARACTERSTRING\"," +
"\"mdLevel\": \"LEVEL1\", \"mdNumericId\": 1}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain mdDecode1 = context
.codec(MaintenanceDomain.class).decode((ObjectNode) cfg, context);
assertEquals(MDID1_CHAR, mdDecode1.mdId());
assertEquals(MaintenanceDomain.MdLevel.LEVEL1, mdDecode1.mdLevel());
assertEquals(1, mdDecode1.mdNumericId());
}
@Test
public void testDecodeMd1NoTypeGiven() throws IOException {
String mdString = "{\"md\": { \"mdName\": \"test-1\"," +
"\"mdLevel\": \"LEVEL1\", \"mdNumericId\": 1}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain mdDecode1 = context
.codec(MaintenanceDomain.class).decode((ObjectNode) cfg, context);
assertEquals(MDID1_CHAR, mdDecode1.mdId());
assertEquals(MaintenanceDomain.MdLevel.LEVEL1, mdDecode1.mdLevel());
assertEquals(1, mdDecode1.mdNumericId());
}
@Test
public void testDecodeMd2() throws IOException {
String mdString = "{\"md\": { \"mdName\": \"test.opennetworking.org\"," +
"\"mdNameType\": \"DOMAINNAME\"}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain mdDecode1 = context
.codec(MaintenanceDomain.class).decode((ObjectNode) cfg, context);
assertEquals(MDID2_DOMAIN, mdDecode1.mdId());
assertEquals(MaintenanceDomain.MdLevel.LEVEL0, mdDecode1.mdLevel());
assertEquals(0, mdDecode1.mdNumericId());
}
@Test
public void testDecodeMd3() throws IOException {
String mdString = "{\"md\": { \"mdName\": \"aa:bb:cc:dd:ee:ff:181\"," +
"\"mdNameType\": \"MACANDUINT\"}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain mdDecode1 = context
.codec(MaintenanceDomain.class).decode((ObjectNode) cfg, context);
assertEquals(MDID3_MACUINT, mdDecode1.mdId());
}
@Test
public void testDecodeMd4() throws IOException {
String mdString = "{\"md\": { \"mdName\": \"\"," +
"\"mdNameType\": \"NONE\"}}";
InputStream input = new ByteArrayInputStream(
mdString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MaintenanceDomain mdDecode1 = context
.codec(MaintenanceDomain.class).decode((ObjectNode) cfg, context);
assertEquals(MDID4_NONE, mdDecode1.mdId());
}
@Test
public void testEncodeMd1() throws CfmConfigException {
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDID1_CHAR)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL1)
.mdNumericId((short) 1)
.build();
ObjectNode node = mapper.createObjectNode();
node.set("md", context.codec(MaintenanceDomain.class).encode(md1, context));
assertEquals("{\"md\":{" +
"\"mdName\":\"test-1\"," +
"\"mdNameType\":\"CHARACTERSTRING\"," +
"\"mdLevel\":\"LEVEL1\"," +
"\"mdNumericId\":1," +
"\"maList\":[]}}", node.toString());
}
@Test
public void testEncodeMd2() throws CfmConfigException {
MaintenanceDomain md2 = DefaultMaintenanceDomain.builder(MDID2_DOMAIN)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL2).build();
ObjectNode node = mapper.createObjectNode();
node.set("md", context.codec(MaintenanceDomain.class).encode(md2, context));
assertEquals("{\"md\":{" +
"\"mdName\":\"test.opennetworking.org\"," +
"\"mdNameType\":\"DOMAINNAME\"," +
"\"mdLevel\":\"LEVEL2\"," +
"\"maList\":[]}}", node.toString());
}
@Test
public void testEncodeMd3() throws CfmConfigException {
MaintenanceDomain md3 = DefaultMaintenanceDomain.builder(MDID3_MACUINT)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL3).build();
ObjectNode node = mapper.createObjectNode();
node.set("md", context.codec(MaintenanceDomain.class).encode(md3, context));
assertEquals("{\"md\":{" +
"\"mdName\":\"AA:BB:CC:DD:EE:FF:181\"," +
"\"mdNameType\":\"MACANDUINT\"," +
"\"mdLevel\":\"LEVEL3\"," +
"\"maList\":[]}}", node.toString());
}
@Test
public void testEncodeMd4() throws CfmConfigException {
MaintenanceDomain md4 = DefaultMaintenanceDomain.builder(MDID4_NONE)
.mdLevel(MaintenanceDomain.MdLevel.LEVEL4).build();
ObjectNode node = mapper.createObjectNode();
node.set("md", context.codec(MaintenanceDomain.class).encode(md4, context));
assertEquals("{\"md\":{" +
"\"mdName\":\"\"," +
"\"mdNameType\":\"NONE\"," +
"\"mdLevel\":\"LEVEL4\"," +
"\"maList\":[]}}", node.toString());
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright 2017-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.cfm.web;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.MacAddress;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepDirection;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry.MepEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Test that the MepEntryCodec can successfully parse Json in to a Mep.
*/
public class MepEntryCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
MepEntry mepEntry1;
@Before
public void setUp() throws Exception, CfmConfigException {
mapper = new ObjectMapper();
context = new CfmCodecContext();
MepEntryBuilder builder = DefaultMepEntry.builder(
MepId.valueOf((short) 22),
DeviceId.deviceId("netconf:1234:830"),
PortNumber.portNumber(2),
MepDirection.UP_MEP,
MdIdCharStr.asMdId("md-1"),
MaIdCharStr.asMaId("ma-1-1"))
.macAddress(MacAddress.valueOf("aa:bb:cc:dd:ee:ff"));
builder = (MepEntryBuilder) builder
.administrativeState(true)
.cciEnabled(true)
.ccmLtmPriority(Priority.PRIO1);
mepEntry1 = builder.buildEntry();
}
@Test
public void testEncodeMepEntryCodecContext() {
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(MepEntry.class).encode(mepEntry1, context));
assertEquals(22, node.get("mep").get("mepId").asInt());
assertEquals("aa:bb:cc:dd:ee:ff".toUpperCase(),
node.get("mep").get("macAddress").asText());
assertTrue(node.get("mep").get("administrative-state").asBoolean());
assertTrue(node.get("mep").get("cci-enabled").asBoolean());
assertEquals(Priority.PRIO1.ordinal(),
node.get("mep").get("ccm-ltm-priority").asInt());
}
@Test
public void testEncodeIterableOfMepEntryCodecContext() throws CfmConfigException {
MepEntry mepEntry2 = DefaultMepEntry.builder(
MepId.valueOf((short) 33),
DeviceId.deviceId("netconf:4321:830"),
PortNumber.portNumber(1),
MepDirection.DOWN_MEP,
MdIdCharStr.asMdId("md-2"),
MaIdCharStr.asMaId("ma-2-2"))
.buildEntry();
ArrayList<MepEntry> meps = new ArrayList<>();
meps.add(mepEntry1);
meps.add(mepEntry2);
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(MepEntry.class)
.encode(meps, context));
Iterator<JsonNode> an = node.get("mep").elements();
while (an.hasNext()) {
JsonNode jn = an.next();
assertEquals("md-", jn.get("mdName").asText().substring(0, 3));
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2017-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.cfm.web;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class MepLbCreateCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testDecodeMepLbCreateMepId() throws JsonProcessingException, IOException {
String loopbackString = "{\"loopback\": { \"remoteMepId\": 20," +
"\"numberMessages\": 10, \"vlanDropEligible\": true," +
"\"vlanPriority\": 6, \"dataTlvHex\": \"0A:BB:CC\" }}";
InputStream input = new ByteArrayInputStream(
loopbackString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MepLbCreate mepLbCreate = context
.codec(MepLbCreate.class).decode((ObjectNode) cfg, context);
assertNull(mepLbCreate.remoteMepAddress());
assertEquals(20, mepLbCreate.remoteMepId().id().shortValue());
assertEquals(10, mepLbCreate.numberMessages().intValue());
assertEquals(6, mepLbCreate.vlanPriority().ordinal());
assertEquals(true, mepLbCreate.vlanDropEligible());
assertEquals("0A:BB:CC".toLowerCase(), mepLbCreate.dataTlvHex());
}
@Test
public void testDecodeMepLbCreateMepMac() throws JsonProcessingException, IOException {
String loopbackString = "{\"loopback\": { " +
"\"remoteMepMac\": \"AA:BB:CC:DD:EE:FF\" }}";
InputStream input = new ByteArrayInputStream(
loopbackString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MepLbCreate mepLbCreate = context
.codec(MepLbCreate.class).decode((ObjectNode) cfg, context);
assertNull(mepLbCreate.remoteMepId());
assertEquals("AA:BB:CC:DD:EE:FF", mepLbCreate.remoteMepAddress().toString());
assertNull(mepLbCreate.dataTlvHex());
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2017-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.cfm.web;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MepLbEntryCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testEncodeMepLbEntryCodecContext() {
MepLbEntry mepLbEntry1 = DefaultMepLbEntry.builder()
.countLbrMacMisMatch(987654321L)
.countLbrReceived(987654322L)
.countLbrTransmitted(987654323L)
.countLbrValidInOrder(987654324L)
.countLbrValidOutOfOrder(987654325L)
.nextLbmIdentifier(987654326L)
.build();
assertEquals(987654321L, mepLbEntry1.countLbrMacMisMatch());
assertEquals(987654322L, mepLbEntry1.countLbrReceived());
assertEquals(987654323L, mepLbEntry1.countLbrTransmitted());
assertEquals(987654324L, mepLbEntry1.countLbrValidInOrder());
assertEquals(987654325L, mepLbEntry1.countLbrValidOutOfOrder());
assertEquals(987654326L, mepLbEntry1.nextLbmIdentifier());
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2017-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.cfm.web;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.BitSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class MepLtCreateCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testDecodeMepLtCreateMepId() throws JsonProcessingException, IOException {
String linktraceString = "{\"linktrace\": { " +
"\"remoteMepId\": 20," +
"\"defaultTtl\": 21," +
"\"transmitLtmFlags\": \"use-fdb-only\"}}";
InputStream input = new ByteArrayInputStream(
linktraceString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
MepLtCreate mepLtCreate = context
.codec(MepLtCreate.class).decode((ObjectNode) cfg, context);
assertNull(mepLtCreate.remoteMepAddress());
assertEquals(20, mepLtCreate.remoteMepId().id().shortValue());
assertEquals(21, mepLtCreate.defaultTtl().intValue());
assertEquals(BitSet.valueOf(new byte[]{1}), mepLtCreate.transmitLtmFlags());
}
@Test
public void testDecodeMepLtCreateInvalidTransmitLtmFlags()
throws JsonProcessingException, IOException {
String linktraceString = "{\"linktrace\": { " +
"\"remoteMepId\": 20," +
"\"transmitLtmFlags\": \"1\"}}";
InputStream input = new ByteArrayInputStream(
linktraceString.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
try {
context.codec(MepLtCreate.class).decode((ObjectNode) cfg, context);
} catch (IllegalArgumentException e) {
assertEquals("Expecting value 'use-fdb-only' or '' " +
"for transmitLtmFlags", e.getMessage());
}
}
@Test
public void testEncodeMepLtCreate() {
MepId mepId1 = MepId.valueOf((short) 1);
MepLtCreate mepLtCreate1 = DefaultMepLtCreate
.builder(mepId1)
.defaultTtl((short) 20)
.transmitLtmFlags(BitSet.valueOf(new byte[]{1}))
.build();
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("linktrace", context.codec(MepLtCreate.class).encode(mepLtCreate1, context));
assertEquals("{\"linktrace\":{" +
"\"remoteMepId\":1," +
"\"defaultTtl\":20," +
"\"transmitLtmFlags\":\"use-fdb-only\"}}", node.toString());
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2017-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.cfm.web;
import static org.junit.Assert.assertEquals;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.MacAddress;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultRemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.InterfaceStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.PortStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepState;
import org.onosproject.incubator.net.l2monitoring.cfm.SenderIdTlv.SenderIdTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class RemoteMepEntryCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
RemoteMepEntry remoteMep1;
@Before
public void setUp() throws Exception, CfmConfigException {
mapper = new ObjectMapper();
context = new CfmCodecContext();
remoteMep1 = DefaultRemoteMepEntry
.builder(MepId.valueOf((short) 10), RemoteMepState.RMEP_OK)
.failedOrOkTime(Duration.ofMillis(546546546L))
.interfaceStatusTlvType(InterfaceStatusTlvType.IS_LOWERLAYERDOWN)
.macAddress(MacAddress.IPV4_MULTICAST)
.portStatusTlvType(PortStatusTlvType.PS_NO_STATUS_TLV)
.rdi(true)
.senderIdTlvType(SenderIdTlvType.SI_NETWORK_ADDRESS)
.build();
}
@Test
public void testEncodeRemoteMepEntryCodecContext() {
ObjectNode node = mapper.createObjectNode();
node.set("remoteMep", context.codec(RemoteMepEntry.class)
.encode(remoteMep1, context));
assertEquals(10, node.get("remoteMep").get("remoteMepId").asInt());
}
@Test
public void testEncodeIterableOfRemoteMepEntryCodecContext()
throws CfmConfigException {
RemoteMepEntry remoteMep2 = DefaultRemoteMepEntry
.builder(MepId.valueOf((short) 20), RemoteMepState.RMEP_IDLE)
.build();
ArrayList<RemoteMepEntry> remoteMeps = new ArrayList<>();
remoteMeps.add(remoteMep1);
remoteMeps.add(remoteMep2);
ObjectNode node = mapper.createObjectNode();
node.set("remoteMep", context.codec(RemoteMepEntry.class)
.encode(remoteMeps, context));
Iterator<JsonNode> an = node.get("remoteMep").elements();
while (an.hasNext()) {
JsonNode jn = an.next();
assertEquals("RMEP_", jn.get("remoteMepState").asText().substring(0, 5));
}
}
}

View File

@ -0,0 +1,299 @@
/*
* Copyright 2017-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.soam.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.cfm.impl.CfmResourceTest;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class DmWebResourceTest extends CfmResourceTest {
private final CfmMepService mepService = createMock(CfmMepService.class);
private final SoamService soamService = createMock(SoamService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
private static final MepId MEPID1 = MepId.valueOf((short) 1);
private static final SoamId DM1 = SoamId.valueOf(1);
private static final SoamId DM2 = SoamId.valueOf(2);
private DelayMeasurementEntry dm1;
private DelayMeasurementEntry dm2;
private final Instant now = Instant.now();
@Before
public void setUpTest() throws CfmConfigException, SoamConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMepService.class, mepService)
.add(SoamService.class, soamService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
DelayMeasurementStatCurrent.DmStatCurrentBuilder dmCurrBuilder1 =
(DelayMeasurementStatCurrent.DmStatCurrentBuilder)
DefaultDelayMeasurementStatCurrent
.builder(Duration.ofMinutes(1), false)
.startTime(now)
.frameDelayBackwardAvg(Duration.ofMillis(10))
.frameDelayForwardAvg(Duration.ofMillis(11))
.frameDelayRangeBackwardAvg(Duration.ofMillis(12));
dm1 = DefaultDelayMeasurementEntry.builder(DM1,
DelayMeasurementCreate.DmType.DMDMM,
DelayMeasurementCreate.Version.Y17312008,
MepId.valueOf((short) 2),
Mep.Priority.PRIO1)
.sessionStatus(DelayMeasurementEntry.SessionStatus.ACTIVE)
.frameDelayTwoWay(Duration.ofMillis(40))
.frameDelayBackward(Duration.ofMillis(30))
.frameDelayForward(Duration.ofMillis(10))
.interFrameDelayVariationTwoWay(Duration.ofMillis(8))
.interFrameDelayVariationBackward(Duration.ofMillis(3))
.interFrameDelayVariationForward(Duration.ofMillis(5))
.currentResult((DelayMeasurementStatCurrent) dmCurrBuilder1.build())
.build();
dm2 = DefaultDelayMeasurementEntry.builder(DM2,
DelayMeasurementCreate.DmType.DMDMM,
DelayMeasurementCreate.Version.Y17312011,
MepId.valueOf((short) 2),
Mep.Priority.PRIO2)
.build();
}
@Test
public void testGetAllDmsForMep() throws CfmConfigException, SoamConfigException {
List<DelayMeasurementEntry> dmList = new ArrayList<>();
dmList.add(dm1);
dmList.add(dm2);
expect(soamService.getAllDms(MDNAME1, MANAME1, MEPID1)).andReturn(dmList).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm")
.request().get(String.class);
assertThat(response, is("{\"dms\":[[" +
"{" +
"\"dmId\":\"1\"," +
"\"sessionStatus\":\"ACTIVE\"," +
"\"frameDelayTwoWay\":\"PT0.04S\"," +
"\"frameDelayForward\":\"PT0.01S\"," +
"\"frameDelayBackward\":\"PT0.03S\"," +
"\"interFrameDelayVariationTwoWay\":\"PT0.008S\"," +
"\"interFrameDelayVariationForward\":\"PT0.005S\"," +
"\"interFrameDelayVariationBackward\":\"PT0.003S\"," +
"\"dmCfgType\":\"DMDMM\"," +
"\"version\":\"Y17312008\"," +
"\"remoteMepId\":2," +
"\"priority\":\"PRIO1\"," +
"\"measurementsEnabled\":[]," +
"\"current\":{" +
"\"startTime\":\"" + now + "\"," +
"\"elapsedTime\":\"PT1M\"," +
"\"suspectStatus\":\"false\"," +
"\"frameDelayForwardAvg\":\"PT0.011S\"," +
"\"frameDelayBackwardAvg\":\"PT0.01S\"," +
"\"frameDelayRangeBackwardAvg\":\"PT0.012S\"" +
"}," +
"\"historic\":[]" +
"},{" +
"\"dmId\":\"2\"," +
"\"dmCfgType\":\"DMDMM\"," +
"\"version\":\"Y17312011\"," +
"\"remoteMepId\":2," +
"\"priority\":\"PRIO2\"," +
"\"measurementsEnabled\":[]," +
"\"historic\":[]}]]" +
"}"));
}
@Test
public void testGetAllDmsForMepEmpty() throws CfmConfigException, SoamConfigException {
List<DelayMeasurementEntry> dmListEmpty = new ArrayList<>();
expect(soamService.getAllDms(MDNAME1, MANAME1, MEPID1)).andReturn(dmListEmpty).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm")
.request().get(String.class);
assertThat(response, is("{\"dms\":[[]]}"));
}
@Test
public void testGetDm() throws CfmConfigException, SoamConfigException {
expect(soamService.getDm(MDNAME1, MANAME1, MEPID1, DM1)).andReturn(dm1).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm/" + DM1.value())
.request().get(String.class);
assertThat(response, is("{\"dm\":" +
"{" +
"\"dmId\":\"1\"," +
"\"sessionStatus\":\"ACTIVE\"," +
"\"frameDelayTwoWay\":\"PT0.04S\"," +
"\"frameDelayForward\":\"PT0.01S\"," +
"\"frameDelayBackward\":\"PT0.03S\"," +
"\"interFrameDelayVariationTwoWay\":\"PT0.008S\"," +
"\"interFrameDelayVariationForward\":\"PT0.005S\"," +
"\"interFrameDelayVariationBackward\":\"PT0.003S\"," +
"\"dmCfgType\":\"DMDMM\"," +
"\"version\":\"Y17312008\"," +
"\"remoteMepId\":2," +
"\"priority\":\"PRIO1\"," +
"\"measurementsEnabled\":[]," +
"\"current\":{" +
"\"startTime\":\"" + now + "\"," +
"\"elapsedTime\":\"PT1M\"," +
"\"suspectStatus\":\"false\"," +
"\"frameDelayForwardAvg\":\"PT0.011S\"," +
"\"frameDelayBackwardAvg\":\"PT0.01S\"," +
"\"frameDelayRangeBackwardAvg\":\"PT0.012S\"" +
"}," +
"\"historic\":[]" +
"}}"));
}
@Test
public void testGetDmInvalid() throws CfmConfigException, SoamConfigException, IOException {
SoamId dm3 = SoamId.valueOf(3);
expect(soamService.getDm(MDNAME1, MANAME1, MEPID1, dm3)).andReturn(null).anyTimes();
replay(soamService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm/" + dm3.value())
.request().get(String.class);
fail("Expecting excpetion");
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertEquals("{ \"failure\":\"DM md-1/ma-1-1/1/3 not found\" }", sb.toString());
}
}
@Test
public void testAbortDm() {
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm/" + DM1.value())
.request().delete();
assertEquals(200, response.getStatus());
}
@Test
public void testCreateDm() throws CfmConfigException, SoamConfigException {
MepEntry mep1 = DefaultMepEntry.builder(MEPID1, DeviceId.deviceId("netconf:1.2.3.4:830"),
PortNumber.portNumber(1), Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).buildEntry();
expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("dm", context.codec(DelayMeasurementCreate.class).encode(dm1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm")
.request().post(Entity.json(node.toString()));
assertEquals(201, response.getStatus());
}
@Test
public void testClearDmHistory() {
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/dm/" + DM1.value() +
"/clear-history")
.request().put(Entity.json(""));
assertEquals(200, response.getStatus());
}
}

View File

@ -0,0 +1,262 @@
/*
* Copyright 2017-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.soam.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.cfm.impl.CfmResourceTest;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.incubator.net.l2monitoring.soam.MilliPct;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.DefaultLmEntry;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class LmWebResourceTest extends CfmResourceTest {
private final CfmMepService mepService = createMock(CfmMepService.class);
private final SoamService soamService = createMock(SoamService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
private static final MepId MEPID1 = MepId.valueOf((short) 1);
private static final SoamId LMID1 = SoamId.valueOf(1);
private static final SoamId LMID2 = SoamId.valueOf(2);
private LossMeasurementEntry lm1;
private LossMeasurementEntry lm2;
private final Instant now = Instant.now();
@Before
public void setUpTest() throws CfmConfigException, SoamConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMepService.class, mepService)
.add(SoamService.class, soamService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
lm1 = DefaultLmEntry.builder(
DelayMeasurementCreate.Version.Y17312008,
MepId.valueOf((short) 10),
Mep.Priority.PRIO1,
LossMeasurementCreate.LmType.LMLMM,
LMID1)
.build();
lm2 = DefaultLmEntry.builder(
DelayMeasurementCreate.Version.Y17312011,
MepId.valueOf((short) 10),
Mep.Priority.PRIO2,
LossMeasurementCreate.LmType.LMLMM,
LMID2)
.measuredAvailabilityBackwardStatus(LossMeasurementEntry.AvailabilityType.AVAILABLE)
.measuredAvailabilityForwardStatus(LossMeasurementEntry.AvailabilityType.UNKNOWN)
.measuredBackwardFlr(MilliPct.ofPercent(49.9f))
.measuredForwardFlr(MilliPct.ofRatio(0.51f))
.measuredBackwardLastTransitionTime(now)
.measuredForwardLastTransitionTime(now)
.build();
}
@Test
public void testGetAllLmsForMep() throws CfmConfigException, SoamConfigException {
List<LossMeasurementEntry> lmList = new ArrayList<>();
lmList.add(lm1);
lmList.add(lm2);
expect(soamService.getAllLms(MDNAME1, MANAME1, MEPID1)).andReturn(lmList).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm")
.request().get(String.class);
assertThat(response, is("{\"lms\":[[" +
"{" +
"\"lmId\":\"1\"," +
"\"lmCfgType\":\"LMLMM\"," +
"\"version\":\"Y17312008\"," +
"\"remoteMepId\":10," +
"\"priority\":\"PRIO1\"," +
"\"countersEnabled\":[]," +
"\"measurementHistories\":[]," +
"\"availabilityHistories\":[]" +
"},{" +
"\"lmId\":\"2\"," +
"\"measuredForwardFlr\":51.0," +
"\"measuredBackwardFlr\":49.9," +
"\"measuredAvailabilityForwardStatus\":\"UNKNOWN\"," +
"\"measuredAvailabilityBackwardStatus\":\"AVAILABLE\"," +
"\"measuredForwardLastTransitionTime\":\"" + now + "\"," +
"\"measuredBackwardLastTransitionTime\":\"" + now + "\"," +
"\"lmCfgType\":\"LMLMM\"," +
"\"version\":\"Y17312011\"," +
"\"remoteMepId\":10," +
"\"priority\":\"PRIO2\"," +
"\"countersEnabled\":[]," +
"\"measurementHistories\":[]," +
"\"availabilityHistories\":[]" +
"}]]}"));
}
@Test
public void testGetAllLmsForMepEmpty() throws CfmConfigException, SoamConfigException {
List<LossMeasurementEntry> lmList = new ArrayList<>();
expect(soamService.getAllLms(MDNAME1, MANAME1, MEPID1)).andReturn(lmList).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm")
.request().get(String.class);
assertThat(response, is("{\"lms\":[[]]}"));
}
@Test
public void testGetLm() throws CfmConfigException, SoamConfigException {
expect(soamService.getLm(MDNAME1, MANAME1, MEPID1, LMID1)).andReturn(lm1).anyTimes();
replay(soamService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm/" + LMID1.value())
.request().get(String.class);
assertThat(response, is("{\"lm\":" +
"{" +
"\"lmId\":\"1\"," +
"\"lmCfgType\":\"LMLMM\"," +
"\"version\":\"Y17312008\"," +
"\"remoteMepId\":10," +
"\"priority\":\"PRIO1\"," +
"\"countersEnabled\":[]," +
"\"measurementHistories\":[]," +
"\"availabilityHistories\":[]" +
"}}"));
}
@Test
public void testGetLmEmpty() throws CfmConfigException, SoamConfigException, IOException {
SoamId lmId3 = SoamId.valueOf(3);
expect(soamService.getLm(MDNAME1, MANAME1, MEPID1, lmId3))
.andReturn(null).anyTimes();
replay(soamService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm/" + lmId3.value())
.request().get(String.class);
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertEquals("{ \"failure\":\"LM md-1/ma-1-1/1/3 not found\" }",
sb.toString());
}
}
@Test
public void testAbortLm() {
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm/" + LMID1.value())
.request().delete();
assertEquals(200, response.getStatus());
}
@Test
public void testCreateLm() throws CfmConfigException, SoamConfigException {
MepEntry mep1 = DefaultMepEntry.builder(MEPID1, DeviceId.deviceId("netconf:1.2.3.4:830"),
PortNumber.portNumber(1), Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).buildEntry();
expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("lm", context.codec(LossMeasurementCreate.class).encode(lm1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm")
.request().post(Entity.json(node.toString()));
assertEquals(201, response.getStatus());
}
@Test
public void testClearLmHistory() {
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/lm/" + LMID1.value() +
"/clear-history")
.request().put(Entity.json(""));
assertEquals(200, response.getStatus());
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright 2017-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.soam.web;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmCreateBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmType;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.Version;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class DmCreateCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testDecodeObjectNodeCodecContext1()
throws JsonProcessingException, IOException {
String moStr = "{\"dm\": {}}";
InputStream input = new ByteArrayInputStream(
moStr.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
try {
context.codec(DelayMeasurementCreate.class)
.decode((ObjectNode) cfg, context);
fail("Expecting an exception");
} catch (IllegalArgumentException e) {
assertEquals("remoteMepId is required", e.getMessage());
}
}
@Test
public void testDecodeObjectNodeCodecContext2()
throws JsonProcessingException, IOException {
String moStr = "{\"dm\": {" +
"\"version\":\"Y17312008\"," +
"\"dmType\":\"DMDMM\"," +
"\"remoteMepId\":12," +
"\"priority\":\"PRIO6\"," +
"\"measurementsEnabled\" :" +
"[\"FRAME_DELAY_RANGE_BACKWARD_AVERAGE\", " +
"\"INTER_FRAME_DELAY_VARIATION_FORWARD_AVERAGE\"]" +
"}}";
InputStream input = new ByteArrayInputStream(
moStr.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
DelayMeasurementCreate dmCreate = context
.codec(DelayMeasurementCreate.class)
.decode((ObjectNode) cfg, context);
assertEquals(Version.Y17312008, dmCreate.version());
assertEquals(DmType.DMDMM, dmCreate.dmCfgType());
assertEquals(12, dmCreate.remoteMepId().id().shortValue());
}
@Test
public void testEncodeDelayMeasurementCreateCodecContext()
throws SoamConfigException {
DmCreateBuilder builder = DefaultDelayMeasurementCreate
.builder(DmType.DM1DMRX, Version.Y17312011,
MepId.valueOf((short) 16), Priority.PRIO5);
builder.addToMeasurementsEnabled(
MeasurementOption.FRAME_DELAY_BACKWARD_MAX);
builder.addToMeasurementsEnabled(
MeasurementOption.FRAME_DELAY_TWO_WAY_MAX);
builder.addToMeasurementsEnabled(
MeasurementOption.INTER_FRAME_DELAY_VARIATION_BACKWARD_BINS);
builder = (DmCreateBuilder) builder.messagePeriod(Duration.ofMillis(100));
builder = (DmCreateBuilder) builder.frameSize((short) 1200);
ObjectNode node = mapper.createObjectNode();
node.set("dm", context.codec(DelayMeasurementCreate.class)
.encode(builder.build(), context));
assertEquals(DmType.DM1DMRX.name(), node.get("dm").get("dmCfgType").asText());
assertEquals(Version.Y17312011.name(), node.get("dm").get("version").asText());
assertEquals(16, node.get("dm").get("remoteMepId").asInt());
assertEquals(Priority.PRIO5.name(), node.get("dm").get("priority").asText());
assertEquals(100, node.get("dm").get("messagePeriodMs").asInt());
assertEquals(1200, node.get("dm").get("frameSize").asInt());
assertEquals(3, ((ArrayNode) node.get("dm").get("measurementsEnabled")).size());
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright 2017-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.soam.web;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmType;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.Version;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry.DmEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry.SessionStatus;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class DmEntryCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
DelayMeasurementEntry dmEntry1;
@Before
public void setUp() throws Exception, SoamConfigException {
mapper = new ObjectMapper();
context = new CfmCodecContext();
DmEntryBuilder builder = DefaultDelayMeasurementEntry
.builder(SoamId.valueOf(12), DmType.DM1DMTX,
Version.Y17312008, MepId.valueOf((short) 10), Priority.PRIO4);
builder = builder.sessionStatus(SessionStatus.NOT_ACTIVE);
builder = builder.frameDelayTwoWay(Duration.ofNanos(101 * 1000));
builder = builder.frameDelayForward(Duration.ofNanos(102 * 1000));
builder = builder.frameDelayBackward(Duration.ofNanos(103 * 1000));
builder = builder.interFrameDelayVariationTwoWay(Duration.ofNanos(104 * 1000));
builder = builder.interFrameDelayVariationForward(Duration.ofNanos(105 * 1000));
builder = builder.interFrameDelayVariationBackward(Duration.ofNanos(106 * 1000));
builder.addToMeasurementsEnabled(MeasurementOption.FRAME_DELAY_BACKWARD_MAX);
builder.addToMeasurementsEnabled(MeasurementOption.FRAME_DELAY_TWO_WAY_MAX);
builder.addToMeasurementsEnabled(MeasurementOption.INTER_FRAME_DELAY_VARIATION_BACKWARD_BINS);
dmEntry1 = builder.build();
}
@Test
public void testEncodeDelayMeasurementEntryCodecContext()
throws JsonProcessingException, IOException {
ObjectNode node = mapper.createObjectNode();
node.set("dm", context.codec(DelayMeasurementEntry.class)
.encode(dmEntry1, context));
assertEquals(12, node.get("dm").get("dmId").asInt());
assertEquals(DmType.DM1DMTX.name(), node.get("dm").get("dmCfgType").asText());
assertEquals(Version.Y17312008.name(), node.get("dm").get("version").asText());
assertEquals(10, node.get("dm").get("remoteMepId").asInt());
assertEquals(3, ((ArrayNode) node.get("dm").get("measurementsEnabled")).size());
assertEquals(SessionStatus.NOT_ACTIVE.name(),
node.get("dm").get("sessionStatus").asText());
assertEquals("PT0.000101S",
node.get("dm").get("frameDelayTwoWay").asText());
assertEquals("PT0.000102S",
node.get("dm").get("frameDelayForward").asText());
assertEquals("PT0.000103S",
node.get("dm").get("frameDelayBackward").asText());
assertEquals("PT0.000104S",
node.get("dm").get("interFrameDelayVariationTwoWay").asText());
assertEquals("PT0.000105S",
node.get("dm").get("interFrameDelayVariationForward").asText());
assertEquals("PT0.000106S",
node.get("dm").get("interFrameDelayVariationBackward").asText());
}
@Test
public void testEncodeIterableOfDelayMeasurementEntryCodecContext()
throws SoamConfigException {
DmEntryBuilder builder2 = DefaultDelayMeasurementEntry
.builder(SoamId.valueOf(14), DmType.DM1DMRX,
Version.Y17312011, MepId.valueOf((short) 16), Priority.PRIO5);
builder2.addToMeasurementsEnabled(MeasurementOption.FRAME_DELAY_BACKWARD_MIN);
builder2.addToMeasurementsEnabled(MeasurementOption.FRAME_DELAY_TWO_WAY_MIN);
builder2.addToMeasurementsEnabled(MeasurementOption.INTER_FRAME_DELAY_VARIATION_BACKWARD_MIN);
Collection<DelayMeasurementEntry> dmEntries = new ArrayList<>();
dmEntries.add(dmEntry1);
dmEntries.add(builder2.build());
ObjectNode node = mapper.createObjectNode();
node.set("dm", context.codec(DelayMeasurementEntry.class)
.encode(dmEntries, context));
assertEquals(2, ((ArrayNode) node.get("dm")).size());
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2017-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.soam.web;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
public class DmMeasurementOptionCodecTest {
ObjectMapper mapper;
CfmCodecContext context;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
context = new CfmCodecContext();
}
@Test
public void testEncodeIterableOfMeasurementOptionCodecContext() {
List<MeasurementOption> moList = new ArrayList<>();
moList.add(MeasurementOption.FRAME_DELAY_BACKWARD_MAX);
moList.add(MeasurementOption.FRAME_DELAY_FORWARD_BINS);
ArrayNode an =
context.codec(MeasurementOption.class).encode(moList, context);
assertEquals(MeasurementOption.FRAME_DELAY_BACKWARD_MAX.toString(),
an.get(0).asText());
assertEquals(MeasurementOption.FRAME_DELAY_FORWARD_BINS.toString(),
an.get(1).asText());
}
@Test
public void testDecodeArrayNodeCodecContext()
throws JsonProcessingException, IOException {
String moStr = "{\"measurementsEnabled\": " +
"[\"FRAME_DELAY_RANGE_BACKWARD_AVERAGE\", " +
"\"INTER_FRAME_DELAY_VARIATION_FORWARD_AVERAGE\"]}";
InputStream input = new ByteArrayInputStream(
moStr.getBytes(StandardCharsets.UTF_8));
JsonNode cfg = mapper.readTree(input);
Iterable<MeasurementOption> moIter = context
.codec(MeasurementOption.class)
.decode((ArrayNode) cfg.get("measurementsEnabled"), context);
Iterator<MeasurementOption> source = moIter.iterator();
List<MeasurementOption> moList = new ArrayList<>();
source.forEachRemaining(moList::add);
assertEquals(MeasurementOption.FRAME_DELAY_RANGE_BACKWARD_AVERAGE.toString(),
moList.get(0).name());
assertEquals(MeasurementOption.INTER_FRAME_DELAY_VARIATION_FORWARD_AVERAGE.toString(),
moList.get(1).name());
}
}

View File

@ -0,0 +1,18 @@
{
"dm": {
"remoteMepId":20,
"dmCfgType": "DMDMM",
"version": "Y17312008",
"priority": "PRIO1",
"messagePeriodMs": 100,
"startTime": {
"immediate":true
},
"stopTime": {
"none":true
},
"frameSize": 1500,
"measurementIntervalMins": 1,
"measurementsEnabled": ["FRAME_DELAY_TWO_WAY_BINS","FRAME_DELAY_TWO_WAY_AVERAGE"]
}
}

View File

@ -0,0 +1,23 @@
{
"ma": {
"maName": "ma-vlan-1",
"maNameType": "CHARACTERSTRING",
"maNumericId": 1,
"ccm-interval": "INTERVAL_1S",
"component-list": [
{ "component": {
"component-id":"1",
"tag-type": "VLAN_STAG",
"vid-list": [
{"vid":1}
]
}
}
],
"rmep-list": [
{ "rmep":10 },
{ "rmep":20 },
{ "rmep":30 }
]
}
}

View File

@ -0,0 +1,22 @@
{
"ma": {
"maName": "ma-vlan-2",
"maNameType": "CHARACTERSTRING",
"maNumericId": 2,
"ccm-interval": "INTERVAL_1S",
"component-list": [
{ "component": {
"component-id":"1",
"tag-type": "VLAN_STAG",
"vid-list": [
{"vid":2}
]
}
}
],
"rmep-list": [
{ "rmep":10 },
{ "rmep":20 }
]
}
}

View File

@ -0,0 +1,7 @@
{"md": {
"mdName": "DomainA",
"mdNameType": "CHARACTERSTRING",
"mdLevel": "LEVEL3",
"mdNumeridId": 1
}
}

View File

@ -0,0 +1,14 @@
{
"mep": {
"mepId": 10,
"deviceId": "netconf:192.168.56.10:830",
"port": 0,
"direction": "DOWN_MEP",
"mdName": "DomainA",
"maName": "ma-vlan-1",
"primary-vid": 1,
"administrative-state": true,
"ccm-ltm-priority": 4,
"cci-enabled" :true
}
}

View File

@ -0,0 +1,12 @@
Run:
* curl --user onos:rocks -d @CreateMdDomainA.json http://localhost:8181/onos/cfm/md --header "Content-Type:application/json"
* curl --user onos:rocks -d @CreateMa1InDomainA.json http://localhost:8181/onos/cfm/md/DomainA/ma --header "Content-Type:application/json"
* curl --user onos:rocks -d @CreateMa2InDomainA.json http://localhost:8181/onos/cfm/md/DomainA/ma --header "Content-Type:application/json"
* curl --user onos:rocks http://localhost:8181/onos/cfm/md
Create a Device that supports CFM Programmable, say at netconf:192.168.56.10:830
* curl --user onos:rocks -d @CreateMep10.json http://localhost:8181/onos/cfm/md/DomainA/ma/ma-vlan-1/mep --header "Content-Type:application/json"
Now call the RPC to create a Delay Measurement on that device
* curl --user onos:rocks -X PUT -d @CreateDM_Mep10.json http://localhost:8181/onos/cfm/md/DomainA/ma/ma-vlan-1/mep/10/dm --header "Content-Type:application/json"

View File

@ -97,6 +97,7 @@
<module>evpn-route-service</module>
<module>l3vpn</module>
<module>openstacknetworkingui</module>
<module>cfm</module>
</modules>
<properties>

View File

@ -13,7 +13,8 @@ TEST_DEPS = [
'//lib:TEST_ADAPTERS',
'//core/api:onos-api-tests',
'//drivers/netconf:onos-drivers-netconf-tests',
'//utils/osgi:onlab-osgi-tests'
'//utils/osgi:onlab-osgi-tests',
'//incubator/net:onos-incubator-net'
]
APPS = [

View File

@ -48,6 +48,11 @@
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-yang-model</artifactId>
@ -133,6 +138,12 @@
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-net</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,610 @@
/*
* Copyright 2017-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.microsemi;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.time.Duration;
import java.util.Collection;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.HexString;
import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
import org.onosproject.drivers.microsemi.yang.utils.MaNameUtil;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultRemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepDirection;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry.MepLbEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.InterfaceStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.PortStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepState;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.ietfinettypes.DomainName;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.MefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.DefaultAbortLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.faultalarmdefectbitstype.Bits;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.DefaultMaintenanceDomain;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.DefaultMaintenanceAssociation;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.MdNameAndTypeCombo;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.CcmIntervalEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.ComponentList;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultComponentList;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaNameAndTypeCombo;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.componentlist.TagTypeEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.ContinuityCheck;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultContinuityCheck;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.InterfaceEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultMacAddressAndUint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameCharacterString;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameDomainName;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameNone;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.namedomainname.NameDomainNameUnion;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.remotemepstatetype.RemoteMepStateTypeEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMacAddress;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMepId;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.DefaultTransmitLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.DefaultTargetAddress;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.TargetAddress;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MacAddressAndUintStr;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MdLevelType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MepIdType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.PriorityType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
import org.slf4j.Logger;
/**
* Implementation of CfmMepProgrammable for Microsemi EA1000.
*/
public class EA1000CfmMepProgrammable extends AbstractHandlerBehaviour
implements CfmMepProgrammable {
private static final int NUMERIC_ID_MAX = 64;
private static final int REMOTEMEPLIST_MIN_COUNT = 2;
private static final int REMOTEMEPLIST_MAX_COUNT = 9;
private static final int COMPONENT_LIST_SIZE = 1;
private static final int VIDLIST_SIZE_MIN = 1;
private static final int MEP_PORT_MIN = 0;
private static final int MEP_PORT_MAX = 1;
private final Logger log = getLogger(getClass());
public EA1000CfmMepProgrammable() {
log.debug("Loaded handler behaviour EA1000CfmMepProgrammable");
}
@Override
public boolean createMep(MdId mdName, MaIdShort maName, Mep mep)
throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
MaintenanceAssociationEndPoint yangMep = buildYangMepFromApiMep(mep);
CfmMdService cfmMdService = checkNotNull(handler().get(CfmMdService.class));
MaintenanceDomain md = cfmMdService.getMaintenanceDomain(mdName).get();
MaintenanceAssociation ma = cfmMdService.getMaintenanceAssociation(mdName, maName).get();
if (!ma.remoteMepIdList().contains(mep.mepId())) {
throw new CfmConfigException("Mep Id " + mep.mepId() +
" is not present in the remote Mep list for MA " + ma.maId() +
". This is required for EA1000.");
} else if (md.mdNumericId() <= 0 || md.mdNumericId() > NUMERIC_ID_MAX) {
throw new CfmConfigException("Numeric id of MD " + mdName + " must"
+ " be between 1 and 64 inclusive for EA1000");
} else if (ma.maNumericId() <= 0 || ma.maNumericId() > NUMERIC_ID_MAX) {
throw new CfmConfigException("Numeric id of MA " + maName + " must"
+ " be between 1 and 64 inclusive for EA1000");
}
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yangMa = buildYangMaFromApiMa(ma);
yangMa.addToMaintenanceAssociationEndPoint(yangMep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm
.mefcfm.MaintenanceDomain yangMd = buildYangMdFromApiMd(md);
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
log.info("Created MEP {} on device {}", mdName + "/" + maName +
"/" + mep.mepId(), handler().data().deviceId());
return true;
} catch (NetconfException e) {
log.error("Unable to create MEP {}/{}/{} on device {}",
mdName, maName, mep.mepId(), handler().data().deviceId());
throw new CfmConfigException("Unable to create MEP :" + e.getMessage());
}
}
@Override
public Collection<MepEntry> getAllMeps(MdId mdName, MaIdShort maName) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
if (handler().data().deviceId() == null) {
throw new CfmConfigException("Device is not ready - connecting or "
+ "disconnected for MEP " + mdName + "/" + maName + "/" + mepId);
}
NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
try {
MseaCfm mseacfm =
mseaCfmService.getMepFull(mdName, maName, mepId, session);
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
mseacfm.mefcfm.MaintenanceDomain replyMd:mseacfm.mefCfm().maintenanceDomain()) {
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
mseacfm.mefcfm.maintenancedomain.
MaintenanceAssociation replyMa:replyMd.maintenanceAssociation()) {
for (MaintenanceAssociationEndPoint replyMep:replyMa.maintenanceAssociationEndPoint()) {
return buildApiMepEntryFromYangMep(replyMep, handler().data().deviceId(), mdName, maName);
}
}
}
log.warn("Mep " + mepId + " not found on device " + handler().data().deviceId());
return null;
} catch (NetconfException e) {
log.error("Unable to get MEP {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to create MEP :" + e.getMessage());
}
}
@Override
public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
MaintenanceAssociationEndPoint mep =
new DefaultMaintenanceAssociationEndPoint();
mep.mepIdentifier(MepIdType.of(mepId.id()));
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
yangMa.maNameAndTypeCombo(MaNameUtil.getYangMaNameFromApiMaId(maName));
yangMa.addToMaintenanceAssociationEndPoint(mep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
new DefaultMaintenanceDomain();
yangMd.mdNameAndTypeCombo(getYangMdNameFromApiMdId(mdName));
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.deleteMseaMep(mseaCfmOpParam, session, DatastoreId.RUNNING);
log.info("Deleted MEP {} on device {}", mdName + "/" + maName +
"/" + mepId, handler().data().deviceId());
return true;
} catch (NetconfException e) {
log.error("Unable to delete MEP {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to delete MEP :" + e.getMessage());
}
}
@Override
public void transmitLoopback(MdId mdName, MaIdShort maName, MepId mepId,
MepLbCreate lbCreate) throws CfmConfigException {
NetconfController controller =
checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
Short maNumericId =
mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
TransmitLoopbackInput lb = new DefaultTransmitLoopbackInput();
lb.maintenanceDomain(mdNumericId);
lb.maintenanceAssociation(maNumericId);
lb.maintenanceAssociationEndPoint(mepId.id());
if (lbCreate.numberMessages() != null) {
lb.numberOfMessages(lbCreate.numberMessages());
}
if (lbCreate.vlanDropEligible() != null) {
lb.vlanDropEligible(lbCreate.vlanDropEligible());
}
if (lbCreate.remoteMepId() != null) {
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
.MepId yangMepId = new DefaultMepId();
yangMepId.mepId(MepIdType.of(lbCreate.remoteMepId().id()));
TargetAddress ta = new DefaultTargetAddress();
ta.addressType(yangMepId);
lb.targetAddress(ta);
} else if (lbCreate.remoteMepAddress() != null) {
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
.MacAddress yangMacAddress = new DefaultMacAddress();
yangMacAddress.macAddress(
org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes
.MacAddress.of(lbCreate.remoteMepAddress().toString()));
TargetAddress ta = new DefaultTargetAddress();
ta.addressType(yangMacAddress);
lb.targetAddress(ta);
} else {
throw new CfmConfigException("Either a remote MEP ID or Remote MEP "
+ "MacAddress must be specified when calling Transmit Loopback");
}
if (lbCreate.dataTlvHex() != null && !lbCreate.dataTlvHex().isEmpty()) {
lb.dataTlv(HexString.fromHexString(lbCreate.dataTlvHex()));
}
if (lbCreate.vlanPriority() != null) {
lb.vlanPriority(PriorityType.of((short) lbCreate.vlanPriority().ordinal()));
}
try {
mseaCfmService.transmitLoopback(lb, session);
log.info("Transmit Loopback called on MEP {} on device {}",
mdName + "/" + maName + "/" + mepId,
handler().data().deviceId());
} catch (NetconfException e) {
throw new CfmConfigException(e);
}
}
@Override
public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
NetconfController controller =
checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
Short maNumericId =
mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
AbortLoopbackInput lbAbort = new DefaultAbortLoopbackInput();
lbAbort.maintenanceDomain(mdNumericId);
lbAbort.maintenanceAssociation(maNumericId);
lbAbort.maintenanceAssociationEndPoint(mepId.id());
try {
mseaCfmService.abortLoopback(lbAbort, session);
log.info("Loopback on MEP {} on device {} aborted",
mdName + "/" + maName + "/" + mepId,
handler().data().deviceId());
} catch (NetconfException e) {
throw new CfmConfigException(e);
}
}
@Override
public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId,
MepLtCreate ltCreate) {
throw new UnsupportedOperationException("Not yet implemented");
}
private org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain buildYangMdFromApiMd(MaintenanceDomain md)
throws CfmConfigException {
MdNameAndTypeCombo mdName = getYangMdNameFromApiMdId(md.mdId());
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain mdYang = new DefaultMaintenanceDomain();
mdYang.id(md.mdNumericId());
mdYang.mdNameAndTypeCombo(mdName);
mdYang.mdLevel(MdLevelType.of((short) md.mdLevel().ordinal()));
return mdYang;
}
protected static MdNameAndTypeCombo getYangMdNameFromApiMdId(MdId mdId)
throws CfmConfigException {
MdNameAndTypeCombo mdName;
if (mdId instanceof MdIdDomainName) {
boolean isIpAddr = false;
try {
if (IpAddress.valueOf(mdId.mdName()) != null) {
isIpAddr = true;
}
} catch (IllegalArgumentException e) {
//continue
}
if (isIpAddr) {
mdName = new DefaultNameDomainName();
((DefaultNameDomainName) mdName).nameDomainName(NameDomainNameUnion.of(
org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.ietfinettypes.
IpAddress.fromString(mdId.mdName())));
} else {
mdName = new DefaultNameDomainName();
((DefaultNameDomainName) mdName).nameDomainName(NameDomainNameUnion
.of(DomainName.fromString(mdId.mdName())));
}
} else if (mdId instanceof MdIdMacUint) {
mdName = new DefaultMacAddressAndUint();
((DefaultMacAddressAndUint) mdName).nameMacAddressAndUint(MacAddressAndUintStr.fromString(mdId.mdName()));
} else if (mdId instanceof MdIdNone) {
mdName = new DefaultNameNone();
} else if (mdId instanceof MdIdCharStr) {
mdName = new DefaultNameCharacterString();
((DefaultNameCharacterString) mdName).name(Identifier45.fromString(mdId.mdName()));
} else {
throw new CfmConfigException("Unexpected error creating MD " +
mdId.getClass().getSimpleName());
}
return mdName;
}
private org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.maintenancedomain.MaintenanceAssociation buildYangMaFromApiMa(
MaintenanceAssociation apiMa) throws CfmConfigException {
MaNameAndTypeCombo maName = MaNameUtil.getYangMaNameFromApiMaId(apiMa.maId());
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yamgMa = new DefaultMaintenanceAssociation();
yamgMa.maNameAndTypeCombo(maName);
if (apiMa.remoteMepIdList() == null || apiMa.remoteMepIdList().size() < REMOTEMEPLIST_MIN_COUNT
|| apiMa.remoteMepIdList().size() > REMOTEMEPLIST_MAX_COUNT) {
throw new CfmConfigException("EA1000 requires between " +
REMOTEMEPLIST_MIN_COUNT + " and " + REMOTEMEPLIST_MAX_COUNT +
" remote meps in an MA");
}
for (MepId rmep:apiMa.remoteMepIdList()) {
yamgMa.addToRemoteMeps(MepIdType.of(rmep.id()));
}
if (apiMa.ccmInterval() != null) {
switch (apiMa.ccmInterval()) {
case INTERVAL_3MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX3_3MS);
break;
case INVERVAL_10MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX10MS);
break;
case INVERVAL_100MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX100MS);
break;
case INTERVAL_1S:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX1S);
break;
default:
throw new CfmConfigException("EA1000 only supports "
+ "3ms, 10ms, 100ms and 1s for CCM Interval. Rejecting: "
+ apiMa.ccmInterval().name());
}
}
if (apiMa.componentList() == null || apiMa.componentList().size() != COMPONENT_LIST_SIZE) {
throw new CfmConfigException("EA1000 supports only 1 Component in an MA");
}
Component maComponent = apiMa.componentList().iterator().next();
if (maComponent.vidList() == null || maComponent.vidList().size() < VIDLIST_SIZE_MIN) {
throw new CfmConfigException("EA1000 requires at least 1 VID in "
+ "the Component of an MA");
}
ComponentList compList = new DefaultComponentList();
for (VlanId vid:maComponent.vidList()) {
compList.addToVid(VlanIdType.of(vid.toShort()));
}
if (maComponent.tagType() != null) {
switch (maComponent.tagType()) {
case VLAN_STAG:
compList.tagType(TagTypeEnum.VLAN_STAG);
break;
case VLAN_CTAG:
compList.tagType(TagTypeEnum.VLAN_CTAG);
break;
case VLAN_NONE:
default:
compList.tagType(TagTypeEnum.VLAN_NONE);
break;
}
}
yamgMa.componentList(compList);
yamgMa.id(apiMa.maNumericId());
return yamgMa;
}
private MaintenanceAssociationEndPoint buildYangMepFromApiMep(Mep mep)
throws CfmConfigException {
MaintenanceAssociationEndPoint mepBuilder =
new DefaultMaintenanceAssociationEndPoint();
mepBuilder.mepIdentifier(MepIdType.of(mep.mepId().id()));
ContinuityCheck cc = new DefaultContinuityCheck();
cc.cciEnabled(mep.cciEnabled());
mepBuilder.continuityCheck(cc);
mepBuilder.ccmLtmPriority(
PriorityType.of((short) mep.ccmLtmPriority().ordinal()));
mepBuilder.administrativeState(mep.administrativeState());
if (mep.direction() == MepDirection.UP_MEP) {
throw new CfmConfigException("EA1000 only supports DOWN Meps");
}
if (mep.port() == null || mep.port().toLong() < MEP_PORT_MIN
|| mep.port().toLong() > MEP_PORT_MAX) {
throw new CfmConfigException("EA1000 has only ports 0 and 1. "
+ "Rejecting Port: " + mep.port());
}
mepBuilder.yangAutoPrefixInterface(
(mep.port().toLong() == 0) ? InterfaceEnum.ETH0 : InterfaceEnum.ETH1);
return mepBuilder;
}
private MepEntry buildApiMepEntryFromYangMep(
MaintenanceAssociationEndPoint yangMep, DeviceId deviceId,
MdId mdName, MaIdShort maName) throws CfmConfigException {
MepId mepId = MepId.valueOf((short) yangMep.mepIdentifier().uint16());
MepEntry.MepEntryBuilder builder = DefaultMepEntry.builder(mepId,
deviceId,
(yangMep.yangAutoPrefixInterface() == InterfaceEnum.ETH0) ?
PortNumber.portNumber(0) : PortNumber.portNumber(1),
MepDirection.DOWN_MEP, //Always down for EA1000
mdName, maName);
if (yangMep.loopback() != null) {
MepLbEntryBuilder lbEntryBuilder = DefaultMepLbEntry.builder();
if (yangMep.loopback().repliesReceived() != null) {
lbEntryBuilder = lbEntryBuilder.countLbrReceived(
yangMep.loopback().repliesReceived().uint32());
}
if (yangMep.loopback().repliesTransmitted() != null) {
lbEntryBuilder = lbEntryBuilder.countLbrTransmitted(
yangMep.loopback().repliesTransmitted().uint32());
}
builder.loopbackAttributes(lbEntryBuilder.build());
}
if (yangMep.remoteMepDatabase() != null &&
yangMep.remoteMepDatabase().remoteMep() != null) {
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.maintenancedomain.maintenanceassociation
.maintenanceassociationendpoint.remotemepdatabase.RemoteMep
rmep:yangMep.remoteMepDatabase().remoteMep()) {
builder = (MepEntry.MepEntryBuilder) builder.addToActiveRemoteMepList(
getApiRemoteMepFromYangRemoteMep(rmep));
}
}
if (yangMep.ccmLtmPriority() != null) {
builder = (MepEntry.MepEntryBuilder) builder.ccmLtmPriority(
Priority.values()[yangMep.ccmLtmPriority().uint8()]);
}
//And the the state attributes
builder = (MepEntry.MepEntryBuilder) builder
.macAddress(MacAddress.valueOf(yangMep.macAddress().toString()))
.administrativeState(yangMep.administrativeState())
.cciEnabled(yangMep.continuityCheck().cciEnabled());
AugmentedMseaCfmMaintenanceAssociationEndPoint augmentedyangMep = yangMep
.augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
if (augmentedyangMep != null) {
if (augmentedyangMep.lastDefectSent() != null) {
builder = (MepEntry.MepEntryBuilder) builder
.activeXconCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.CROSS_CONNECT_CCM.bits()))
.activeErrorCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.INVALID_CCM.bits()))
.activeMacStatusDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_MAC_ERROR.bits()))
.activeRdiCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_RDI.bits()))
.activeRemoteCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_INVALID_CCM.bits()));
}
}
return builder.buildEntry();
}
private RemoteMepEntry getApiRemoteMepFromYangRemoteMep(
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.
maintenanceassociation.maintenanceassociationendpoint.remotemepdatabase.
RemoteMep yangRemoteMep) throws CfmConfigException {
MepId remoteMepId = MepId.valueOf((short) yangRemoteMep.remoteMepId().uint16());
RemoteMepStateTypeEnum state = RemoteMepStateTypeEnum.FAILED;
if (yangRemoteMep.remoteMepState() != null) {
state = yangRemoteMep.remoteMepState().enumeration();
}
RemoteMepEntryBuilder rmepBuilder = DefaultRemoteMepEntry.builder(
remoteMepId, RemoteMepState.valueOf("RMEP_" + state.name()))
.rdi(yangRemoteMep.rdi());
if (yangRemoteMep.macAddress() != null) {
rmepBuilder = rmepBuilder.macAddress(
MacAddress.valueOf(yangRemoteMep.macAddress().toString()));
}
if (yangRemoteMep.failedOkTime() != null) {
//Currently EA1000 is reporting this as 1/1000s even though yang type
// is time ticks 1/100s - to be fixed
rmepBuilder = rmepBuilder.failedOrOkTime(Duration.ofMillis(
yangRemoteMep.failedOkTime().uint32()));
}
if (yangRemoteMep.portStatusTlv() != null) {
rmepBuilder = rmepBuilder.portStatusTlvType(PortStatusTlvType.valueOf(
"PS_" + yangRemoteMep.portStatusTlv().enumeration().name()));
}
if (yangRemoteMep.interfaceStatusTlv() != null) {
rmepBuilder = rmepBuilder.interfaceStatusTlvType(InterfaceStatusTlvType.valueOf(
"IS_" + yangRemoteMep.interfaceStatusTlv().enumeration().name()));
}
return rmepBuilder.build();
}
}

View File

@ -0,0 +1,740 @@
/*
* Copyright 2017-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.microsemi;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.time.Duration;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService.DmEntryParts;
import org.onosproject.drivers.microsemi.yang.utils.IetfYangTypesUtils;
import org.onosproject.drivers.microsemi.yang.utils.MepIdUtil;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.MepTsCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
import org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.incubator.net.l2monitoring.soam.StartTime.StartTimeOption;
import org.onosproject.incubator.net.l2monitoring.soam.StopTime.StopTimeOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementStatHistory;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.DmType;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.MeasurementOption;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate.Version;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry.DmEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry.SessionStatus;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent.DmStatCurrentBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory.DmStatHistoryBuilder;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatCurrent;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.MefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.DefaultMaintenanceDomain;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.DefaultMaintenanceAssociation;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.delaymeasurementbinsgroup.bins.FrameDelay;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.delaymeasurementbinsgroup.bins.InterFrameDelayVariation;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.DefaultDelayMeasurements;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.DelayMeasurements;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.DefaultDelayMeasurement;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.DelayMeasurement;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.delaymeasurement.HistoryStats;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.delaymeasurement.MeasurementEnable;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.delaymeasurement.MessagePeriodEnum;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.remotemep.DefaultMepId;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MepIdType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.PriorityType;
import org.slf4j.Logger;
/**
* Implementation of SoamDmProgrammable for Microsemi EA1000.
*/
public class EA1000SoamDmProgrammable extends AbstractHandlerBehaviour
implements SoamDmProgrammable {
private static final Logger log = getLogger(EA1000SoamDmProgrammable.class);
private static final int MAX_DMS = 2;
public EA1000SoamDmProgrammable() {
log.debug("Loaded handler behaviour EA1000SoamDmProgrammable");
}
@Override
public Collection<DelayMeasurementEntry> getAllDms(
MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException, SoamConfigException {
return getAllDmsOrOneDm(mdName, maName, mepId, null, DmEntryParts.ALL_PARTS);
}
@Override
public DelayMeasurementEntry getDm(MdId mdName, MaIdShort maName,
MepId mepId, SoamId dmId) throws CfmConfigException, SoamConfigException {
Collection<DelayMeasurementEntry> allDms =
getAllDmsOrOneDm(mdName, maName, mepId, dmId, DmEntryParts.ALL_PARTS);
if (allDms != null && allDms.size() >= 1) {
return allDms.toArray(new DelayMeasurementEntry[1])[0];
}
return null;
}
@Override
public DelayMeasurementStatCurrent getDmCurrentStat(
MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
throws CfmConfigException, SoamConfigException {
Collection<DelayMeasurementEntry> dms =
getAllDmsOrOneDm(mdName, maName, mepId, dmId, DmEntryParts.CURRENT_ONLY);
//There should be only one
if (dms != null && dms.size() == 1) {
return dms.toArray((new DelayMeasurementEntry[1]))[0].currentResult();
}
return null;
}
@Override
public Collection<DelayMeasurementStatHistory> getDmHistoricalStats(
MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
throws CfmConfigException, SoamConfigException {
Collection<DelayMeasurementEntry> dms =
getAllDmsOrOneDm(mdName, maName, mepId, dmId, DmEntryParts.HISTORY_ONLY);
//There should only be one in the result
if (dms != null && dms.size() == 1) {
return dms.toArray(new DelayMeasurementEntry[1])[0].historicalResults();
}
return new ArrayList<>();
}
@Override
public Optional<SoamId> createDm(
MdId mdName, MaIdShort maName, MepId mepId, DelayMeasurementCreate dm)
throws CfmConfigException, SoamConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
MseaCfm mepEssentials;
try {
mepEssentials = mseaCfmService.getMepEssentials(
mdName, maName, mepId, session);
} catch (NetconfException e) {
throw new CfmConfigException(e);
}
short mdNumber = mepEssentials.mefCfm().maintenanceDomain().get(0).id();
short maNumber = mepEssentials.mefCfm().maintenanceDomain().get(0)
.maintenanceAssociation().get(0).id();
MaintenanceAssociationEndPoint currentMep =
mepEssentials.mefCfm().maintenanceDomain().get(0)
.maintenanceAssociation().get(0)
.maintenanceAssociationEndPoint().get(0);
AugmentedMseaCfmMaintenanceAssociationEndPoint currAugMep =
currentMep.augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
if (dm.startTime() != null && !dm.startTime().option().equals(StartTimeOption.IMMEDIATE)) {
throw new SoamConfigException(
"Only start time: IMMEDIATE is supported on EA1000");
} else if (dm.stopTime() != null && !dm.stopTime().option().equals(StopTimeOption.NONE)) {
throw new SoamConfigException(
"Only stop time: NONE is supported on EA1000");
}
MessagePeriodEnum mpEnum = MessagePeriodEnum.YANGAUTOPREFIX1000MS;
if (dm.messagePeriod() != null) {
if (dm.messagePeriod().toMillis() == 1000) {
mpEnum = MessagePeriodEnum.YANGAUTOPREFIX1000MS;
} else if (dm.messagePeriod().toMillis() == 100) {
mpEnum = MessagePeriodEnum.YANGAUTOPREFIX100MS;
} else if (dm.messagePeriod().toMillis() == 10) {
mpEnum = MessagePeriodEnum.YANGAUTOPREFIX10MS;
} else if (dm.messagePeriod().toMillis() == 3) {
mpEnum = MessagePeriodEnum.YANGAUTOPREFIX3MS;
} else {
throw new SoamConfigException("EA1000 supports only Message "
+ "Periods 1000ms,100ms, 10ms and 3ms for Delay Measurements");
}
}
short lastDmId = 0;
short newDmId = 1;
if (currAugMep != null && currAugMep.delayMeasurements() != null) {
Iterator<DelayMeasurement> dmIterator =
currAugMep.delayMeasurements().delayMeasurement().iterator();
while (dmIterator.hasNext()) {
lastDmId = dmIterator.next().dmId();
}
if (lastDmId == 0) {
//Indicates that no DM was found under this MEP.
//We will just create the next one as 1
log.info("Creating DM 1");
newDmId = 1;
} else if (lastDmId == 1) {
log.info("Creating DM 2");
newDmId = 2;
} else if (lastDmId == MAX_DMS) {
log.warn("Maximum number of DMs (2) have been created on MEP {}/{}/{}"
+ "on device {} - delete DMs before creating more",
mdName.mdName(), maName.maName(), mepId.id(),
handler().data().deviceId());
throw new CfmConfigException("Maximum number of DMs (2) exist on MEP. "
+ "Please call abort on a DM before creating more");
}
}
DelayMeasurement dmBuilder = new DefaultDelayMeasurement();
dmBuilder.dmId((short) newDmId);
DefaultMepId dMepId = new DefaultMepId();
dMepId.mepId(MepIdType.of(dm.remoteMepId().id()));
dmBuilder.remoteMep(dMepId);
BitSet measurementEnable = getMeasurementEnabledSet(dm.measurementsEnabled());
if (measurementEnable != null && !measurementEnable.isEmpty()) {
dmBuilder.measurementEnable(measurementEnable);
}
dmBuilder.administrativeState(true);
dmBuilder.priority(PriorityType.of((short) dm.priority().ordinal()));
dmBuilder.messagePeriod(mpEnum);
if (dm.numberIntervalsStored() != null) {
//Here we pass in num intervals stored - for EA1000 32 are always
//stored so it's not controllable - instead we set number returned
dmBuilder.numberIntervalsReturned(dm.numberIntervalsStored());
}
if (dm.measurementInterval() != null) {
dmBuilder.measurementInterval(dm.measurementInterval().toMinutes());
}
if (dm.frameSize() != null) {
dmBuilder.frameSize(dm.frameSize());
}
DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint augmentedMep =
new DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint();
DelayMeasurements dms = new DefaultDelayMeasurements();
dms.addToDelayMeasurement(dmBuilder);
augmentedMep.delayMeasurements(dms);
MaintenanceAssociationEndPoint mep =
new DefaultMaintenanceAssociationEndPoint();
mep.mepIdentifier(MepIdType.of(mepId.id()));
mep.addAugmentation(augmentedMep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
yangMa.id(maNumber);
yangMa.addToMaintenanceAssociationEndPoint(mep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain yangMd = new DefaultMaintenanceDomain();
yangMd.id(mdNumber);
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
return Optional.empty();
} catch (NetconfException e) {
log.error("Unable to create DM {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to create DM :" + e.getMessage());
}
}
@Override
public void abortDm(MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap().get(handler().data()
.deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler()
.get(MseaCfmNetconfService.class));
CfmMdService cfmMdService = checkNotNull(handler().get(CfmMdService.class));
org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain
.maintenanceassociation.maintenanceassociationendpoint
.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements
.DelayMeasurement dm = new DefaultDelayMeasurement();
dm.dmId(dmId.id().shortValue());
DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint augmentedMep =
new DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint();
DelayMeasurements ddms = new DefaultDelayMeasurements();
ddms.addToDelayMeasurement(dm);
augmentedMep.delayMeasurements(ddms);
MaintenanceAssociationEndPoint mep =
new DefaultMaintenanceAssociationEndPoint();
mep.mepIdentifier(MepIdType.of(mepId.id()));
mep.addAugmentation(augmentedMep);
short mdNumericId = cfmMdService.getMaintenanceDomain(mdName).get().mdNumericId();
short maNumericId = cfmMdService
.getMaintenanceAssociation(mdName, maName).get().maNumericId();
DefaultMaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
yangMa.id(maNumericId);
yangMa.addToMaintenanceAssociationEndPoint(mep);
DefaultMaintenanceDomain yangMd = new DefaultMaintenanceDomain();
yangMd.id(mdNumericId);
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.deleteMseaCfmDm(mseaCfmOpParam, session, DatastoreId.RUNNING);
} catch (NetconfException e) {
log.error("Unable to delete DM {}/{}/{}/{} on device {}",
mdName, maName, mepId, dm.dmId(), handler().data().deviceId());
throw new CfmConfigException("Unable to delete DM :" + e.getMessage());
}
}
@Override
public void abortDm(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void clearDelayHistoryStats(MdId mdName, MaIdShort maName,
MepId mepId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void clearDelayHistoryStats(MdId mdName, MaIdShort maName,
MepId mepId, SoamId dmId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Collection<LossMeasurementEntry> getAllLms(MdId mdName,
MaIdShort maName, MepId mepId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public LossMeasurementEntry getLm(MdId mdName, MaIdShort maName,
MepId mepId, SoamId lmId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public LossMeasurementStatCurrent getLmCurrentStat(MdId mdName,
MaIdShort maName, MepId mepId, SoamId lmId) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Collection<LossMeasurementStatCurrent> getLmHistoricalStats(
MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Optional<SoamId> createLm(MdId mdName, MaIdShort maName, MepId mepId,
LossMeasurementCreate lm) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void abortLm(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void abortLm(MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId)
throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void clearLossHistoryStats(MdId mdName, MaIdShort maName,
MepId mepId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void clearLossHistoryStats(MdId mdName, MaIdShort maName,
MepId mepId, SoamId lmId) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void createTestSignal(MdId mdName, MaIdShort maName, MepId mepId,
MepTsCreate tsCreate) throws CfmConfigException {
throw new UnsupportedOperationException("Not supported by EA1000");
}
@Override
public void abortTestSignal(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
throw new UnsupportedOperationException("Not supported by EA1000");
}
private static DelayMeasurementEntry buildApiDmFromYangDm(DelayMeasurement dm,
MdId mdName, MaIdShort maName, MepId mepId)
throws SoamConfigException, CfmConfigException {
org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.remotemep
.MepId rmep = MepIdUtil.convertRemoteMepId(dm.remoteMep());
DmEntryBuilder dmBuilder = (DmEntryBuilder) DefaultDelayMeasurementEntry.builder(
SoamId.valueOf(dm.dmId()), DmType.DMDMM, Version.Y17312011,
MepId.valueOf((short) ((MepIdType) rmep.mepId()).uint16()),
Priority.values()[dm.priority().uint8()]);
if (dm.sessionStatus() != null) {
dmBuilder = dmBuilder.sessionStatus(SessionStatus.valueOf(
dm.sessionStatus().enumeration().name()));
}
if (dm.frameDelayTwoWay() != null) {
dmBuilder = dmBuilder.frameDelayTwoWay(Duration.ofNanos(
dm.frameDelayTwoWay().uint32() * 1000));
}
if (dm.interFrameDelayVariationTwoWay() != null) {
dmBuilder = dmBuilder.interFrameDelayVariationTwoWay(Duration.ofNanos(
dm.interFrameDelayVariationTwoWay().uint32() * 1000));
}
if (dm.frameSize() != 0) {
dmBuilder = (DmEntryBuilder) dmBuilder.frameSize((short) dm.frameSize());
}
if (dm.messagePeriod() != null) {
switch (dm.messagePeriod()) {
case YANGAUTOPREFIX1000MS:
dmBuilder = (DmEntryBuilder) dmBuilder.messagePeriod(Duration.ofMillis(1000));
break;
case YANGAUTOPREFIX100MS:
dmBuilder = (DmEntryBuilder) dmBuilder.messagePeriod(Duration.ofMillis(100));
break;
case YANGAUTOPREFIX10MS:
dmBuilder = (DmEntryBuilder) dmBuilder.messagePeriod(Duration.ofMillis(10));
break;
case YANGAUTOPREFIX3MS:
dmBuilder = (DmEntryBuilder) dmBuilder.messagePeriod(Duration.ofMillis(3));
break;
default:
throw new SoamConfigException("EA1000 supports only 1000,"
+ "100, 10 and 3ms for Message Period on DM");
}
}
Collection<MeasurementOption> moSet =
EA1000SoamDmProgrammable.getMeasurementOptions(dm.measurementEnable());
moSet.forEach(dmBuilder::addToMeasurementsEnabled);
dmBuilder = dmBuilder
.currentResult(buildApiDmCurrFromYangDmCurr(dm, mdName, maName, mepId));
for (DelayMeasurementStatHistory historyStat:
buildApiDmHistFromYangDm(dm, mdName, maName, mepId)) {
dmBuilder = dmBuilder.addToHistoricalResults(historyStat);
}
return dmBuilder.build();
}
private static Collection<DelayMeasurementStatHistory> buildApiDmHistFromYangDm(
DelayMeasurement dm, MdId mdName, MaIdShort maName, MepId mepId)
throws SoamConfigException, CfmConfigException {
Collection<DelayMeasurementStatHistory> historyStatsCollection = new ArrayList<>();
if (dm.historyStats() != null) {
for (HistoryStats dmHistory:dm.historyStats()) {
DmStatHistoryBuilder historyBuilder =
DefaultDelayMeasurementStatHistory.builder(
SoamId.valueOf((int) dmHistory.id()),
Duration.ofMillis(dmHistory.elapsedTime() * 10), //Values are in 1/100th sec
dmHistory.suspectStatus() != null ?
dmHistory.suspectStatus().yangAutoPrefixBoolean() : false);
historyBuilder = historyBuilder.endTime(
IetfYangTypesUtils.fromYangDateTimeToInstant(dmHistory.endTime()));
if (dmHistory.frameDelayTwoWayMin() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.frameDelayTwoWayMin(Duration.ofNanos(dmHistory.frameDelayTwoWayMin().uint32() * 1000));
}
if (dmHistory.frameDelayTwoWayMax() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.frameDelayTwoWayMax(Duration.ofNanos(dmHistory.frameDelayTwoWayMax().uint32() * 1000));
}
if (dmHistory.frameDelayTwoWayAverage() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.frameDelayTwoWayAvg(Duration.ofNanos(dmHistory.frameDelayTwoWayAverage().uint32() * 1000));
}
if (dmHistory.interFrameDelayVariationTwoWayMin() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.interFrameDelayVariationTwoWayMin(Duration.ofNanos(
dmHistory.interFrameDelayVariationTwoWayMin().uint32() * 1000));
}
if (dmHistory.interFrameDelayVariationTwoWayMax() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.interFrameDelayVariationTwoWayMax(Duration.ofNanos(
dmHistory.interFrameDelayVariationTwoWayMax().uint32() * 1000));
}
if (dmHistory.interFrameDelayVariationTwoWayAverage() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.interFrameDelayVariationTwoWayAvg(Duration.ofNanos(
dmHistory.interFrameDelayVariationTwoWayAverage().uint32() * 1000));
}
if (dmHistory.soamPdusReceived() != null) {
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.soamPdusReceived(Integer.valueOf((int) dmHistory.soamPdusReceived().uint32()));
}
if (dmHistory.bins() != null && dmHistory.bins().frameDelay() != null) {
Map<Duration, Integer> frameDelayTwoWayBins = new HashMap<>();
for (FrameDelay fdBin:dmHistory.bins().frameDelay()) {
frameDelayTwoWayBins.put(
Duration.ofNanos(fdBin.lowerBound().uint32() * 1000),
Integer.valueOf((int) fdBin.counter().uint32()));
}
historyBuilder = (DmStatHistoryBuilder) historyBuilder
.frameDelayTwoWayBins(frameDelayTwoWayBins);
}
if (dmHistory.bins() != null && dmHistory.bins().interFrameDelayVariation() != null) {
Map<Duration, Integer> ifdvTwoWayBins = new HashMap<>();
for (InterFrameDelayVariation ifdvBin:dmHistory.bins().interFrameDelayVariation()) {
ifdvTwoWayBins.put(
Duration.ofNanos(ifdvBin.lowerBound().uint32() * 1000),
Integer.valueOf((int) ifdvBin.counter().uint32()));
}
historyBuilder =
(DmStatHistoryBuilder) historyBuilder.interFrameDelayVariationTwoWayBins(ifdvTwoWayBins);
}
historyStatsCollection.add((DelayMeasurementStatHistory) historyBuilder.build());
}
}
return historyStatsCollection;
}
private static DelayMeasurementStatCurrent buildApiDmCurrFromYangDmCurr(
DelayMeasurement dm, MdId mdName, MaIdShort maName, MepId mepId)
throws SoamConfigException, CfmConfigException {
if (dm == null || dm.currentStats() == null || mdName == null ||
maName == null || mepId == null) {
return null;
}
DmStatCurrentBuilder statCurrBuilder =
DefaultDelayMeasurementStatCurrent.builder(
Duration.ofMillis(dm.currentStats().elapsedTime() * 10), //Values are in 1/100th sec
dm.currentStats().suspectStatus() != null ?
dm.currentStats().suspectStatus().yangAutoPrefixBoolean() : false);
statCurrBuilder = statCurrBuilder.startTime(
IetfYangTypesUtils.fromYangDateTimeToInstant(dm.currentStats().startTime()));
if (dm.currentStats().frameDelayTwoWayMin() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.frameDelayTwoWayMin(Duration.ofNanos(
dm.currentStats().frameDelayTwoWayMin().uint32() * 1000));
}
if (dm.currentStats().frameDelayTwoWayMax() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.frameDelayTwoWayMax(Duration.ofNanos(
dm.currentStats().frameDelayTwoWayMax().uint32() * 1000));
}
if (dm.currentStats().frameDelayTwoWayAverage() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.frameDelayTwoWayAvg(Duration.ofNanos(
dm.currentStats().frameDelayTwoWayAverage().uint32() * 1000));
}
if (dm.currentStats().interFrameDelayVariationTwoWayMin() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.interFrameDelayVariationTwoWayMin(Duration.ofNanos(
dm.currentStats().interFrameDelayVariationTwoWayMin().uint32() * 1000));
}
if (dm.currentStats().interFrameDelayVariationTwoWayMax() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.interFrameDelayVariationTwoWayMax(Duration.ofNanos(
dm.currentStats().interFrameDelayVariationTwoWayMax().uint32() * 1000));
}
if (dm.currentStats().interFrameDelayVariationTwoWayAverage() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.interFrameDelayVariationTwoWayAvg(Duration.ofNanos(
dm.currentStats().interFrameDelayVariationTwoWayAverage().uint32() * 1000));
}
if (dm.currentStats().soamPdusReceived() != null) {
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder
.soamPdusReceived(Integer.valueOf((int) dm.currentStats().soamPdusReceived().uint32()));
}
if (dm.currentStats().bins() != null && dm.currentStats().bins().frameDelay() != null) {
Map<Duration, Integer> frameDelayTwoWayBins = new HashMap<>();
for (FrameDelay fdBin:dm.currentStats().bins().frameDelay()) {
frameDelayTwoWayBins.put(
Duration.ofNanos(fdBin.lowerBound().uint32() * 1000),
Integer.valueOf((int) fdBin.counter().uint32()));
}
statCurrBuilder = (DmStatCurrentBuilder) statCurrBuilder.frameDelayTwoWayBins(frameDelayTwoWayBins);
}
if (dm.currentStats().bins() != null && dm.currentStats().bins().interFrameDelayVariation() != null) {
Map<Duration, Integer> ifdvTwoWayBins = new HashMap<>();
for (InterFrameDelayVariation ifdvBin:dm.currentStats().bins().interFrameDelayVariation()) {
ifdvTwoWayBins.put(
Duration.ofNanos(ifdvBin.lowerBound().uint32() * 1000),
Integer.valueOf((int) ifdvBin.counter().uint32()));
}
statCurrBuilder =
(DmStatCurrentBuilder) statCurrBuilder.interFrameDelayVariationTwoWayBins(ifdvTwoWayBins);
}
return (DelayMeasurementStatCurrent) statCurrBuilder.build();
}
private Collection<DelayMeasurementEntry> getAllDmsOrOneDm(
MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId, DmEntryParts parts)
throws CfmConfigException, SoamConfigException {
NetconfController controller =
checkNotNull(handler().get(NetconfController.class));
NetconfSession session =
controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
Collection<DelayMeasurementEntry> dmResults = new ArrayList<>();
try {
MseaCfm mseacfm =
mseaCfmService.getSoamDm(mdName, maName, mepId, dmId, parts, session);
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain replyMd:mseacfm.mefCfm().maintenanceDomain()) {
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm
.mefcfm.maintenancedomain.MaintenanceAssociation replyMa:
replyMd.maintenanceAssociation()) {
for (MaintenanceAssociationEndPoint replyMep:
replyMa.maintenanceAssociationEndPoint()) {
AugmentedMseaCfmMaintenanceAssociationEndPoint augmentedMep =
replyMep.augmentation(
DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
if (augmentedMep == null ||
augmentedMep.delayMeasurements() == null ||
augmentedMep.delayMeasurements()
.delayMeasurement().isEmpty()) {
log.info("No Delay Measurements retrieved from MEP " +
mdName + "/" + maName + "/" + mepId);
} else {
for (org.onosproject.yang.gen.v1.mseasoampm.rev20160229
.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation
.maintenanceassociationendpoint
.augmentedmseacfmmaintenanceassociationendpoint
.delaymeasurements.DelayMeasurement dm
:augmentedMep.delayMeasurements().delayMeasurement()) {
dmResults.add(buildApiDmFromYangDm(dm, mdName, maName, mepId));
}
}
}
}
}
return dmResults;
} catch (NetconfException e) {
log.error("Unable to get MEP {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to create MEP :" + e.getMessage());
}
}
protected static BitSet getMeasurementEnabledSet(
Collection<MeasurementOption> measEnabled) throws SoamConfigException {
BitSet measurementEnable = new BitSet();
try {
measEnabled.forEach(mo -> {
MeasurementEnable me = MeasurementEnable.valueOf(mo.name());
measurementEnable.set(me.measurementEnable());
});
} catch (IllegalArgumentException e) {
throw new SoamConfigException(
"Measurement Option is not supported on EA1000: ", e);
}
return measurementEnable;
}
protected static Collection<MeasurementOption> getMeasurementOptions(BitSet meBs) {
Collection<MeasurementOption> meList = new ArrayList<>();
if (meBs != null && !meBs.isEmpty()) {
for (int i = 0; i < meBs.size(); i++) {
if (meBs.get(i)) {
meList.add(MeasurementOption.valueOf(MeasurementEnable.of(i).name()));
}
}
}
return meList;
}
}

View File

@ -15,6 +15,10 @@
*/
package org.onosproject.drivers.microsemi.yang;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
@ -34,32 +38,48 @@ import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.
public interface MseaCfmNetconfService {
/**
* Returns attributes of MEP.
* Returns minimal set of attributes of MEP.
*
* @param mdName The name of the MD
* @param maName The name of the MA
* @param mdId The name of the MD
* @param maId The name of the MA
* @param mepId The ID of the MEP
* @param session An active NETCONF session
* @return mseaCfm
* @throws NetconfException if the session has any error
*/
MseaCfm getMepEssentials(String mdName, String maName, int mepId,
NetconfSession session) throws NetconfException;
MseaCfm getMepEssentials(MdId mdId, MaIdShort maId, MepId mepId,
NetconfSession session) throws NetconfException;
/**
* Returns full set of attributes of MEP.
* This returns config and state attributes of all children of the MEP
* except for Delay Measurements and Loss Measurements - these have to be
* retrieved separately, because of their potential size
* @param mdId The name of the MD
* @param maId The name of the MA
* @param mepId The ID of the MEP
* @param session An active NETCONF session
* @return mseaCfm
* @throws NetconfException if the session has any error
*/
MseaCfm getMepFull(MdId mdId, MaIdShort maId, MepId mepId,
NetconfSession session) throws NetconfException;
/**
* Returns attributes of DM.
*
* @param mdName The name of the MD
* @param maName The name of the MA
* @param mdId The name of the MD
* @param maId The name of the MA
* @param mepId The ID of the MEP
* @param dmId The Id of the Delay Measurement
* @param dmId The Id of the Delay Measurement - if null then all DMs
* @param parts The parts of the DM to return
* @param session An active NETCONF session
* @return mseaCfm
* @throws NetconfException if the session has any error
*/
MseaCfm getSoamDm(String mdName, String maName, int mepId,
int dmId, NetconfSession session) throws NetconfException;
MseaCfm getSoamDm(MdId mdId, MaIdShort maId, MepId mepId,
SoamId dmId, DmEntryParts parts, NetconfSession session)
throws NetconfException;
/**
* Sets the value to attribute mseaCfm.
@ -73,6 +93,33 @@ public interface MseaCfmNetconfService {
boolean setMseaCfm(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException;
/**
* Deletes named Meps of mseaCfm.
* Expects to see a list of Meps
*
* @param mseaCfm value of mseaCfm
* @param session An active NETCONF session
* @param targetDs one of running, candidate or startup
* @return Boolean to indicate success or failure
* @throws NetconfException if the session has any error
*/
boolean deleteMseaMep(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException;
/**
* Deletes named delay measurements of mseaCfm.
* Expects to see a list of Delay Measurements
*
* @param mseaCfm value of mseaCfm
* @param session An active NETCONF session
* @param targetDs one of running, candidate or startup
* @return Boolean to indicate success or failure
* @throws NetconfException if the session has any error
*/
boolean deleteMseaCfmDm(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException;
/**
* Service interface of transmitLoopback.
*
@ -103,4 +150,10 @@ public interface MseaCfmNetconfService {
*/
TransmitLinktraceOutput transmitLinktrace(TransmitLinktraceInput inputVar,
NetconfSession session) throws NetconfException;
public enum DmEntryParts {
ALL_PARTS,
CURRENT_ONLY,
HISTORY_ONLY;
}
}

View File

@ -35,6 +35,8 @@ import org.onosproject.core.CoreService;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.CcmIntervalEnum;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.lossmeasurements.lossmeasurement.MessagePeriodEnum;
import org.onosproject.yang.model.ModelConverter;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ResourceData;
@ -100,7 +102,8 @@ public abstract class AbstractYangServiceImpl {
Pattern.compile("(<data/>)");
protected static final Pattern REGEX_RPC_REPLY_CLOSE =
Pattern.compile("(</rpc-reply>)");
protected static final Pattern REGEX_RPC_OK =
Pattern.compile("\\R?\\s*(<ok/>)\\R?");
@Activate
public void activate() {
Set<YangSerializer> yangSer = ((YangSerializerRegistry) yangModelRegistry).getSerializers();
@ -189,18 +192,65 @@ public abstract class AbstractYangServiceImpl {
if (moConfig == null) {
throw new NetconfException("Query object cannot be null");
} else if (session == null) {
throw new NetconfException("Session is null when calling getMseaSaFiltering()");
throw new NetconfException("Session is null when calling setNetconfObject()");
} else if (targetDs == null) {
throw new NetconfException("TargetDs is null when calling getMseaSaFiltering()");
throw new NetconfException("TargetDs is null when calling setNetconfObject()");
}
String xmlQueryStr = encodeMoToXmlStr(moConfig, annotations);
log.debug("Sending <edit-config> query on NETCONF session " + session.getSessionId() +
":\n" + xmlQueryStr);
//Some encoded values just have to be replaced
xmlQueryStr = xmlQueryStr.replace(MessagePeriodEnum.YANGAUTOPREFIX3MS.toString(), "3ms");
xmlQueryStr = xmlQueryStr.replace(MessagePeriodEnum.YANGAUTOPREFIX10MS.toString(), "10ms");
xmlQueryStr = xmlQueryStr.replace(MessagePeriodEnum.YANGAUTOPREFIX100MS.toString(), "100ms");
xmlQueryStr = xmlQueryStr.replace(MessagePeriodEnum.YANGAUTOPREFIX1000MS.toString(), "1000ms");
xmlQueryStr = xmlQueryStr.replace(CcmIntervalEnum.YANGAUTOPREFIX3_3MS.toString(), "3.3ms");
xmlQueryStr = xmlQueryStr.replace(CcmIntervalEnum.YANGAUTOPREFIX10MS.toString(), "10ms");
xmlQueryStr = xmlQueryStr.replace(CcmIntervalEnum.YANGAUTOPREFIX100MS.toString(), "100ms");
xmlQueryStr = xmlQueryStr.replace(CcmIntervalEnum.YANGAUTOPREFIX1S.toString(), "1s");
return session.editConfig(targetDs, null, xmlQueryStr);
}
/**
* Internal method to generically call a NETCONF custom RPC from a set of YANG objects.
*
* @param customRpcInput A YANG object model
* @param rpcName The name of the RPC - replaces 'input' in the XML payload
* @param session A NETCONF session
* @return ModelObjectData value indicating success or failure of command
* @throws NetconfException if the session has any error
*/
protected final ModelObjectData customRpcNetconf(
ModelObjectData customRpcInput, String rpcName, NetconfSession session)
throws NetconfException {
if (customRpcInput == null) {
throw new NetconfException("Input object cannot be null");
} else if (session == null) {
throw new NetconfException("Session is null when calling customRpcNetconf()");
}
String xmlQueryStr = encodeMoToXmlStr(customRpcInput, null);
xmlQueryStr = xmlQueryStr.replace("input", rpcName);
log.debug("Sending <edit-config> query on NETCONF session " + session.getSessionId() +
":\n" + xmlQueryStr);
String xmlResult = session.doWrappedRpc(xmlQueryStr);
xmlResult = removeRpcReplyData(xmlResult);
if (REGEX_RPC_OK.matcher(xmlResult).matches()) {
return null;
}
DefaultCompositeStream resultDcs = new DefaultCompositeStream(
null, new ByteArrayInputStream(xmlResult.getBytes()));
CompositeData compositeData = xSer.decode(resultDcs, yCtx);
return ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
}
protected final String encodeMoToXmlStr(ModelObjectData yangObjectOpParamFilter,
List<AnnotatedNodeInfo> annotations)
throws NetconfException {
@ -231,8 +281,12 @@ public abstract class AbstractYangServiceImpl {
}
}
protected static final String removeRpcReplyData(String rpcReplyXml) {
protected static final String removeRpcReplyData(String rpcReplyXml) throws NetconfException {
rpcReplyXml = REGEX_XML_HEADER.matcher(rpcReplyXml).replaceFirst("");
if (rpcReplyXml.contains("<rpc-error")) {
throw new NetconfException("NETCONF rpc-error: " + rpcReplyXml);
}
rpcReplyXml = REGEX_RPC_REPLY.matcher(rpcReplyXml).replaceFirst("");
rpcReplyXml = REGEX_RPC_REPLY_DATA_NS.matcher(rpcReplyXml).replaceFirst("");
rpcReplyXml = REGEX_RPC_REPLY_DATA.matcher(rpcReplyXml).replaceFirst("");

View File

@ -15,11 +15,17 @@
*/
package org.onosproject.drivers.microsemi.yang.impl;
import java.util.ArrayList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
@ -27,14 +33,26 @@ import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.MaintenanceAssociation;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.CcmIntervalEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceOutput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.delaymeasurements.DelayMeasurement;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.augmentedmseacfmmaintenanceassociationendpoint.lossmeasurements.lossmeasurement.MessagePeriodEnum;
import org.onosproject.yang.model.DefaultModelObjectData;
import org.onosproject.yang.model.ModelConverter;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectData;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.runtime.AnnotatedNodeInfo;
import org.onosproject.yang.runtime.CompositeData;
import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo;
import org.onosproject.yang.runtime.DefaultAnnotation;
import org.onosproject.yang.runtime.DefaultCompositeStream;
import java.io.ByteArrayInputStream;
@ -49,6 +67,8 @@ public class MseaCfmManager extends AbstractYangServiceImpl
public static final String MSEA_CFM = "org.onosproject.drivers.microsemi.yang.mseacfmservice";
public static final String MSEA_CFM_NS = "http://www.microsemi.com/microsemi-edge-assure/msea-cfm";
public static final String MSEA_CFM_PM_NS = "http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm";
@Activate
public void activate() {
super.activate();
@ -63,20 +83,51 @@ public class MseaCfmManager extends AbstractYangServiceImpl
}
@Override
public MseaCfm getMepEssentials(String mdName, String maName, int mepId,
NetconfSession session) throws NetconfException {
public MseaCfm getMepEssentials(MdId mdId, MaIdShort maId, MepId mepId,
NetconfSession session) throws NetconfException {
if (session == null) {
throw new NetconfException("Session is null when calling getMepEssentials()");
}
String xmlQueryStr = buildMepQueryString(mdName, maName, mepId);
log.debug("Sending <get> for " +
String xmlQueryStr = buildMepEssentialsQueryString(mdId, maId, mepId);
log.debug("Sending <get> for MEP essentials" +
" query on NETCONF session " + session.getSessionId() +
":\n" + xmlQueryStr);
String xmlResult = session.get(xmlQueryStr, null);
xmlResult = removeRpcReplyData(xmlResult);
xmlResult = removePrefixedMessagePeriod(xmlResult);
DefaultCompositeStream resultDcs = new DefaultCompositeStream(
null, new ByteArrayInputStream(xmlResult.getBytes()));
CompositeData compositeData = xSer.decode(resultDcs, yCtx);
ModelObjectData mod = ((ModelConverter) yangModelRegistry).createModel(
compositeData.resourceData());
MseaCfmOpParam mseaCfm = new MseaCfmOpParam();
for (ModelObject mo:mod.modelObjects()) {
if (mo instanceof DefaultMefCfm) {
mseaCfm.mefCfm((DefaultMefCfm) mo);
}
}
return mseaCfm;
}
@Override
public MseaCfm getMepFull(MdId mdId, MaIdShort maId, MepId mepId,
NetconfSession session) throws NetconfException {
if (session == null) {
throw new NetconfException("Session is null when calling getMepFull()");
}
String xmlQueryStr = buildMepFullQueryString(mdId, maId, mepId);
log.debug("Sending <get> for full MEP" +
" query on NETCONF session " + session.getSessionId() +
":\n" + xmlQueryStr);
String xmlResult = session.get(xmlQueryStr, null);
xmlResult = removeRpcReplyData(xmlResult);
xmlResult = removePrefixedCcmInterval(xmlResult);
DefaultCompositeStream resultDcs = new DefaultCompositeStream(
null, new ByteArrayInputStream(xmlResult.getBytes()));
CompositeData compositeData = xSer.decode(resultDcs, yCtx);
@ -94,41 +145,151 @@ public class MseaCfmManager extends AbstractYangServiceImpl
}
@Override
public MseaCfm getSoamDm(String mdName, String maName, int mepId,
int dmId, NetconfSession session) throws NetconfException {
String xmlQueryStr = buildDmQueryString(mdName, maName, mepId, dmId);
throw new UnsupportedOperationException("Not yet implemented");
public MseaCfm getSoamDm(MdId mdName, MaIdShort maName, MepId mepId,
SoamId dmId, DmEntryParts parts, NetconfSession session)
throws NetconfException {
String xmlQueryStr = buildDmQueryString(mdName, maName, mepId, dmId, parts);
log.debug("Sending <get> for " +
" query on NETCONF session " + session.getSessionId() +
":\n" + xmlQueryStr);
String xmlResult = session.get(xmlQueryStr, null);
xmlResult = removeRpcReplyData(xmlResult);
xmlResult = removePrefixedMessagePeriod(xmlResult);
DefaultCompositeStream resultDcs = new DefaultCompositeStream(
null, new ByteArrayInputStream(xmlResult.getBytes()));
CompositeData compositeData = xSer.decode(resultDcs, yCtx);
ModelObjectData mod = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
MseaCfmOpParam mseaCfm = new MseaCfmOpParam();
for (ModelObject mo:mod.modelObjects()) {
if (mo instanceof DefaultMefCfm) {
mseaCfm.mefCfm((DefaultMefCfm) mo);
}
}
return mseaCfm;
}
@Override
public boolean setMseaCfm(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException {
ModelObjectData moEdit = DefaultModelObjectData.builder()
.addModelObject(mseaCfm).build();
DatastoreId targetDs) throws NetconfException {
return setNetconfObject(moEdit, session, targetDs, null);
ModelObjectData moQuery = DefaultModelObjectData.builder()
.addModelObject((ModelObject) mseaCfm.mefCfm()).build();
return setNetconfObject(moQuery, session, targetDs, null);
}
@Override
public boolean deleteMseaCfmDm(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException {
ModelObjectData mseCfmDmList = DefaultModelObjectData.builder()
.addModelObject((ModelObject) mseaCfm).build();
ArrayList anis = new ArrayList<AnnotatedNodeInfo>();
if (mseaCfm != null && mseaCfm.mefCfm() != null) {
for (MaintenanceDomain md:mseaCfm.mefCfm().maintenanceDomain()) {
for (MaintenanceAssociation ma:md.maintenanceAssociation()) {
for (MaintenanceAssociationEndPoint mep:ma.maintenanceAssociationEndPoint()) {
AugmentedMseaCfmMaintenanceAssociationEndPoint mepAugment =
mep.augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
if (mepAugment != null && mepAugment.delayMeasurements() != null) {
for (DelayMeasurement dms:mepAugment.delayMeasurements().delayMeasurement()) {
ResourceId.Builder ridBuilder = ResourceId.builder()
.addBranchPointSchema("/", null)
.addBranchPointSchema("mef-cfm", MSEA_CFM_NS)
.addBranchPointSchema("maintenance-domain", MSEA_CFM_NS)
.addKeyLeaf("id", MSEA_CFM_NS, md.id())
.addBranchPointSchema("maintenance-association", MSEA_CFM_NS)
.addKeyLeaf("id", MSEA_CFM_NS, ma.id())
.addBranchPointSchema("maintenance-association-end-point", MSEA_CFM_NS)
.addKeyLeaf("mep-id", MSEA_CFM_NS, mep.mepIdentifier())
.addBranchPointSchema("delay-measurements", MSEA_CFM_PM_NS)
.addBranchPointSchema("delay-measurement", MSEA_CFM_PM_NS)
.addKeyLeaf("dm-id", MSEA_CFM_PM_NS, mep.mepIdentifier());
AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder()
.resourceId(ridBuilder.build())
.addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE))
.build();
anis.add(ani);
}
}
}
}
}
}
return setNetconfObject(mseCfmDmList, session, targetDs, anis);
}
@Override
public boolean deleteMseaMep(MseaCfmOpParam mseaCfm, NetconfSession session,
DatastoreId targetDs) throws NetconfException {
ModelObjectData mseCfmMepList = DefaultModelObjectData.builder()
.addModelObject((ModelObject) mseaCfm.mefCfm()).build();
ArrayList anis = new ArrayList<AnnotatedNodeInfo>();
if (mseaCfm != null && mseaCfm.mefCfm() != null) {
for (MaintenanceDomain md:mseaCfm.mefCfm().maintenanceDomain()) {
for (MaintenanceAssociation ma:md.maintenanceAssociation()) {
for (MaintenanceAssociationEndPoint mep:ma.maintenanceAssociationEndPoint()) {
ResourceId.Builder ridBuilder = ResourceId.builder()
.addBranchPointSchema("/", null)
.addBranchPointSchema("mef-cfm", MSEA_CFM_NS)
.addBranchPointSchema("maintenance-domain", MSEA_CFM_NS)
.addBranchPointSchema("maintenance-association", MSEA_CFM_NS)
.addBranchPointSchema("maintenance-association-end-point", MSEA_CFM_NS)
.addKeyLeaf("mep-identifier", MSEA_CFM_NS, mep.mepIdentifier().uint16());
AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder()
.resourceId(ridBuilder.build())
.addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE))
.build();
anis.add(ani);
}
}
}
}
return setNetconfObject(mseCfmMepList, session, targetDs, anis);
}
/**
* Call RPCs on the device through NETCONF.
*/
@Override
public void transmitLoopback(TransmitLoopbackInput inputVar, NetconfSession session) throws NetconfException {
throw new UnsupportedOperationException("Not yet implemented");
public void transmitLoopback(TransmitLoopbackInput inputVar,
NetconfSession session) throws NetconfException {
ModelObjectData transLoopbackMo = DefaultModelObjectData.builder()
.addModelObject((ModelObject) inputVar).build();
customRpcNetconf(transLoopbackMo,
"transmit-loopback", session);
}
@Override
public void abortLoopback(AbortLoopbackInput inputVar, NetconfSession session) throws NetconfException {
throw new UnsupportedOperationException("Not yet implemented");
public void abortLoopback(AbortLoopbackInput inputVar,
NetconfSession session) throws NetconfException {
ModelObjectData abortLoopbackMo = DefaultModelObjectData.builder()
.addModelObject((ModelObject) inputVar).build();
customRpcNetconf(abortLoopbackMo, "abort-loopback", session);
}
@Override
public TransmitLinktraceOutput transmitLinktrace(TransmitLinktraceInput inputVar, NetconfSession session)
public TransmitLinktraceOutput transmitLinktrace(
TransmitLinktraceInput inputVar, NetconfSession session)
throws NetconfException {
throw new UnsupportedOperationException("Not yet implemented");
}
private String buildMepQueryString(String mdName, String maName, int mepId) {
@Deprecated //Replace this with a ModelObject defintion
private String buildMepEssentialsQueryString(MdId mdId, MaIdShort maId,
MepId mepId) {
StringBuilder rpc = new StringBuilder();
rpc.append("<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" ");
@ -136,29 +297,31 @@ public class MseaCfmManager extends AbstractYangServiceImpl
rpc.append("xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">\n");
rpc.append("<maintenance-domain>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + mdName + "</name>\n");
rpc.append("<md-level/>\n");
rpc.append("<name>" + mdId.mdName() + "</name>\n");
rpc.append("<maintenance-association>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + maName + "</name>\n");
rpc.append("<name>" + maId.maName() + "</name>\n");
rpc.append("<ccm-interval>10ms</ccm-interval>\n");
rpc.append("<remote-meps/>\n");
rpc.append("<component-list/>\n");
rpc.append("<maintenance-association-end-point>\n");
rpc.append("<mep-identifier>" + mepId + "</mep-identifier>\n");
rpc.append("<interface/>\n");
rpc.append("<primary-vid/>\n");
rpc.append("<administrative-state/>\n");
rpc.append("<ccm-ltm-priority/>\n");
rpc.append("<continuity-check/>\n");
rpc.append("<mep-identifier>" + mepId.id() + "</mep-identifier>\n");
rpc.append("<mac-address/>\n");
rpc.append("<msea-soam-fm:port-status/>\n");
rpc.append("<msea-soam-fm:interface-status/>\n");
rpc.append("<msea-soam-fm:last-defect-sent/>\n");
rpc.append("<msea-soam-fm:rdi-transmit-status/>\n");
rpc.append("<loopback/>\n");
rpc.append("<remote-mep-database/>\n");
rpc.append("<linktrace/>\n");
rpc.append("<remote-mep-database>\n");
rpc.append("<remote-mep>\n");
rpc.append("<remote-mep-id/>\n");
rpc.append("</remote-mep>\n");
rpc.append("</remote-mep-database>\n");
rpc.append("<msea-soam-pm:delay-measurements>\n");
rpc.append("<msea-soam-pm:delay-measurement>\n");
rpc.append("<msea-soam-pm:dm-id/>\n");
rpc.append("</msea-soam-pm:delay-measurement>\n");
rpc.append("</msea-soam-pm:delay-measurements>\n");
rpc.append("<msea-soam-pm:loss-measurements>\n");
rpc.append("<msea-soam-pm:loss-measurement>\n");
rpc.append("<msea-soam-pm:lm-id/>\n");
rpc.append("</msea-soam-pm:loss-measurement>\n");
rpc.append("</msea-soam-pm:loss-measurements>\n");
rpc.append("</maintenance-association-end-point>\n");
rpc.append("</maintenance-association>\n");
rpc.append("</maintenance-domain>\n");
@ -167,8 +330,8 @@ public class MseaCfmManager extends AbstractYangServiceImpl
return rpc.toString();
}
private String buildDmQueryString(String mdName, String maName, int mepId, int dmId) {
@Deprecated //Replace this with a ModelObject defintion
private String buildMepFullQueryString(MdId mdId, MaIdShort maId, MepId mepId) {
StringBuilder rpc = new StringBuilder();
rpc.append("<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" ");
@ -176,19 +339,28 @@ public class MseaCfmManager extends AbstractYangServiceImpl
rpc.append("xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">\n");
rpc.append("<maintenance-domain>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + mdName + "</name>\n");
rpc.append("<md-level/>\n");
rpc.append("<name>" + mdId.mdName() + "</name>\n");
rpc.append("<maintenance-association>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + maName + "</name>\n");
rpc.append("<ccm-interval>10ms</ccm-interval>\n");
rpc.append("<name>" + maId.maName() + "</name>\n");
rpc.append("<maintenance-association-end-point>\n");
rpc.append("<mep-identifier>" + mepId + "</mep-identifier>\n");
rpc.append("<msea-soam-pm:delay-measurements>");
rpc.append("<msea-soam-pm:delay-measurement>");
rpc.append("<msea-soam-pm:dm-id>" + dmId + "</msea-soam-pm:dm-id>");
rpc.append("</msea-soam-pm:delay-measurement>");
rpc.append("</msea-soam-pm:delay-measurements>");
rpc.append("<mep-identifier>" + mepId.id() + "</mep-identifier>\n");
rpc.append("<interface/>\n");
//Direction will always be DOWN for EA1000
rpc.append("<primary-vid/>\n");
rpc.append("<administrative-state/>\n");
rpc.append("<mac-address/>\n");
rpc.append("<ccm-ltm-priority/>\n");
rpc.append("<continuity-check/>\n"); //Container
rpc.append("<loopback/>\n"); //Container
rpc.append("<linktrace/>\n"); //Container
rpc.append("<remote-mep-database/>\n"); //Container
rpc.append("<msea-soam-fm:operational-state/>\n");
rpc.append("<msea-soam-fm:connectivity-status/>\n");
rpc.append("<msea-soam-fm:port-status/>\n");
rpc.append("<msea-soam-fm:interface-status/>\n");
rpc.append("<msea-soam-fm:last-defect-sent/>\n");
rpc.append("<msea-soam-fm:rdi-transmit-status/>\n");
rpc.append("</maintenance-association-end-point>\n");
rpc.append("</maintenance-association>\n");
rpc.append("</maintenance-domain>\n");
@ -197,4 +369,95 @@ public class MseaCfmManager extends AbstractYangServiceImpl
return rpc.toString();
}
@Deprecated //Replace this with a ModelObject defintion
private String buildDmQueryString(MdId mdId, MaIdShort maId, MepId mepId,
SoamId dmId, DmEntryParts parts) {
StringBuilder rpc = new StringBuilder();
rpc.append("<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" ");
rpc.append(" xmlns:msea-soam-fm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-fm\" ");
rpc.append("xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">\n");
rpc.append("<maintenance-domain>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + mdId.mdName() + "</name>\n");
rpc.append("<maintenance-association>\n");
rpc.append("<id/>\n");
rpc.append("<name>" + maId.maName() + "</name>\n");
rpc.append("<maintenance-association-end-point>\n");
rpc.append("<mep-identifier>" + mepId.id() + "</mep-identifier>\n");
if (dmId != null) {
rpc.append("<msea-soam-pm:delay-measurements>");
rpc.append("<msea-soam-pm:delay-measurement>\n");
rpc.append("<msea-soam-pm:dm-id>" + dmId.id() + "</msea-soam-pm:dm-id>\n");
rpc.append("<msea-soam-pm:mep-id/>");
rpc.append("<msea-soam-pm:mac-address/>");
rpc.append("<msea-soam-pm:administrative-state/>\n");
rpc.append("<msea-soam-pm:measurement-enable/>\n");
rpc.append("<msea-soam-pm:message-period/>\n");
rpc.append("<msea-soam-pm:priority/>\n");
rpc.append("<msea-soam-pm:frame-size/>\n");
rpc.append("<msea-soam-pm:measurement-interval/>\n");
rpc.append("<msea-soam-pm:number-intervals-stored/>\n");
rpc.append("<msea-soam-pm:session-status/>\n");
rpc.append("<msea-soam-pm:frame-delay-two-way/>\n");
rpc.append("<msea-soam-pm:inter-frame-delay-variation-two-way/>\n");
if (parts != null && (parts.equals(DmEntryParts.CURRENT_ONLY) ||
parts.equals(DmEntryParts.ALL_PARTS))) {
rpc.append("<msea-soam-pm:current-stats/>\n");
}
if (parts != null && (parts.equals(DmEntryParts.HISTORY_ONLY) ||
parts.equals(DmEntryParts.ALL_PARTS))) {
rpc.append("<msea-soam-pm:history-stats/>\n");
}
rpc.append("</msea-soam-pm:delay-measurement>\n");
rpc.append("</msea-soam-pm:delay-measurements>");
} else {
rpc.append("<msea-soam-pm:delay-measurements/>");
}
rpc.append("</maintenance-association-end-point>\n");
rpc.append("</maintenance-association>\n");
rpc.append("</maintenance-domain>\n");
rpc.append("</mef-cfm>");
return rpc.toString();
}
@Deprecated //Replace this with a ModelObject defintion
private String buildAbortLoopbackQueryString(Short mdId, Short maId,
Short mepId) {
StringBuilder rpc = new StringBuilder();
rpc.append("<abort-loopback xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\">");
rpc.append("<maintenance-domain>" + mdId + "</maintenance-domain>");
rpc.append("<maintenance-association>" + maId + "</maintenance-association>");
rpc.append("<maintenance-association-end-point>" + mepId + "</maintenance-association-end-point>");
rpc.append("</abort-loopback>");
return rpc.toString();
}
private static final String removePrefixedMessagePeriod(String xmlResult) {
xmlResult = xmlResult.replace("message-period>3ms</",
"message-period>" + MessagePeriodEnum.YANGAUTOPREFIX3MS.toString() + "</");
xmlResult = xmlResult.replace("message-period>10ms</",
"message-period>" + MessagePeriodEnum.YANGAUTOPREFIX10MS.toString() + "</");
xmlResult = xmlResult.replace("message-period>100ms</",
"message-period>" + MessagePeriodEnum.YANGAUTOPREFIX100MS.toString() + "</");
xmlResult = xmlResult.replace("message-period>1000ms</",
"message-period>" + MessagePeriodEnum.YANGAUTOPREFIX1000MS.toString() + "</");
return xmlResult;
}
private static final String removePrefixedCcmInterval(String xmlResult) {
xmlResult = xmlResult.replace("ccm-interval>3.3ms</",
"ccm-interval>" + CcmIntervalEnum.YANGAUTOPREFIX3_3MS.toString() + "</");
xmlResult = xmlResult.replace("ccm-interval>10ms</",
"ccm-interval>" + CcmIntervalEnum.YANGAUTOPREFIX10MS.toString() + "</");
xmlResult = xmlResult.replace("ccm-interval>100ms</",
"ccm-interval>" + CcmIntervalEnum.YANGAUTOPREFIX100MS.toString() + "</");
xmlResult = xmlResult.replace("ccm-interval>1s</",
"ccm-interval>" + CcmIntervalEnum.YANGAUTOPREFIX1S.toString() + "</");
return xmlResult;
}
}

View File

@ -288,4 +288,4 @@ public class MseaUniEvcServiceManager extends AbstractYangServiceImpl
return sb.toString();
}
}
}

View File

@ -15,6 +15,7 @@
*/
package org.onosproject.drivers.microsemi.yang.utils;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
@ -61,4 +62,13 @@ public final class IetfYangTypesUtils {
return LocalDateTime.ofInstant(odt.toInstant(), ZoneId.systemDefault());
}
/**
* Convert a from Date and Time in a ietf-yang-types format to the Java Time API as an Instant.
* @param dateAndTime A date and time from a YANG object
* @return The date and time as an Instant
*/
public static Instant fromYangDateTimeToInstant(DateAndTime dateAndTime) {
return Instant.from(OffsetDateTime.parse(dateAndTime.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2017-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.microsemi.yang.utils;
import org.onlab.util.HexString;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes.YangIdentifier;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaNameAndTypeCombo;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.DefaultNameCharacterString;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.DefaultNamePrimaryVid;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.DefaultNameRfc2685VpnId;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.DefaultNameUint16;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.DefaultNameY1731Icc;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.manameandtypecombo.nameprimaryvid.NamePrimaryVidUnion;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
/**
* This is a workaround for Checkstyle issue.
* https://github.com/checkstyle/checkstyle/issues/3850
* There are two types of DefaultNameCharacterString - one for MA and another for MD
* Putting both together in a file means that the full path has to be given which
* will then fail checkstyle
*/
public final class MaNameUtil {
private MaNameUtil() {
//Hidden
}
public static MaNameAndTypeCombo getYangMaNameFromApiMaId(MaIdShort maId)
throws CfmConfigException {
MaNameAndTypeCombo maName;
if (maId instanceof MaIdPrimaryVid) {
maName = new DefaultNamePrimaryVid();
((DefaultNamePrimaryVid) maName).namePrimaryVid(NamePrimaryVidUnion.fromString(maId.maName()));
} else if (maId instanceof MaId2Octet) {
maName = new DefaultNameUint16();
((DefaultNameUint16) maName).nameUint16(Integer.valueOf(maId.maName()));
} else if (maId instanceof MaIdRfc2685VpnId) {
maName = new DefaultNameRfc2685VpnId();
((DefaultNameRfc2685VpnId) maName).nameRfc2685VpnId(HexString.fromHexString(maId.maName()));
} else if (maId instanceof MaIdIccY1731) {
maName = new DefaultNameY1731Icc();
((DefaultNameY1731Icc) maName).nameY1731Icc(YangIdentifier.of(maId.maName()));
} else if (maId instanceof MaIdCharStr) {
maName = new DefaultNameCharacterString();
((DefaultNameCharacterString) maName).name(Identifier45.fromString(maId.maName()));
} else {
throw new CfmConfigException("Unexpected error creating MD " +
maId.getClass().getSimpleName());
}
return maName;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2017-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.microsemi.yang.utils;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.RemoteMep;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.remotemep.MepId;
/**
* This is a workaround for Checkstyle issue.
* https://github.com/checkstyle/checkstyle/issues/3850
*
*/
public final class MepIdUtil {
private MepIdUtil() {
//Hidden
}
public static MepId convertRemoteMepId(RemoteMep rmep) {
return (MepId) rmep;
}
public static AugmentedMseaCfmMaintenanceAssociationEndPoint
convertPmAugmentedMep(MaintenanceAssociationEndPoint mep) {
AugmentedMseaCfmMaintenanceAssociationEndPoint augmentedMep =
(AugmentedMseaCfmMaintenanceAssociationEndPoint) mep
.augmentation(
DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
return augmentedMep;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2017-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.microsemi.yang.utils;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.TargetAddress;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.MepId;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.MacAddress;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
/**
* This is a workaround for Checkstyle issue.
* https://github.com/checkstyle/checkstyle/issues/3850
*
*/
public final class MepIdUtil2 {
private MepIdUtil2() {
//Hidden
}
public static MepId convertTargetAddrToMepId(TargetAddress targetMep) {
return (MepId) targetMep.addressType();
}
public static MacAddress convertTargetAddrToMacAddress(TargetAddress targetMep) {
return (MacAddress) targetMep.addressType();
}
public static AugmentedMseaCfmMaintenanceAssociationEndPoint
convertFmAugmentedMep(MaintenanceAssociationEndPoint mep) {
return (AugmentedMseaCfmMaintenanceAssociationEndPoint) mep
.augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2017-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.microsemi.yang.utils;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.RemoteMep;
import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.mseasoampm.remotemepgroup.remotemep.DefaultMepId;
public final class MepIdUtil3 {
private MepIdUtil3() {
//Hidden
}
public static DefaultMepId convertPmRemoteMepToMepId(RemoteMep remoteMep) {
return (DefaultMepId) remoteMep;
}
}

Some files were not shown because too many files have changed in this diff Show More