From 8e869851857c216b2513c2bf1adae927737de507 Mon Sep 17 00:00:00 2001 From: Martial COULIBALY Date: Fri, 5 May 2017 11:24:49 +0200 Subject: [PATCH] Initial commit for ServiceHandler - Add Servicehandler folder to project - Add Stubpce & Stubrender folder to project - Add RPCs implementation : * serviceCreate * serviceDelete * serviceFeasabilityCheck * serviceReconfigure * serviceRestoration Change-Id: I98c887222ab57d15a41aecf1097b1ee5c894c251 Signed-off-by: Martial COULIBALY Signed-off-by: Xavier POUGNARD --- features/pom.xml | 15 + features/src/main/features/features.xml | 5 +- ordmodels/pom.xml | 24 + .../pm/types/rev161014/PmDataTypeBuilder.java | 19 + .../facility/LogFacilityFacilityBuilder.java | 20 + .../state/schemas/SchemaLocationBuilder.java | 20 + .../rev131019/DatastoreIdentifierBuilder.java | 19 + .../modules/ModuleRevisionBuilder.java | 20 + .../rev160409/OptionalRevisionBuilder.java | 19 + .../list/CommonLeafsRevisionBuilder.java | 20 + .../org-openroadm-common-service-types.yang | 514 +++++ ...nroadm-routing-constraints@2016-10-14.yang | 128 + .../src/main/yang/org-openroadm-topology.yang | 91 + ...ransportpce-common-service-path-types.yang | 217 ++ .../transportpce-pathDescription.yang | 142 ++ .../transportpce-routing-constraints.yang | 179 ++ .../transportpce-service-path.yang | 167 ++ .../main/yang/servicehandler@2016-10-14.yang | 593 +++++ ordmodels/src/main/yang/stubpce.yang | 135 ++ ordmodels/src/main/yang/stubrenderer.yang | 138 ++ pom.xml | 3 + servicehandler/pom.xml | 57 + .../CheckCoherencyHardSoft.java | 52 + .../LoggingFuturesCallBack.java | 41 + .../MappingAndSendingPCRequest.java | 325 +++ .../MappingAndSendingSIRequest.java | 701 ++++++ .../servicehandler/MappingConstraints.java | 289 +++ .../servicehandler/MyEndpoint.java | 59 + .../ServicehandlerCompliancyCheck.java | 180 ++ .../ServicehandlerTxRxCheck.java | 201 ++ .../impl/ServicehandlerImpl.java | 2056 +++++++++++++++++ .../impl/ServicehandlerProvider.java | 74 + .../blueprint/Servicehandler-blueprint.xml | 39 + stubpce/pom.xml | 54 + .../transportpce/stubpce/CompliancyCheck.java | 80 + .../transportpce/stubpce/SendingPceRPCs.java | 275 +++ .../stubpce/impl/StubpceImpl.java | 171 ++ .../stubpce/impl/StubpceProvider.java | 61 + .../blueprint/Stubpce-blueprint.xml | 35 + stubrenderer/pom.xml | 52 + .../stubrenderer/SendingRendererRPCs.java | 94 + .../stubrenderer/impl/StubrendererImpl.java | 161 ++ .../impl/StubrendererProvider.java | 60 + .../blueprint/stubrenderer-blueprint.xml | 35 + 44 files changed, 7639 insertions(+), 1 deletion(-) create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev161014/PmDataTypeBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev161014/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/DatastoreIdentifierBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/restconf/restconf/modules/ModuleRevisionBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160409/OptionalRevisionBuilder.java create mode 100644 ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160621/module/list/CommonLeafsRevisionBuilder.java create mode 100644 ordmodels/src/main/yang/org-openroadm-common-service-types.yang create mode 100644 ordmodels/src/main/yang/org-openroadm-routing-constraints@2016-10-14.yang create mode 100644 ordmodels/src/main/yang/org-openroadm-topology.yang create mode 100644 ordmodels/src/main/yang/service_path_v1.5/transportpce-common-service-path-types.yang create mode 100644 ordmodels/src/main/yang/service_path_v1.5/transportpce-pathDescription.yang create mode 100644 ordmodels/src/main/yang/service_path_v1.5/transportpce-routing-constraints.yang create mode 100644 ordmodels/src/main/yang/service_path_v1.5/transportpce-service-path.yang create mode 100644 ordmodels/src/main/yang/servicehandler@2016-10-14.yang create mode 100644 ordmodels/src/main/yang/stubpce.yang create mode 100644 ordmodels/src/main/yang/stubrenderer.yang create mode 100644 servicehandler/pom.xml create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/CheckCoherencyHardSoft.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/LoggingFuturesCallBack.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingPCRequest.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingSIRequest.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingConstraints.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MyEndpoint.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerCompliancyCheck.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerTxRxCheck.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java create mode 100644 servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerProvider.java create mode 100644 servicehandler/src/main/resources/org/opendaylight/blueprint/Servicehandler-blueprint.xml create mode 100644 stubpce/pom.xml create mode 100644 stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java create mode 100644 stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java create mode 100644 stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java create mode 100644 stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java create mode 100644 stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml create mode 100644 stubrenderer/pom.xml create mode 100644 stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/SendingRendererRPCs.java create mode 100644 stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererImpl.java create mode 100644 stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererProvider.java create mode 100644 stubrenderer/src/main/resources/org/opendaylight/blueprint/stubrenderer-blueprint.xml diff --git a/features/pom.xml b/features/pom.xml index 91f24608d..007f800bb 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -211,5 +211,20 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL transportpce-cli ${project.version} + + ${project.groupId} + transportpce-stubrenderer + ${project.version} + + + ${project.groupId} + transportpce-stubpce + ${project.version} + + + ${project.groupId} + transportpce-servicehandler + ${project.version} + diff --git a/features/src/main/features/features.xml b/features/src/main/features/features.xml index 4d9c087fa..b6959fbab 100644 --- a/features/src/main/features/features.xml +++ b/features/src/main/features/features.xml @@ -36,6 +36,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html mvn:org.opendaylight.transportpce/transportpce-impl/{{VERSION}} mvn:org.opendaylight.transportpce/transportpce-renderer/{{VERSION}} mvn:org.opendaylight.transportpce/transportpce-olm/{{VERSION}} + mvn:org.opendaylight.transportpce/transportpce-stubrenderer/{{VERSION}} + mvn:org.opendaylight.transportpce/transportpce-stubpce/{{VERSION}} + mvn:org.opendaylight.transportpce/transportpce-servicehandler/{{VERSION}} odl-transportpce @@ -52,4 +55,4 @@ and is available at http://www.eclipse.org/legal/epl-v10.html mvn:org.opendaylight.transportpce/transportpce-cli/{{VERSION}} - \ No newline at end of file + diff --git a/ordmodels/pom.xml b/ordmodels/pom.xml index 08e498835..2da297f14 100644 --- a/ordmodels/pom.xml +++ b/ordmodels/pom.xml @@ -54,4 +54,28 @@ and is available at http://www.eclipse.org/legal/epl-v10.html ietf-packet-fields + + + + + org.apache.felix + maven-bundle-plugin + 3.0.1 + true + + + {maven-resources},target/classes/LICENSE,META-INF/git.properties=-target/classes/META-INF/git.properties + <_exportcontents> + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.transportpce.stubrenderer.rev170403.service.implementation.request.input, + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.rev170120.service.implementation.request.input, + org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.internal.link, + org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.internal.links,* + + + + + + diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev161014/PmDataTypeBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev161014/PmDataTypeBuilder.java new file mode 100644 index 000000000..0ee83b66e --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev161014/PmDataTypeBuilder.java @@ -0,0 +1,19 @@ +package org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class PmDataTypeBuilder { + + public static PmDataType getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev161014/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev161014/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java new file mode 100644 index 000000000..2a3b58a6c --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev161014/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java @@ -0,0 +1,20 @@ +package org.opendaylight.yang.gen.v1.http.org.openroadm.syslog.rev161014.syslog.selector.log.selector.selector.facility.log.facility; +import org.opendaylight.yang.gen.v1.http.org.openroadm.syslog.rev161014.syslog.selector.log.selector.selector.facility.log.facility.LogFacility.Facility; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class LogFacilityFacilityBuilder { + + public static Facility getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java new file mode 100644 index 000000000..a4570e130 --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java @@ -0,0 +1,20 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class SchemaLocationBuilder { + + public static Location getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/DatastoreIdentifierBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/DatastoreIdentifierBuilder.java new file mode 100644 index 000000000..20d96d995 --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/DatastoreIdentifierBuilder.java @@ -0,0 +1,19 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class DatastoreIdentifierBuilder { + + public static DatastoreIdentifier getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/restconf/restconf/modules/ModuleRevisionBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/restconf/restconf/modules/ModuleRevisionBuilder.java new file mode 100644 index 000000000..0a3a91aea --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/restconf/rev131019/restconf/restconf/modules/ModuleRevisionBuilder.java @@ -0,0 +1,20 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev131019.restconf.restconf.modules.Module.Revision; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ModuleRevisionBuilder { + + public static Revision getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160409/OptionalRevisionBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160409/OptionalRevisionBuilder.java new file mode 100644 index 000000000..54ee117be --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160409/OptionalRevisionBuilder.java @@ -0,0 +1,19 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class OptionalRevisionBuilder { + + public static OptionalRevision getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160621/module/list/CommonLeafsRevisionBuilder.java b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160621/module/list/CommonLeafsRevisionBuilder.java new file mode 100644 index 000000000..3d675115f --- /dev/null +++ b/ordmodels/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/yang/library/rev160621/module/list/CommonLeafsRevisionBuilder.java @@ -0,0 +1,20 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.CommonLeafs.Revision; + + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class CommonLeafsRevisionBuilder { + + public static Revision getDefaultInstance(java.lang.String defaultValue) { + throw new java.lang.UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/ordmodels/src/main/yang/org-openroadm-common-service-types.yang b/ordmodels/src/main/yang/org-openroadm-common-service-types.yang new file mode 100644 index 000000000..6e17b7d7c --- /dev/null +++ b/ordmodels/src/main/yang/org-openroadm-common-service-types.yang @@ -0,0 +1,514 @@ +module org-openroadm-common-service-types { + namespace "http://org/openroadm/common/service/types"; + prefix org-openroadm-common-service-types; + + import ietf-yang-types { + prefix yang; + } + import ietf-inet-types { + prefix inet; + } + import org-openroadm-routing-constraints { + prefix org-openroadm-routing-constraints; + revision-date 2016-10-14; + } + import org-openroadm-topology { + prefix org-openroadm-topology; + } + import org-openroadm-common-types { + prefix org-openroadm-common-types; + revision-date 2016-10-14; + } + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + } + + organization + "Open ROADM MSA"; + contact + "OpenROADM.org"; + description + "YANG definitions of common service types. + + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2016-10-14 { + description + "Version 1.2"; + } + + grouping configuration-response-common { + container configuration-response-common { + leaf request-id { + type string; + mandatory true; + } + leaf response-code { + type string; + mandatory true; + } + leaf response-message { + type string; + } + leaf ack-final-indicator { + type string; + mandatory true; + } + } + } + + grouping response-parameters { + container response-parameters { + uses org-openroadm-routing-constraints:routing-constraints; + } + } + + grouping service-endpoint { + leaf service-format { + type service-format; + mandatory true; + description + "Format of the requested service: Ethernet, OTU, etc."; + } + leaf service-rate { + when "../service-format!='OMS'"{ + description "service rate not applicable when service + format is roadmline"; + } + type uint32; + mandatory true; + description + "Rate of the requested service in GBps"; + } + leaf clli { + type string; + mandatory true; + description + "CLLI"; + } + uses org-openroadm-resource-types:device-id; + container site; + container tx-direction { + uses service-port; + uses service-lgx; + uses service-tail; + } + container rx-direction { + uses service-port; + uses service-lgx; + uses service-tail; + } + leaf optic-type { + type org-openroadm-common-types:optic-types; + } + container router { + description + "Needed for communication with DWDM pluggable"; + leaf node-id { + type string; + description + "Node id. This is reported against the service, but may not get reflected in the service in the network."; + } + leaf ip-address { + type inet:ip-address; + description + "Router IP Address. This is reported against the service, but may not get reflected in the service in the network."; + } + leaf url { + type string; + description + "URL needed for communication with DWDM pluggable. This is reported against the service, but may not get reflected in the service in the network."; + } + } + leaf user-label { + type string; + mandatory false; + description + "Label for service endpoint, defined by the user"; + } + } + + typedef rpc-actions { + description "rpc-actions include all the rpc methods"; + type enumeration { + enum service-create { + value "1"; + } + enum service-feasibility-check { + value "2"; + } + enum service-delete { + value "3"; + } + enum equipment-notification { + value "4"; + } + enum temp-service-create { + value "5"; + } + enum temp-service-delete { + value "6"; + } + enum service-roll { + value "7"; + } + enum service-reconfigure { + value "8"; + } + enum service-restoration { + value "9"; + } + enum service-reversion { + value "10"; + } + enum service-reroute { + value "11"; + } + enum service-reroute-confirm { + value "12"; + } + enum network-re-optimization { + value "13"; + } + } + } + + grouping sdnc-request-header { + container sdnc-request-header { + leaf request-id { + type string; + } + leaf rpc-action { + type rpc-actions; + } + leaf notification-url { + type string; + } + leaf request-system-id{ + type string; + } + } + } + + grouping service-port { + container port { + leaf port-device-name { + type string; + } + leaf port-type { + type string; + } + leaf port-name { + type string; + } + leaf port-rack { + type string; + } + leaf port-shelf { + type string; + } + leaf port-slot { + type string; + } + leaf port-sub-slot { + type string; + } + } + } + + grouping service-lgx { + container lgx { + leaf lgx-device-name { + type string; + } + leaf lgx-port-name { + type string; + } + leaf lgx-port-rack { + type string; + } + leaf lgx-port-shelf { + type string; + } + } + } + + grouping service-tail { + container tail { + container tail-roadm { + description + "ROADM on which the transponder is connected to (TID, IP Address, + or FQDN)"; + uses org-openroadm-resource-types:device-id; + } + container xponder-port { + description + "Muxponder port used in tail, that will get used as a service endpoint."; + leaf circuit-pack-name { + type string; + } + leaf port-name { + type string; + } + } + leaf tail-roadm-port-aid { + type string; + description + "This will provide the transponder port needed to inter-city ROADM + connection"; + } + leaf tail-roadm-port-rack-location { + type string; + description + "Transponder's location"; + } + } + } + + grouping service-information { + leaf due-date { + type yang:date-and-time; + description + "Date and time service to be turn up. If time is not specified for a given date, default to midnight. Service turned up immediately if no due date is specified"; + } + leaf end-date { + type yang:date-and-time; + description + "Date and time service to be removed"; + mandatory false; + } + leaf nc-code { + type string; + description + "NC code applied to wavelength service only.This is reported against the service, but may not get reflected in the service in the network."; + } + leaf nci-code { + type string; + description + "NCI code applied to wavelength service only.This is reported against the service, but may not get reflected in the service in the network."; + } + leaf secondary-nci-code { + type string; + description + "NC code applied to wavelength service only.This is reported against the service, but may not get reflected in the service in the network."; + } + leaf customer { + type string; + description + "To be included in ticket information.This is reported against the service, but may not get reflected in the service in the network."; + } + leaf customer-contact { + type string; + description + "Customer contact information To be included in ticket information. This is reported against the service, but may not get reflected in the service in the network."; + } + leaf operator-contact { + type string; + description + "Operator contact information to be included in ticket information. This is reported against the service, but may not get reflected in the service in the network."; + } + } + + grouping service { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc."; + mandatory true; + } + leaf common-id { + type string; + description + "To be used by the ROADM controller to identify the routing + constraints received from planning application (PED)."; + } + uses sdnc-request-header; + leaf connection-type { + type connection-type; + mandatory true; + description + "Connection type"; + } + leaf lifecycle-state { + type org-openroadm-common-types:lifecycle-state; + description + "Lifecycle State of service. Whether it is planned, deployed, in maintenance, etc."; + } + leaf administrative-state { + type org-openroadm-common-types:state; + description + "Administrative State: Intended state of service"; + } + leaf operational-state { + type org-openroadm-common-types:state; + config false; + description + "Operational State: Actual state of service"; + } + leaf condition { + type service-condition; + description + "Service Condition: Additional information about the state of the service. Only sent when applicable."; + } + container service-a-end { + uses service-endpoint; + } + container service-z-end { + uses service-endpoint; + } + uses org-openroadm-routing-constraints:routing-constraints; + uses service-information; + leaf latency { + type uint32; + description + "Latency on service"; + } + leaf-list fiber-span-srlgs { + type string; + description + "Shared risk link group identifiers"; + } + list equipment-srgs { + key "srg-number"; + uses org-openroadm-resource-types:srg-number; + } + leaf-list supporting-service-name { + description + "The service name that this runs over top. If connection-type is service, then this is the related + connection-type = infrastructure service, for example."; + type string; + } + container topology { + uses org-openroadm-topology:topology; + } + } + + grouping service-notification-result { + leaf service-name { + type string; + description + "Identifier for the service e.g., CLFI, CLCI, etc."; + mandatory true; + } + leaf actual-date { + type yang:date-and-time; + description + "Actual date and time (if successful)"; + } + } + + typedef service-format { + type enumeration { + enum "Ethernet" { + value 1; + } + enum "OTU" { + value 2; + } + enum "OC" { + value 3; + } + enum "STM" { + value 4; + } + enum "OMS" { + value 5; + } + enum "ODU" { + value 6; + } + enum "OTM" { + value 7; + } + } + } + + typedef service-notification-types { + type enumeration { + enum "service-create-result" { + value 1; + } + enum "service-reconfigure-result" { + value 2; + } + enum "service-delete-result" { + value 3; + } + enum "service-roll-result" { + value 4; + } + enum "service-revert-result" { + value 5; + } + enum "service-reroute-result" { + value 6; + } + enum "service-restoration-result" { + value 7; + } + //Add Martial + enum "service-feasibility-check-result" { + value 8; + } + } + } + + typedef connection-type { + type enumeration { + enum "service" { + value 1; + } + enum "infrastructure" { + value 2; + } + enum "roadm-line" { + value 3; + } + } + } + + typedef service-condition { + type enumeration { + enum "restored-temporarily" { + value 1; + } + enum "re-routed-temporarily" { + value 2; + } + enum "activated-for-service" { + value 3; + } + enum "activated-for-further-check" { + value 4; + } + enum "activated-for-troubleshooting-failure" { + value 5; + } + } + } +} diff --git a/ordmodels/src/main/yang/org-openroadm-routing-constraints@2016-10-14.yang b/ordmodels/src/main/yang/org-openroadm-routing-constraints@2016-10-14.yang new file mode 100644 index 000000000..229726b08 --- /dev/null +++ b/ordmodels/src/main/yang/org-openroadm-routing-constraints@2016-10-14.yang @@ -0,0 +1,128 @@ +module org-openroadm-routing-constraints { + namespace "http://org/openroadm/routing/constrains"; + prefix org-openroadm-routing-constraints; + + organization + "Open ROADM MSA"; + contact + "OpenROADM.org"; + description + "YANG definitions of routing constraints. + + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2016-10-14 { + description + "Version 1.2"; + } + + grouping routing-constraints { + container hard-constraints { + uses constraints; + } + container soft-constraints { + uses constraints; + } + } + + grouping constraints { + leaf-list customer-code { + type string; + } + choice co-routing-or-general { + case general { + container diversity { + uses diversity-existing-service-contraints; + } + container exclude { + uses common-constraints; + leaf-list supporting-service-name { + description + "Supporting service(s) to exclude from this route."; + type string; + } + } + container include { + uses common-constraints; + leaf-list supporting-service-name { + description + "Supporting service(s) to include in this route."; + type string; + } + } + container latency { + description + "Maximum latency allowed"; + leaf max-latency { + type uint32; + units "ms"; + } + } + } + case co-routing { + container co-routing { + leaf-list existing-service { + type string; + description + "Diverse from existing services identified by facility CLFI"; + } + } + } + } + } + + grouping common-constraints { + leaf-list fiber-bundle { + type string; + } + leaf-list site { + type string; + } + leaf-list node-id { + type string; + } + } + + grouping diversity-existing-service-contraints { + leaf-list existing-service { + type string; + description + "Diverse from existing services identified by facility CLFI"; + } + container existing-service-applicability { + leaf site { + type boolean; + } + leaf node { + type boolean; + } + leaf srlg { + type boolean; + } + } + } +} diff --git a/ordmodels/src/main/yang/org-openroadm-topology.yang b/ordmodels/src/main/yang/org-openroadm-topology.yang new file mode 100644 index 000000000..93c965bd1 --- /dev/null +++ b/ordmodels/src/main/yang/org-openroadm-topology.yang @@ -0,0 +1,91 @@ +module org-openroadm-topology { + namespace "http://org/openroadm/topology"; + prefix org-openroadm-topology; + + import org-openroadm-resource { + prefix org-openroadm-resource; + } + + organization + "Open ROADM MSA"; + contact + "OpenROADM.org"; + description + "YANG definitions of topology. + + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2016-10-14 { + description + "Version 1.2"; + } + + grouping topology { + description + "Topology reports the individual hops along the service in the A to Z direction and Z to A directions. This includes both ports internal to a device and those + at its edge that are available for externally connections. It includes both physical and logical ports. + Physical ports are ordered with the logical ports that run over them as follows: + a.\tOn ingress to a node/card, physical then logical + b.\tOn egress to a node/card, logical then physical"; + list aToZ { + key "id"; + leaf id { + description + "Unigue identifier for this topology component within this service"; + type string; + } + uses hop; + } + list zToA { + key "id"; + leaf id { + description + "Unigue identifier for this topology component within this service"; + type string; + } + uses hop; + } + } + + grouping hop { + leaf hop-type { + type enumeration { + enum "node-external" { + description + "The given resource is on the edge of the node, and used in relationships to resources outside of the node."; + value 1; + } + enum "node-internal" { + description + "The given resource is internally to the node"; + value 2; + } + } + } + uses org-openroadm-resource:resource; + } +} diff --git a/ordmodels/src/main/yang/service_path_v1.5/transportpce-common-service-path-types.yang b/ordmodels/src/main/yang/service_path_v1.5/transportpce-common-service-path-types.yang new file mode 100644 index 000000000..1245f4bc7 --- /dev/null +++ b/ordmodels/src/main/yang/service_path_v1.5/transportpce-common-service-path-types.yang @@ -0,0 +1,217 @@ +module transportpce-common-service-path-types { + namespace "http://org/transportpce/B-C-interface/service/types"; + prefix transportpce-common-service-path-types; + + import ietf-yang-types { + prefix yang; + } + import ietf-inet-types { + prefix inet; + } + import transportpce-routing-constraints { + prefix transportpce-routing-constraints; + } + import transportpce-pathDescription { + prefix transportpce-pathDescription; + } + import org-openroadm-common-types { + prefix org-openroadm-common-types; + } + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + } + import org-openroadm-common-service-types { + prefix org-openroadm-common-service-types; + } + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of B & C interfaces (transportPCE). Adapted from service definition (openroadm). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + openroadm copyright: + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2017-04-26 { + description + "Version 1.5"; + } + typedef service-path-notification-types { + type enumeration { + enum "path-computation-request" { + value 1; + } + enum "cancel-resource-reserve" { + value 2; + } + enum "service-implementation-request" { + value 3; + } + enum "service-delete" { + value 4; + } + } + } + + typedef rpc-status-ex { + description + "extended status of RPC "; + type enumeration { + enum "Successful" { + value 1; + } + enum "Failed" { + value 2; + } + enum "Pending" { + value 3; + } + } + } + + grouping rpc-response-status-ex { + leaf status { + type rpc-status-ex; + mandatory true; + description + "Successful, Failed or Pending"; + + } + leaf status-message { + type string; + description + "Gives a more detailed reason for failure"; + } + } + + grouping response-parameters-sp { + container response-parameters { + uses transportpce-routing-constraints:routing-constraints-sp; + container path-description { + uses transportpce-pathDescription:path-description; + } + } + } + + grouping service-endpoint-sp { + leaf service-format { + type org-openroadm-common-service-types:service-format; + mandatory true; + description + "Format of the requested service: Ethernet, OTU, etc."; + } + leaf service-rate { + when "../service-format!='OMS'"{ + description "service rate not applicable when service + format is roadmline"; + } + type uint32; + mandatory true; + description + "Rate of the requested service in GBps"; + } + leaf clli { + type string; + mandatory true; + description + "CLLI"; + } + leaf node-id { + type string; + } + container tx-direction { + uses org-openroadm-common-service-types:service-port; + // uses service-lgx; + // uses service-tail; + } + container rx-direction { + uses org-openroadm-common-service-types:service-port; + // uses service-lgx; + // uses service-tail; + } + } + + grouping service-handler-header { + container service-handler-header { + leaf request-id { + type string; + mandatory true; + } + } + } + + grouping service-path { + leaf service-path-name { + type string; + description + "Identifier for the service-path to be calculated by + the PCE"; + mandatory true; + } + uses service-handler-header; + + container service-a-end { + uses service-endpoint-sp; + } + container service-z-end { + uses service-endpoint-sp; + } + uses transportpce-routing-constraints:routing-constraints-sp; + + leaf latency { + type uint32; + description + "Latency on service"; + } + leaf-list fiber-span-srlgs { + type string; + description + "Shared risk link group identifiers"; + } + list equipment-srgs { + key "srg-number"; + uses org-openroadm-resource-types:srg-number; + } + leaf-list supporting-service-name { + description + "The service name that this runs over top. If connection-type is service, then this is the related + connection-type = infrastructure service, for example."; + type string; + } + container path-description { + uses transportpce-pathDescription:path-description; + } + } + + + +} diff --git a/ordmodels/src/main/yang/service_path_v1.5/transportpce-pathDescription.yang b/ordmodels/src/main/yang/service_path_v1.5/transportpce-pathDescription.yang new file mode 100644 index 000000000..d9d4de0aa --- /dev/null +++ b/ordmodels/src/main/yang/service_path_v1.5/transportpce-pathDescription.yang @@ -0,0 +1,142 @@ +module transportpce-pathDescription { + namespace "http://org/transportpce/B-C-interface/pathDescription"; + prefix transportpce-pathDescription; + + import org-openroadm-resource { + prefix org-openroadm-resource; + } + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of B interface (transportPCE). Adapted from service definition (openroadm). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + + openroadm copyright: + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2017-04-26 { + description + "Version 1.5"; + } + + grouping PCE-resource { + description + "This resource identifier is intended to provide a generic identifer + for any resource that can be used without specific knowledge of + the resource."; + container resource { + choice resource { + case termination-point { + leaf tp-id { + type string; //to be clarified with topology model + } + leaf node-id { + type string; //to be clarified with topology model + } + } + + case link { + leaf link-id { + type string; //to be clarified with topology model + } + } + + case node { + leaf node-id { + type string; // to be clarified with topology model + } + } + } + } + } + + + grouping path-description { + description + "Topology reports the individual hops along the service in the A to Z direction and Z to A directions. This includes both ports internal to a device and those + at its edge that are available for externally connections. It includes both physical and logical ports. + Physical ports are ordered with the logical ports that run over them as follows: + a.\tOn ingress to a node/card, physical then logical + b.\tOn egress to a node/card, logical then physical"; + container aToZ-direction { + leaf aToZ-wavelength-number { + type uint32; + mandatory true; + } + leaf rate { + type uint32; + mandatory true; + } + leaf modulation-format { + type string; // enum ? + } + list aToZ { + key "id"; + leaf id { + description + "Unigue identifier for this topology component within this service"; + type string; + } + uses hop; + } + } + + container zToA-direction { + leaf zToA-wavelength-number { + type uint32; + mandatory true; + } + leaf rate { + type uint32; + mandatory true; + } + leaf modulation-format { + type string; // enum ? + } + list zToA { + key "id"; + leaf id { + description + "Unigue identifier for this topology component within this service"; + type string; + } + uses hop; + } + } + } + + + grouping hop { + uses PCE-resource; + } +} diff --git a/ordmodels/src/main/yang/service_path_v1.5/transportpce-routing-constraints.yang b/ordmodels/src/main/yang/service_path_v1.5/transportpce-routing-constraints.yang new file mode 100644 index 000000000..9caafdf5d --- /dev/null +++ b/ordmodels/src/main/yang/service_path_v1.5/transportpce-routing-constraints.yang @@ -0,0 +1,179 @@ +module transportpce-routing-constraints { + namespace "http://org/transportpce/B-C-interface/routing/constraints"; + prefix transportpce-routing-constraints; + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of B interface (transportPCE). Adapted from service definition (openroadm). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + openroadm copyright: + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2017-04-26 { + description + "Version 1.5"; + } + + grouping common-constraints-sp { + leaf-list SRLG { + type string; + } + leaf-list clli { + type string; + } + leaf-list node-id { + type string; + } + } + + grouping ordered-constraints-sp { + description + ""; + container hop-type { + choice hop-type { + case SRLG { + leaf SRLG { + type string; //to be clarified with topology model + } + } + + case clli { + leaf clli { + type string; //to be clarified with topology model + } + } + + case node { + leaf node-id { + type string; // to be clarified with topology model + } + } + } + } + } + + + grouping diversity-existing-service-contraints-sp { + leaf-list existing-service { + type string; + description + "Diverse from existing services identified by facility CLFI"; + } + container existing-service-applicability { + leaf clli { + type boolean; + } + leaf node { + type boolean; + } + leaf srlg { + type boolean; + } + } + } + + grouping routing-constraints-sp { + container hard-constraints { + uses constraints-sp; + } + container soft-constraints { + uses constraints-sp; + } + leaf pce-metric { + type enumeration { + enum hop-count; + enum propagation-delay; + enum TE-metric; + enum IGP-metric; + } + } + leaf locally-protected-links { + type boolean; + description "indicates whether it must use locally protected links or not"; + } + } + + grouping constraints-sp { + leaf-list customer-code { + type string; + } + choice co-routing-or-general { + case general { + container diversity { + uses diversity-existing-service-contraints-sp; + } + container exclude_ { + uses common-constraints-sp; + leaf-list supporting-service-name { + description + "Supporting service(s) to exclude from this route."; + type string; + } + leaf affinity { + type uint32; + } + } + container include_ { + list ordered-hops { + key hop-number; + leaf hop-number { + description + "designates the id of the hop: node-id, SRLG-id, site-id"; + type uint16; + } + uses ordered-constraints-sp; + } + + } + container latency { + description + "Maximum latency allowed"; + leaf max-latency { + type uint32; + units "ms"; + } + } + } + case co-routing { + container co-routing { + leaf-list existing-service { + type string; + description + "Diverse from existing services identified by facility CLFI"; + } + } + } + } + } + +} diff --git a/ordmodels/src/main/yang/service_path_v1.5/transportpce-service-path.yang b/ordmodels/src/main/yang/service_path_v1.5/transportpce-service-path.yang new file mode 100644 index 000000000..e38a1602a --- /dev/null +++ b/ordmodels/src/main/yang/service_path_v1.5/transportpce-service-path.yang @@ -0,0 +1,167 @@ +module transportpce-servicepath { + namespace "http://org/transportpce/B-C-interface"; + prefix transportpce-servicepath; + + import ietf-yang-types { + prefix yang; + } + import transportpce-routing-constraints { + prefix transportpce-routing-constraints; + } + import org-openroadm-common-types { + prefix org-openroadm-common-types; + } + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + } + import org-openroadm-common-service-types { + prefix org-openroadm-common-service-types; + } + import transportpce-common-service-path-types { + prefix transportpce-common-service-path-types; + } + import transportpce-pathDescription { + prefix transportpce-pathDescription; + } + import org-openroadm-topology { + prefix org-openroadm-topology; + } + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of B and C interfaces (transportPCE). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + @authors: Xavier POUGNARD ( xavier.pougnard AT orange DOT com ) + Olivier RENAIS ( oliver.renais AT orange DOT com )"; + + + revision 2017-04-26 { + description + "Version 1.5"; + } + + rpc path-computation-request { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + leaf resource-reserve { + type boolean; + description + "indicates if resources (from local PCE topology) must be reserved until further notice (cancel-resource-reserve or topology update)"; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + container service-a-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container service-z-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + uses transportpce-routing-constraints:routing-constraints-sp; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + uses transportpce-common-service-path-types:response-parameters-sp; + } + } + + rpc cancel-resource-reserve { + input { + leaf service-name { + type string; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + + + rpc service-implementation-request { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + container service-a-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container service-z-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container path-description { + uses transportpce-pathDescription:path-description; + } + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + rpc service-delete { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + container service-path-list { + description + "List of service paths. Can only be created, deleted, modified, etc. using special RPCs."; + list service-paths { + key "service-path-name"; + uses transportpce-common-service-path-types:service-path; + } + } +notification service-path-rpc-result { + description + "This Notification indicates result of service RPC"; + leaf notification-type { + type transportpce-common-service-path-types:service-path-notification-types; + } + container path-description { + uses transportpce-pathDescription:path-description; + } + uses transportpce-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-common-service-types:service-notification-result; + } +notification service-rpc-result-sp { + description + "This Notification indicates result of service RPC and provides the topology"; + leaf notification-type { + type transportpce-common-service-path-types:service-path-notification-types; + } + container path-topology { + uses org-openroadm-topology:topology; + } + uses transportpce-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-common-service-types:service-notification-result; + } + + + +} diff --git a/ordmodels/src/main/yang/servicehandler@2016-10-14.yang b/ordmodels/src/main/yang/servicehandler@2016-10-14.yang new file mode 100644 index 000000000..4a42ee37e --- /dev/null +++ b/ordmodels/src/main/yang/servicehandler@2016-10-14.yang @@ -0,0 +1,593 @@ +module servicehandler { + namespace "http://org/opendaylight/transportpce/servicehandler"; + prefix "org-opendaylight-transportpce-servicehandler"; + + import ietf-yang-types { + prefix yang; + } + import org-openroadm-routing-constraints { + prefix org-openroadm-routing-constraints; + revision-date 2016-10-14; + } + import org-openroadm-common-types { + prefix org-openroadm-common-types; + revision-date 2016-10-14; + } + + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + } + import org-openroadm-common-service-types { + prefix org-openroadm-common-service-types; + } + import transportpce-common-service-path-types { + prefix org-openroadm-common-service-path-types; + revision-date 2017-04-26; + } + + + organization + "Open ROADM MSA"; + contact + "OpenROADM.org"; + description + "YANG definitions of services. + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + revision 2016-10-14 { + description + "Version 1.2"; + } + + rpc service-create { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + leaf common-id { + type string; + description + "To be used by the ROADM controller to identify the routing constraints received from planning application (PED)."; + } + uses org-openroadm-common-service-types:sdnc-request-header; + leaf connection-type { + type org-openroadm-common-service-types:connection-type; + mandatory true; + } + container service-a-end { + uses org-openroadm-common-service-types:service-endpoint; + } + container service-z-end { + uses org-openroadm-common-service-types:service-endpoint; + } + uses org-openroadm-routing-constraints:routing-constraints; + uses org-openroadm-common-service-types:service-information; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + uses org-openroadm-common-service-types:response-parameters; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent."; + } + + rpc service-feasibility-check { + input { + leaf common-id { + type string; + mandatory true; + description + "To be used by the ROADM controller to identify the routing + constraints received from planning application (PED)."; + } + uses org-openroadm-common-service-types:sdnc-request-header; + leaf connection-type { + type org-openroadm-common-service-types:connection-type; + } + container service-a-end { + uses org-openroadm-common-service-types:service-endpoint; + } + container service-z-end { + uses org-openroadm-common-service-types:service-endpoint; + } + uses org-openroadm-routing-constraints:routing-constraints; + uses org-openroadm-common-service-types:service-information; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + uses org-openroadm-common-service-types:response-parameters; + container service-a-end { + uses org-openroadm-common-service-types:service-endpoint; + list equipment-required { + description + "List of required equipment, including equipment type and quantity"; + key "eqipment-identifier"; + leaf eqipment-identifier { + type string; + } + leaf equipment-type { + type string; + } + leaf equipment-quantity { + type uint32; + } + } + } + container service-z-end { + uses org-openroadm-common-service-types:service-endpoint; + list equipment-required { + description + "List of required equipment, including equipment type and quantity"; + key "eqipment-identifier"; + leaf eqipment-identifier { + type string; + } + leaf equipment-type { + type string; + } + leaf equipment-quantity { + type uint32; + } + } + } + list intermediate-sites { + key "clli"; + uses org-openroadm-common-service-types:service-endpoint; + list equipment-required { + description + "List of required equipment, including equipment type and quantity"; + key "eqipment-identifier"; + leaf eqipment-identifier { + type string; + } + leaf equipment-type { + type string; + } + leaf equipment-quantity { + type uint32; + } + } + } + } + description + "Whether a service was possible to be created, and if so + the routing constraints match and the a and z end connection that have + to match"; + } + + rpc service-delete { + input { + uses org-openroadm-common-service-types:sdnc-request-header; + container service-delete-req-info { + leaf service-name { + type string; + description + "Identifier for the service to be deleted in + the ROADM network, e.g., CLFI, CLCI, etc."; + mandatory true; + } + leaf due-date { + type yang:date-and-time; + description + "date and time service to be turned down. If missing, now."; + } + leaf tail-retention { + type enumeration { + enum "yes" { + value 1; + description + "tails are left intact "; + } + enum "no" { + value 2; + description + "tails are deleted"; + } + } + mandatory true; + } + } + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent. Once the service has been deleted, it no longer will appear in the service list"; + } + + rpc equipment-notification { + input { + uses org-openroadm-common-service-types:sdnc-request-header; + leaf equiptment-id { + type string; + mandatory true; + } + leaf equipment-name { + type string; + } + leaf equipemt-type { + type string; + mandatory true; + } + leaf equipment-vendor { + type string; + mandatory true; + } + leaf equipment-customer { + type string; + } + leaf equipment-clli { + type string; + mandatory true; + } + leaf equipment-ip { + type string; + } + leaf controller-id { + type string; + mandatory true; + } + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + rpc temp-service-create { + input { + leaf common-id { + type string; + description + "To be used by the ROADM controller to identify the routing constraints received from planning application (PED)."; + mandatory true; + } + uses org-openroadm-common-service-types:sdnc-request-header; + leaf connection-type { + type org-openroadm-common-service-types:connection-type; + mandatory true; + } + container service-a-end { + uses org-openroadm-common-service-types:service-endpoint; + } + container service-z-end { + uses org-openroadm-common-service-types:service-endpoint; + } + uses org-openroadm-routing-constraints:routing-constraints; + uses org-openroadm-common-service-types:service-information; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + uses org-openroadm-common-service-types:response-parameters; + } + } + + rpc temp-service-delete { + input { + leaf common-id { + type string; + mandatory true; + } + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + rpc service-roll { + input { + leaf service-name { + type string; + mandatory true; + description + "Identifier for the service to be rolled in + the ROADM network, e.g., CLFI, CLCI, etc."; + } + leaf due-date { + type yang:date-and-time; + description + "date and time service to be rolled"; + } + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + } + } + + rpc service-reconfigure { + input { + leaf service-name { + type string; + mandatory true; + description + "Existing identifier for the service to be + reconfigured in the ROADM network, e.g., CLFI, CLCI, etc."; + } + leaf new-service-name { + type string; + description + "New identifier for the service to be + reconfigured in the ROADM network, e.g., CLFI, CLCI, etc."; + } + leaf common-id { + type string; + description + "To be used by the ROADM controller to identify the routing + constraints received from planning application (PED)."; + } + /**Add by Martial **/ + leaf notification-url { + type string; + } + leaf connection-type { + type org-openroadm-common-service-types:connection-type; + } + container service-a-end { + uses org-openroadm-common-service-types:service-endpoint; + } + container service-z-end { + uses org-openroadm-common-service-types:service-endpoint; + } + uses org-openroadm-routing-constraints:routing-constraints; + uses org-openroadm-common-service-types:service-information; + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent."; + } + + rpc service-restoration { + input { + leaf service-name { + type string; + mandatory true; + description + "Identifier for the service to be restored in + the ROADM network, e.g., CLFI, CLCI, etc."; + } + /**Add by Martial **/ + leaf notification-url { + type string; + } + leaf option { + type enumeration { + enum "permanent" { + value 1; + description + "A spare regen can be used to restore the + service permanently without reverting back to the + original regen"; + } + enum "temporary" { + value 2; + description + "a spare regen can be used to restore the + service temporarily. The service needs to be reverted + back to the original regen transponder"; + } + } + mandatory true; + } + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent."; + } + + rpc service-reversion { + input { + leaf service-name { + type string; + mandatory true; + description + "Identifier for the service to be reverted + in the ROADM network, e.g., CLFI, CLCI, etc. "; + } + leaf due-date { + type yang:date-and-time; + description + "date and time service to be reverted"; + } + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent."; + } + + rpc service-reroute { + input { + leaf service-name { + type string; + mandatory true; + description + "Identifier for the service to be re-routed in + the ROADM network, e.g., CLFI, CLCI, etc."; + } + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-routing-constraints:routing-constraints; + } + description + "Whether this request was validated and processed correct. If sucessful, it return the proposed new route. + If acceptable, this request should be followed by a service-reroute-confirm to complete the reroute operation."; + } + + rpc service-reroute-confirm { + input { + leaf service-name { + type string; + mandatory true; + description + "Identifier for the service to be re-routed in + the ROADM network, e.g., CLFI, CLCI, etc."; + } + uses org-openroadm-routing-constraints:routing-constraints; + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + } + description + "Whether this request passed initial validation and was accepted for processing. Once the request completes processing, a + service-rpc-result Notification shall be sent."; + } + + rpc network-re-optimization { + input { + leaf service-name { + type string; + description + "Identifier for the service in the ROADM network, + e.g., CLFI, CLCI, etc. whose path is to be checked by the RNC + for re-optimization"; + } + leaf a-end { + type string; + description + "Services whose A-ends are terminated at the + specified office location are to be checked by the RNC for + re-optimization"; + } + leaf z-end { + type string; + description + "Services whose Z-ends are terminated at the + specified office location are to be checked by the RNC for + re-optimization "; + } + leaf pass-through { + type string; + description + "Services that are pass-through (either via + regen or express) at the specified office location are to + be checked by the RNC for re-optimization"; + } + leaf customer-code { + type string; + description + "Services that belong to the specified customer + are to be checked by the RNC for re-optimization "; + } + } + output { + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + leaf optimization-candidate { + type string; + } + } + } + + container service-list { + description + "List of service. Can only be created, deleted, modified, etc. using special RPCs."; + list services { + key "service-name"; + uses org-openroadm-common-service-types:service; + } + } + + container temp-service-list { + description + "List of temporary services Can only be created, deleted, modified, etc. using special RPCs."; + list services { + key "common-id"; + uses org-openroadm-common-service-types:service { + refine "service-name" { + mandatory false; + } + } + } + } + + notification service-rpc-result { + description + "This Notification indicates result of service RPC"; + leaf notification-type { + type org-openroadm-common-service-types:service-notification-types; + } + //uses org-openroadm-common-types:rpc-response-status; + uses org-openroadm-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-common-service-types:service-notification-result; + } + + notification service-traffic-flow { + description + "This Notification indicates that traffic is flowing again on the service after an administrative action has completed"; + leaf service-name { + type string; + description + "Identifier for the service being reported on"; + mandatory true; + } + leaf actual-date { + type yang:date-and-time; + description + "Actual date and time traffic started flowing"; + } + } + + notification service-notification { + description + "This Notification that a service has been added, modified or removed. + A resourceCreation notification shall contain the created service in its entirety. + A resourceMofified notification shall contain just the modified field, plus the service identifier + A resourceDeleted notification shall just contain the service identifier"; + leaf notificationType { + type org-openroadm-resource-types:resource-notification-type; + description + "Whether this notification indicates a service creation, service modification or service deletion."; + } + uses org-openroadm-common-service-types:service; + } + +} diff --git a/ordmodels/src/main/yang/stubpce.yang b/ordmodels/src/main/yang/stubpce.yang new file mode 100644 index 000000000..44ba5ca08 --- /dev/null +++ b/ordmodels/src/main/yang/stubpce.yang @@ -0,0 +1,135 @@ +module stubpce { + yang-version 1; + namespace "http://org/opendaylight/transportpce/stubpce"; + prefix "org-opendaylight-transportpce-stubpce"; + + + import ietf-yang-types { + prefix yang; + revision-date 2013-07-15; + } + import transportpce-routing-constraints { + prefix transportpce-routing-constraints; + revision-date 2017-04-26; + } + + + import org-openroadm-common-service-types { + prefix org-openroadm-common-service-types; + revision-date 2016-10-14; + } + + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + revision-date 2016-10-14; + } + import transportpce-common-service-path-types { + prefix transportpce-common-service-path-types; + revision-date 2017-04-26; + } + import transportpce-pathDescription { + prefix transportpce-pathDescription; + revision-date 2017-04-26; + } + + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of stubrenderer services (transportPCE). Adapted from service path definition (openroadm). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + + openroadm copyright: + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + + revision 2017-04-26 { + description + "Version 1.5"; + } + + rpc path-computation-request { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + leaf resource-reserve { + type boolean; + description + "indicates if resources (from local PCE topology) must be reserved until further notice (cancel-resource-reserve or topology update)"; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + container service-a-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container service-z-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + uses transportpce-routing-constraints:routing-constraints-sp; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + uses transportpce-common-service-path-types:response-parameters-sp; + } + } + + rpc cancel-resource-reserve { + input { + leaf service-name { + type string; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + notification service-path-rpc-result { + description + "This Notification indicates result of service RPC"; + leaf notification-type { + type transportpce-common-service-path-types:service-path-notification-types; + } + container path-description { + uses transportpce-pathDescription:path-description; + } + uses transportpce-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-common-service-types:service-notification-result; + } +} diff --git a/ordmodels/src/main/yang/stubrenderer.yang b/ordmodels/src/main/yang/stubrenderer.yang new file mode 100644 index 000000000..c1ded4598 --- /dev/null +++ b/ordmodels/src/main/yang/stubrenderer.yang @@ -0,0 +1,138 @@ +module stubrenderer { + yang-version 1; + namespace "http://org/opendaylight/transportpce/stubrenderer"; + prefix "org-opendaylight-transportpce-stubrenderer"; + + import ietf-yang-types { + prefix yang; + revision-date 2013-07-15; + } + import transportpce-routing-constraints { + prefix transportpce-routing-constraints; + revision-date 2017-04-26; + } + + + import org-openroadm-common-service-types { + prefix org-openroadm-common-service-types; + revision-date 2016-10-14; + } + + import org-openroadm-resource-types { + prefix org-openroadm-resource-types; + revision-date 2016-10-14; + } + import transportpce-common-service-path-types { + prefix transportpce-common-service-path-types; + revision-date 2017-04-26; + } + import transportpce-pathDescription { + prefix transportpce-pathDescription; + revision-date 2017-04-26; + } + + import org-openroadm-topology { + prefix org-openroadm-topology; + revision-date 2016-10-14; + } + + + organization + "transportPCE"; + contact + "transportPCE committers - ODL"; + description + "YANG definitions of stubrenderer services (transportPCE). Adapted from service path definition (openroadm). + Copyright © 2017 Orange, Inc. and others. All rights reserved. + + This model is derived from the OpenROADM service definition that includes the following notice: + + + openroadm copyright: + Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, + AT&T Intellectual Property. All other rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + * Neither the Members of the Open ROADM MSA Agreement nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT ''AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA AGREEMENT BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE"; + + + revision 2017-04-26 { + description + "Version 1.5"; + } + + rpc service-implementation-request { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + container service-a-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container service-z-end { + uses transportpce-common-service-path-types:service-endpoint-sp; + } + container path-description { + uses transportpce-pathDescription:path-description; + } + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + rpc service-delete { + input { + leaf service-name { + type string; + description + "Identifier for the service to be created in + the ROADM network, e.g., CLFI, CLCI, etc. This is reported against the service, but may not get reflected in the service in the network."; + mandatory true; + } + uses transportpce-common-service-path-types:service-handler-header; + } + output { + uses org-openroadm-common-service-types:configuration-response-common; + } + } + + + notification service-rpc-result-sp { + description + "This Notification indicates result of service RPC"; + leaf notification-type { + type transportpce-common-service-path-types:service-path-notification-types; + } + container path-topology { + uses org-openroadm-topology:topology; + } + uses transportpce-common-service-path-types:rpc-response-status-ex; + uses org-openroadm-common-service-types:service-notification-result; + } +} diff --git a/pom.xml b/pom.xml index 5aeccea7d..44c1a42a8 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL impl renderer olm + stubrenderer + stubpce + servicehandler karaf features artifacts diff --git a/servicehandler/pom.xml b/servicehandler/pom.xml new file mode 100644 index 000000000..df7d10f6b --- /dev/null +++ b/servicehandler/pom.xml @@ -0,0 +1,57 @@ + + + + + 4.0.0 + + + org.opendaylight.controller + config-parent + 0.6.0-SNAPSHOT + + + + org.opendaylight.transportpce + transportpce-servicehandler + 0.1.0-SNAPSHOT + bundle + + + + ${project.groupId} + transportpce-api + ${project.version} + + + ${project.groupId} + transportpce-ordmodels + ${project.version} + + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + + com.google.code.gson + gson + + + diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/CheckCoherencyHardSoft.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/CheckCoherencyHardSoft.java new file mode 100644 index 000000000..3ddf0e6eb --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/CheckCoherencyHardSoft.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.routing.constraints.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.routing.constraints.SoftConstraints; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* Class to check coherency between hard & sof constraints. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class CheckCoherencyHardSoft { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(CheckCoherencyHardSoft.class); + /* Hard Constraints. */ + private HardConstraints hard; + /* Soft Constraints. */ + private SoftConstraints soft; + + public CheckCoherencyHardSoft(HardConstraints hard, SoftConstraints soft) { + this.hard = hard; + this.soft = soft; + } + + /*function to check coherency between hard & soft constraints. + * @return true if coherent + * false else + */ + public boolean check() { + boolean result = false; + if (hard != null && soft != null) { + /* + * Check coherency with hard/soft constraints + * hard/soft include/exclude coherency + * + */ + } else { + LOG.info("HardConstraints or/and SoftConstraints is null !"); + result = true; + } + return result; + } + +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/LoggingFuturesCallBack.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/LoggingFuturesCallBack.java new file mode 100644 index 000000000..1747b4adb --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/LoggingFuturesCallBack.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import com.google.common.util.concurrent.FutureCallback; +import org.slf4j.Logger; + +/* + * Class to log future logging from datastore actions (write & modify & delete..). + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + */ + +public class LoggingFuturesCallBack implements FutureCallback { + + private Logger log; + private String message; + + public LoggingFuturesCallBack(String message, Logger log) { + this.message = message; + this.log = log; + } + + @Override + public void onFailure(Throwable ex) { + log.warn(message, ex); + + } + + @Override + public void onSuccess(V arg0) { + log.info("Success! {} ", arg0); + + } + +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingPCRequest.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingPCRequest.java new file mode 100644 index 000000000..df9192211 --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingPCRequest.java @@ -0,0 +1,325 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceCreateInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceFeasibilityCheckInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReconfigureInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.list.Services; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header.SdncRequestHeader; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header.SdncRequestHeaderBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.RoutingConstraintsSp.PceMetric; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeaderBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * class for Mapping and Sending PCE requests : - path-computation-request - + * cancel-resource-reserve. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class MappingAndSendingPCRequest { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(MappingAndSendingPCRequest.class); + /* Permit to call PCE RPCs. */ + private StubpceService service; + /* define procedure success (or not ). */ + private Boolean success; + /* permit to call bundle service (PCE, Renderer, Servicehandler. */ + private RpcProviderRegistry rpcRegistry; + PathComputationRequestInput pathComputationRequestInput = null; + CancelResourceReserveInput cancelResourceReserveInput = null; + HardConstraints hard = null; + SoftConstraints soft = null; + /* store all error messages. */ + private String error; + private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + + /* + * MappingAndSendingPCRequest Class constructor for RPC serviceReconfigure. + * + * @param rpcRegistry + * RpcProviderRegistry + * @param serviceReconfigureInput + * serviceReconfigureInput + * @param resvResource + * Boolean to define resource reserve + */ + public MappingAndSendingPCRequest(RpcProviderRegistry rpcRegistry, ServiceReconfigureInput serviceReconfigureInput, + Boolean resvResource) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubpceService.class); + } + SdncRequestHeader head = new SdncRequestHeaderBuilder().build(); + MappingConstraints map = new MappingConstraints(serviceReconfigureInput.getHardConstraints(), + serviceReconfigureInput.getSoftConstraints()); + map.serviceToServicePathConstarints(); + /* + * mappingPCRequest(serviceReconfigureInput.getNewServiceName(), + * serviceReconfigureInput.getHardConstraints(), + * serviceReconfigureInput.getSoftConstraints(),head ,resvResource); + */ + mappingPCRequest(serviceReconfigureInput.getNewServiceName(), map.getServicePathHardConstraints(), + map.getServicePathSoftConstraints(), head, resvResource); + setSuccess(false); + setError(""); + } + + /* + * MappingAndSendingPCRequest Class constructor for RPC + * serviceFeasibilityCheck. + * + * @param rpcRegistry + * RpcProviderRegistry + * @param serviceFeasibilityCheckInput + * ServiceFeasibilityCheckInput + * @param resvResource + * Boolean to reserve resource + */ + public MappingAndSendingPCRequest(RpcProviderRegistry rpcRegistry, + ServiceFeasibilityCheckInput serviceFeasibilityCheckInput, Boolean resvResource) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubpceService.class); + } + MappingConstraints map = new MappingConstraints(serviceFeasibilityCheckInput.getHardConstraints(), + serviceFeasibilityCheckInput.getSoftConstraints()); + map.serviceToServicePathConstarints(); + mappingPCRequest("no name", map.getServicePathHardConstraints(), map.getServicePathSoftConstraints(), + serviceFeasibilityCheckInput.getSdncRequestHeader(), resvResource); + setSuccess(false); + setError(""); + } + + /* + * MappingAndSendingPCRequest Class constructor for RPC serviceCreate. + * + * @param rpcRegistry + * RpcProviderRegistry + * @param serviceCreateInput + * ServiceCreateInput + * @param resvResource + * Boolean to reserve resource + */ + public MappingAndSendingPCRequest(RpcProviderRegistry rpcRegistry, ServiceCreateInput serviceCreateInput, + Boolean resvResource) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubpceService.class); + } + MappingConstraints map = new MappingConstraints(serviceCreateInput.getHardConstraints(), + serviceCreateInput.getSoftConstraints()); + map.serviceToServicePathConstarints(); + mappingPCRequest(serviceCreateInput.getServiceName(), map.getServicePathHardConstraints(), + map.getServicePathSoftConstraints(), serviceCreateInput.getSdncRequestHeader(), resvResource); + setSuccess(false); + setError(""); + } + + /* + * MappingAndSendingPCRequest Class constructor for modify Service in ODL + * Datastore. + * + * @param rpcRegistry + * RpcProviderRegistry + * @param input + * Services + * @param resvResource + * Boolean to reserve resource + */ + public MappingAndSendingPCRequest(RpcProviderRegistry rpcRegistry, Services input, Boolean resvResource) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubpceService.class); + } + MappingConstraints map = new MappingConstraints(input.getHardConstraints(), input.getSoftConstraints()); + map.serviceToServicePathConstarints(); + mappingPCRequest(input.getServiceName(), map.getServicePathHardConstraints(), + map.getServicePathSoftConstraints(), input.getSdncRequestHeader(), resvResource); + setSuccess(false); + setError(""); + } + + /* + * Build pathComputationRequestInput or cancelResourceReserveInput with + * input parameters (serviceReconfigureInput or serviceFeasibilityCheckInput. + * + * @param String + * serviceName + * @param HardConstraints + * hardConstraints + * @param SoftConstraints + * softConstraints + * @param SdncRequestHeader + * sdncRequestHeader + * @param Boolean + * resvResource + */ + private void mappingPCRequest(String serviceName, HardConstraints hardConstraints, SoftConstraints softConstraints, + org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header + .SdncRequestHeader sdncRequestHeader, Boolean resvResource) { + + LOG.info("Mapping ServiceCreateInput or ServiceFeasibilityCheckInput or serviceReconfigureInput " + + "to PCE requests"); + + HardConstraints serviceCreateHard = hardConstraints; + SoftConstraints serviceCreateSoft = softConstraints; + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing + .constraints.sp.HardConstraints pceHardConstraints = null; + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing + .constraints.sp.SoftConstraints pceSoftConstraints = null; + if (serviceCreateHard != null) { + pceHardConstraints = serviceCreateHard; + } + if (serviceCreateSoft != null) { + pceSoftConstraints = serviceCreateSoft; + } + + ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder(); + if (sdncRequestHeader != null) { + serviceHandlerHeader.setRequestId(sdncRequestHeader.getRequestId()); + } + + /* PathComputationRequestInput build */ + pathComputationRequestInput = new PathComputationRequestInputBuilder().setServiceName(serviceName) + .setResourceReserve(resvResource).setServiceHandlerHeader(serviceHandlerHeader.build()) + .setHardConstraints(pceHardConstraints).setSoftConstraints(pceSoftConstraints) + .setPceMetric(PceMetric.TEMetric).build(); + + /* CancelResourceReserveInput build */ + cancelResourceReserveInput = new CancelResourceReserveInputBuilder().setServiceName(serviceName) + .setServiceHandlerHeader(serviceHandlerHeader.build()).build(); + } + + /* Send cancelResourceReserve request to PCE. + * + * @return CancelResourceReserveOutput data response from PCE + */ + public ListenableFuture cancelResourceReserve() { + setSuccess(false); + return executor.submit(new Callable() { + + @Override + public CancelResourceReserveOutput call() throws Exception { + CancelResourceReserveOutput output = null; + if (cancelResourceReserveInput != null) { + + RpcResult pceOutputResult = null; + Future> pceOutputFuture = service + .cancelResourceReserve(cancelResourceReserveInput); + + try { + pceOutputResult = pceOutputFuture.get(); + } catch (InterruptedException | CancellationException | ExecutionException e) { + setError("Did not receive the expected response from pce to cancelResourceReserve RPC " + + e.toString()); + LOG.error(error); + pceOutputFuture.cancel(true); + } + + if (pceOutputResult != null && pceOutputResult.isSuccessful()) { + LOG.info("PCE replied to CancelResource request !"); + CancelResourceReserveOutput pceOutput = pceOutputResult.getResult(); + output = new CancelResourceReserveOutputBuilder() + .setConfigurationResponseCommon(pceOutput.getConfigurationResponseCommon()).build(); + setSuccess(true); + } + } else { + LOG.info("cancelResourceReserveInput parameter not valid !"); + } + return output; + } + }); + + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + /*Send pathComputationRequest request to PCE. + * + * @return PathComputationRequestOutput data response from PCE + */ + public ListenableFuture pathComputationRequest() { + LOG.info("In pathComputationRequest ..."); + setSuccess(false); + return executor.submit(new Callable() { + @Override + public PathComputationRequestOutput call() throws Exception { + RpcResult pceOutputResult = null; + PathComputationRequestOutput output = null; + if (pathComputationRequestInput != null) { + Future> pceOutputFuture = service + .pathComputationRequest(pathComputationRequestInput); + try { + pceOutputResult = pceOutputFuture.get();// wait to get + // the result + } catch (InterruptedException | CancellationException | ExecutionException e) { + setError("Did not receive the expected response from pce to pathComputationRequest RPC " + + e.toString()); + LOG.error(error); + pceOutputFuture.cancel(true); + } + + if (pceOutputResult != null && pceOutputResult.isSuccessful()) { + setSuccess(true); + LOG.info("PCE replied to pathComputation request !"); + PathComputationRequestOutput pceOutput = pceOutputResult.getResult(); + output = new PathComputationRequestOutputBuilder() + .setConfigurationResponseCommon(pceOutput.getConfigurationResponseCommon()) + .setResponseParameters(pceOutput.getResponseParameters()).build(); + } + } else { + LOG.info("pathComputationRequestInput parameter not valid !"); + } + return output; + } + }); + + } +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingSIRequest.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingSIRequest.java new file mode 100644 index 000000000..18531c251 --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingAndSendingSIRequest.java @@ -0,0 +1,701 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceCreateInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReconfigureInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.list.Services; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestInputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.PathDescription; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.PathDescriptionBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.ServiceAEnd; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.ServiceAEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.ServiceZEnd; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.implementation.request.input.ServiceZEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceFormat; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.Port; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.PortBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.RxDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.RxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.TxDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.TxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeaderBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + + +/* + * Class for Mapping and Sending + * Service Implemention requests : + * - service implementation + * - service delete. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class MappingAndSendingSIRequest { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(MappingAndSendingSIRequest.class); + /* Permit to call Renderer RPCs. */ + private StubrendererService service; + /* define procedure success (or not ). */ + private Boolean success = false; + /* permit to call bundle service (PCE, Renderer, Servicehandler. */ + private RpcProviderRegistry rpcRegistry; + /* store all error messages. */ + private String error; + ServiceImplementationRequestInput serviceImplementationRequestInput = null; + ServiceDeleteInput serviceDeleteInput = null; + + private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + + + /* + * MappingAndSendingSIRequest class constructor + * for RPC serviceCreate. + * + * @param rpcRegistry rpcRegistry + * @param serviceCreateInput serviceCreateInput + * @param pathComputationOutput pathComputationOutput + */ + public MappingAndSendingSIRequest(RpcProviderRegistry rpcRegistry, + ServiceCreateInput serviceCreateInput,PathComputationRequestOutput pathComputationOutput) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubrendererService.class); + } + setSuccess(false); + setError(""); + + /* Building ServiceImplementationRequestInput / ServiceDeleteInput serviceDeleteInput. */ + ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder(); + if (serviceCreateInput.getSdncRequestHeader() != null) { + serviceHandlerHeader.setRequestId(serviceCreateInput.getSdncRequestHeader().getRequestId()); + } + //.build(); + + /*ServiceAEnd Build */ + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014 + .service.create.input.ServiceAEnd tempA = serviceCreateInput.getServiceAEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortRx = + serviceCreateInput.getServiceAEnd().getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortTx = + serviceCreateInput.getServiceAEnd().getTxDirection().getPort(); + + /*Port portARx = new PortBuilder() + .setPortDeviceName(tempAPortRx.getPortDeviceName()) + .setPortName(tempAPortRx.getPortName()) + .setPortRack(tempAPortRx.getPortRack()) + .setPortShelf(tempAPortRx.getPortShelf()) + .setPortSlot(tempAPortRx.getPortSlot()) + .setPortSubSlot(tempAPortRx.getPortSubSlot()) + .setPortType(tempAPortRx.getPortType()) + .build(); + + Port portATx = new PortBuilder() + .setPortDeviceName(tempAPortTx.getPortDeviceName()) + .setPortName(tempAPortTx.getPortName()) + .setPortRack(tempAPortTx.getPortRack()) + .setPortShelf(tempAPortTx.getPortShelf()) + .setPortSlot(tempAPortTx.getPortSlot()) + .setPortSubSlot(tempAPortTx.getPortSubSlot()) + .setPortType(tempAPortTx.getPortType()) + .build(); + + RxDirection rxDirectionAEnd = new RxDirectionBuilder() + .setPort(portARx ) + .build(); + + TxDirection txDirectionAEnd = new TxDirectionBuilder() + .setPort(portATx ) + .build();*/ + + RxDirection rxDirectionAEnd = getRxDirection(tempAPortRx); + + TxDirection txDirectionAEnd = getTxDirection(tempAPortTx); + + ServiceAEnd serviceAEnd = new ServiceAEndBuilder() + .setClli(tempA.getClli()) + .setNodeId(tempA.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempA.getServiceFormat().getName())) + .setServiceRate(tempA.getServiceRate()) + .setRxDirection(rxDirectionAEnd) + .setTxDirection(txDirectionAEnd) + .build(); + + /* ServiceZEnd Build */ + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014 + .service.create.input.ServiceZEnd tempZ = serviceCreateInput.getServiceZEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortRx = + serviceCreateInput.getServiceZEnd().getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortTx = + serviceCreateInput.getServiceZEnd().getTxDirection().getPort(); + + /*Port portZRx = new PortBuilder() + .setPortDeviceName(tempZPortRx.getPortDeviceName()) + .setPortName(tempZPortRx.getPortName()) + .setPortRack(tempZPortRx.getPortRack()) + .setPortShelf(tempZPortRx.getPortShelf()) + .setPortSlot(tempZPortRx.getPortSlot()) + .setPortSubSlot(tempZPortRx.getPortSubSlot()) + .setPortType(tempZPortRx.getPortType()) + .build(); + + Port portZTx = new PortBuilder() + .setPortDeviceName(tempZPortTx.getPortDeviceName()) + .setPortName(tempZPortTx.getPortName()) + .setPortRack(tempZPortTx.getPortRack()) + .setPortShelf(tempZPortTx.getPortShelf()) + .setPortSlot(tempZPortTx.getPortSlot()) + .setPortSubSlot(tempZPortTx.getPortSubSlot()) + .setPortType(tempZPortTx.getPortType()) + .build(); + + RxDirection rxDirectionZEnd = new RxDirectionBuilder() + .setPort(portZRx ) + .build(); + + TxDirection txDirectionZEnd = new TxDirectionBuilder() + .setPort(portZTx ) + .build();*/ + + RxDirection rxDirectionZEnd = getRxDirection(tempZPortRx); + + TxDirection txDirectionZEnd = getTxDirection(tempZPortTx); + + ServiceZEnd serviceZEnd = new ServiceZEndBuilder() + .setClli(tempZ.getClli()) + .setNodeId(tempZ.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempZ.getServiceFormat().getName())) + .setServiceRate(tempZ.getServiceRate()) + .setRxDirection(rxDirectionZEnd) + .setTxDirection(txDirectionZEnd) + .build(); + + + /* ServiceImplementationRequestInput Build*/ + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types + .rev170426.response.parameters.sp.response.parameters.PathDescription tmp = null; + try { + tmp = pathComputationOutput.getResponseParameters().getPathDescription(); + } catch (NullPointerException e) { + LOG.error("PathDescription is null : " + e.toString()); + } + PathDescriptionBuilder pathDescription = new PathDescriptionBuilder(); + if (tmp != null) { + pathDescription = new PathDescriptionBuilder(tmp); + } + serviceImplementationRequestInput = new ServiceImplementationRequestInputBuilder() + .setPathDescription(pathDescription.build()) + .setServiceHandlerHeader(serviceHandlerHeader.build()) + .setServiceName(serviceCreateInput.getServiceName()) + .setServiceAEnd(serviceAEnd) + .setServiceZEnd(serviceZEnd) + .build(); + } + + /* + * MappingAndSendingSIRequest class constructor + * for RPC serviceReconfigure. + * + * @param rpcRegistry rpcRegistry + * @param serviceReconfigureInput serviceReconfigureInput + * @param pathComputationOutput pathComputationOutput + */ + + public MappingAndSendingSIRequest(RpcProviderRegistry rpcRegistry, + ServiceReconfigureInput serviceReconfigureInput,PathComputationRequestOutput pathComputationOutput) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubrendererService.class); + } + setSuccess(false); + setError(""); + + /* Building ServiceImplementationRequestInput / ServiceDeleteInput serviceDeleteInput .*/ + ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder(); + + /*ServiceAEnd Build .*/ + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014 + .service.reconfigure.input.ServiceAEnd tempA = serviceReconfigureInput.getServiceAEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortRx = + serviceReconfigureInput.getServiceAEnd().getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortTx = + serviceReconfigureInput.getServiceAEnd().getTxDirection().getPort(); + + /*Port portARx = new PortBuilder() + .setPortDeviceName(tempAPortRx.getPortDeviceName()) + .setPortName(tempAPortRx.getPortName()) + .setPortRack(tempAPortRx.getPortRack()) + .setPortShelf(tempAPortRx.getPortShelf()) + .setPortSlot(tempAPortRx.getPortSlot()) + .setPortSubSlot(tempAPortRx.getPortSubSlot()) + .setPortType(tempAPortRx.getPortType()) + .build(); + + Port portATx = new PortBuilder() + .setPortDeviceName(tempAPortTx.getPortDeviceName()) + .setPortName(tempAPortTx.getPortName()) + .setPortRack(tempAPortTx.getPortRack()) + .setPortShelf(tempAPortTx.getPortShelf()) + .setPortSlot(tempAPortTx.getPortSlot()) + .setPortSubSlot(tempAPortTx.getPortSubSlot()) + .setPortType(tempAPortTx.getPortType()) + .build(); + + RxDirection rxDirectionAEnd = new RxDirectionBuilder() + .setPort(portARx ) + .build(); + + TxDirection txDirectionAEnd = new TxDirectionBuilder() + .setPort(portATx ) + .build();*/ + + RxDirection rxDirectionAEnd = getRxDirection(tempAPortRx); + + TxDirection txDirectionAEnd = getTxDirection(tempAPortTx); + + ServiceAEnd serviceAEnd = new ServiceAEndBuilder() + .setClli(tempA.getClli()) + .setNodeId(tempA.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempA.getServiceFormat().getName())) + .setServiceRate(tempA.getServiceRate()) + .setRxDirection(rxDirectionAEnd) + .setTxDirection(txDirectionAEnd) + .build(); + + /* ServiceZEnd Build .*/ + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014 + .service.reconfigure.input.ServiceZEnd tempZ = serviceReconfigureInput.getServiceZEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortRx = + serviceReconfigureInput.getServiceZEnd().getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortTx = + serviceReconfigureInput.getServiceZEnd().getTxDirection().getPort(); + + /*Port portZRx = new PortBuilder() + .setPortDeviceName(tempZPortRx.getPortDeviceName()) + .setPortName(tempZPortRx.getPortName()) + .setPortRack(tempZPortRx.getPortRack()) + .setPortShelf(tempZPortRx.getPortShelf()) + .setPortSlot(tempZPortRx.getPortSlot()) + .setPortSubSlot(tempZPortRx.getPortSubSlot()) + .setPortType(tempZPortRx.getPortType()) + .build(); + + Port portZTx = new PortBuilder() + .setPortDeviceName(tempZPortTx.getPortDeviceName()) + .setPortName(tempZPortTx.getPortName()) + .setPortRack(tempZPortTx.getPortRack()) + .setPortShelf(tempZPortTx.getPortShelf()) + .setPortSlot(tempZPortTx.getPortSlot()) + .setPortSubSlot(tempZPortTx.getPortSubSlot()) + .setPortType(tempZPortTx.getPortType()) + .build(); + + RxDirection rxDirectionZEnd = new RxDirectionBuilder() + .setPort(portZRx ) + .build(); + + TxDirection txDirectionZEnd = new TxDirectionBuilder() + .setPort(portZTx ) + .build();*/ + + RxDirection rxDirectionZEnd = getRxDirection(tempZPortRx); + TxDirection txDirectionZEnd = getTxDirection(tempZPortTx); + + ServiceZEnd serviceZEnd = new ServiceZEndBuilder() + .setClli(tempZ.getClli()) + .setNodeId(tempZ.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempZ.getServiceFormat().getName())) + .setServiceRate(tempZ.getServiceRate()) + .setRxDirection(rxDirectionZEnd) + .setTxDirection(txDirectionZEnd) + .build(); + + + /* ServiceImplementationRequestInput Build.*/ + + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types + .rev170426.response.parameters.sp.response.parameters.PathDescription tmp = null; + try { + tmp = pathComputationOutput.getResponseParameters().getPathDescription(); + } catch (NullPointerException e) { + LOG.error("PathDescription is null : " + e.toString()); + } + PathDescriptionBuilder pathDescription = new PathDescriptionBuilder(); + if (tmp != null) { + pathDescription = new PathDescriptionBuilder(tmp); + } + serviceImplementationRequestInput = new ServiceImplementationRequestInputBuilder() + .setPathDescription(pathDescription.build()) + .setServiceHandlerHeader(serviceHandlerHeader.build()) + .setServiceName(serviceReconfigureInput.getNewServiceName()) + .setServiceAEnd(serviceAEnd) + .setServiceZEnd(serviceZEnd) + .build(); + LOG.info("ServiceImplementationRequestInput : " + serviceImplementationRequestInput.toString()); + } + + + /* + * MappingAndSendingSIRequest class constructor + * for RPC serviceDelete. + * + * @param rpcRegistry RpcProviderRegistry + * @param requestId Request ID + * @param serviceName Service name + */ + public MappingAndSendingSIRequest(RpcProviderRegistry rpcRegistry,String requestId, String serviceName) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubrendererService.class); + } + setSuccess(false); + setError(""); + + /* ServiceDeleteInput Build .*/ + ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder(); + if (requestId != null) { + serviceHandlerHeader.setRequestId(requestId); + } + + serviceDeleteInput = new ServiceDeleteInputBuilder() + .setServiceHandlerHeader(serviceHandlerHeader.build()) + .setServiceName(serviceName) + .build(); + } + + /* + * MappingAndSendingSIRequest Class constructor + * for modify Service in ODL Datastore. + * + * @param rpcRegistry RpcProviderRegistry + * @param services Services + */ + public MappingAndSendingSIRequest(RpcProviderRegistry rpcRegistry,Services services) { + this.rpcRegistry = rpcRegistry; + if (rpcRegistry != null) { + service = rpcRegistry.getRpcService(StubrendererService.class); + } + setSuccess(false); + setError(""); + + /* Building ServiceImplementationRequestInput / ServiceDeleteInput serviceDeleteInput .*/ + ServiceHandlerHeaderBuilder serviceHandlerHeader = new ServiceHandlerHeaderBuilder(); + + /*ServiceAEnd Build .*/ + org.opendaylight.yang.gen.v1.http.org.openroadm.common.service + .types.rev161014.service.ServiceAEnd tempA = services.getServiceAEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortRx = tempA.getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempAPortTx = tempA.getTxDirection().getPort(); + + + RxDirection rxDirectionAEnd = getRxDirection(tempAPortRx); + + TxDirection txDirectionAEnd = getTxDirection(tempAPortTx); + + ServiceAEnd serviceAEnd = new ServiceAEndBuilder() + .setClli(tempA.getClli()) + .setNodeId(tempA.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempA.getServiceFormat().getName())) + .setServiceRate(tempA.getServiceRate()) + .setRxDirection(rxDirectionAEnd) + .setTxDirection(txDirectionAEnd) + .build(); + + /* ServiceZEnd Build .*/ + org.opendaylight.yang.gen.v1.http.org.openroadm.common.service + .types.rev161014.service.ServiceZEnd tempZ = services.getServiceZEnd(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortRx = tempZ.getRxDirection().getPort(); + + org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempZPortTx = tempZ.getTxDirection().getPort(); + + RxDirection rxDirectionZEnd = getRxDirection(tempZPortRx); + TxDirection txDirectionZEnd = getTxDirection(tempZPortTx); + + ServiceZEnd serviceZEnd = new ServiceZEndBuilder() + .setClli(tempZ.getClli()) + .setNodeId(tempZ.getNodeId()) + .setServiceFormat(ServiceFormat.valueOf(tempZ.getServiceFormat().getName())) + .setServiceRate(tempZ.getServiceRate()) + .setRxDirection(rxDirectionZEnd) + .setTxDirection(txDirectionZEnd) + .build(); + + + /* ServiceImplementationRequestInput Build.*/ + + + List atozList = new ArrayList(); + List ztoaList = new ArrayList(); + + for (org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZ + tmp : services.getTopology().getAToZ()) { + + AToZKey key = new AToZKey(tmp.getKey().getId()); + Resource atozresource = new ResourceBuilder() + .build(); + AToZ atoz = new AToZBuilder() + .setId(tmp.getId()) + .setKey(key) + .setResource(atozresource) + .build(); + atozList.add(atoz); + } + + for (org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToA + tmp : services.getTopology().getZToA()) { + ZToAKey key = new ZToAKey(tmp.getKey().getId()); + Resource ztoaresource = new ResourceBuilder() + .build(); + ZToA ztoa = new ZToABuilder() + .setId(tmp.getId()) + .setKey(key) + .setResource(ztoaresource) + .build(); + ztoaList.add(ztoa); + } + + AToZDirection atozdirection = new AToZDirectionBuilder() + .setAToZ(atozList) + .build(); + + ZToADirection ztoadirection = new ZToADirectionBuilder() + .setZToA(ztoaList) + .build(); + + + PathDescription pathDescription = new PathDescriptionBuilder() + .setAToZDirection(atozdirection) + .setZToADirection(ztoadirection) + .build(); + + serviceImplementationRequestInput = new ServiceImplementationRequestInputBuilder() + .setPathDescription(pathDescription) + .setServiceHandlerHeader(serviceHandlerHeader.build()) + .setServiceName(services.getServiceName()) + .setServiceAEnd(serviceAEnd) + .setServiceZEnd(serviceZEnd) + .build(); + LOG.info("ServiceImplementationRequestInput : " + serviceImplementationRequestInput.toString()); + } + + /* + * Create RxDirection with Port + * information. + * + * @param tempPort Port + * @return RxDirection + */ + public RxDirection getRxDirection(org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempPort) { + Port port = new PortBuilder() + .setPortDeviceName(tempPort.getPortDeviceName()) + .setPortName(tempPort.getPortName()) + .setPortRack(tempPort.getPortRack()) + .setPortShelf(tempPort.getPortShelf()) + .setPortSlot(tempPort.getPortSlot()) + .setPortSubSlot(tempPort.getPortSubSlot()) + .setPortType(tempPort.getPortType()) + .build(); + + RxDirection result = new RxDirectionBuilder() + .setPort(port) + .build(); + + return result; + } + + /* + * Create TxDirection with Port + * information. + * + * @param tempPort Port + * @return TxDirection TxDirection + */ + public TxDirection getTxDirection(org.opendaylight.yang.gen.v1.http.org.openroadm.common + .service.types.rev161014.service.port.Port tempPort) { + Port port = new PortBuilder() + .setPortDeviceName(tempPort.getPortDeviceName()) + .setPortName(tempPort.getPortName()) + .setPortRack(tempPort.getPortRack()) + .setPortShelf(tempPort.getPortShelf()) + .setPortSlot(tempPort.getPortSlot()) + .setPortSubSlot(tempPort.getPortSubSlot()) + .setPortType(tempPort.getPortType()) + .build(); + + TxDirection result = new TxDirectionBuilder() + .setPort(port) + .build(); + + return result; + } + + /* + * Send serviceImplementation request to Render. + * + * @return ServiceImplementationRequestOutput data response from Renderer + */ + public ListenableFuture serviceImplementation() { + setSuccess(false); + return executor.submit(new Callable() { + + @Override + public ServiceImplementationRequestOutput call() throws Exception { + ServiceImplementationRequestOutput output = null; + if (serviceImplementationRequestInput != null) { + RpcResult rendererOutputResult = null; + Future> rendererOutputFuture = + service.serviceImplementationRequest(serviceImplementationRequestInput); + try { + rendererOutputResult = rendererOutputFuture.get();//wait to get the result + } catch (InterruptedException | CancellationException | ExecutionException e) { + setError("Did not receive the expected response from renderer to pathComputationRequest RPC " + + e.toString()); + LOG.error(error); + rendererOutputFuture.cancel(true); + } + + if (rendererOutputResult != null && rendererOutputResult.isSuccessful()) { + LOG.info("Renderer replied to serviceImplementation Request !"); + setSuccess(true); + ServiceImplementationRequestOutput rendererOutput = rendererOutputResult.getResult(); + output = new ServiceImplementationRequestOutputBuilder() + .setConfigurationResponseCommon(rendererOutput.getConfigurationResponseCommon()) + .build(); + setSuccess(true); + } + } else { + LOG.info("serviceImplementationRequestInput is not valid"); + } + + return output; + } + }); + + } + + /* + * Send serviceDelete request to Render. + * + * @return ServiceDeleteOutput data response from Renderer + */ + public ListenableFuture serviceDelete() { + setSuccess(false); + return executor.submit(new Callable() { + + @Override + public ServiceDeleteOutput call() throws Exception { + ServiceDeleteOutput output = null; + if (serviceDeleteInput != null) { + RpcResult rendererOutputResult = null; + Future> rendererOutputFuture = + service.serviceDelete(serviceDeleteInput); + + try { + rendererOutputResult = rendererOutputFuture.get();//wait to get the result + } catch (InterruptedException | CancellationException | ExecutionException e) { + setError("Did not receive the expected response from renderer to pathComputationRequest RPC " + + e.toString()); + LOG.error(error); + rendererOutputFuture.cancel(true); + } + + if (rendererOutputResult != null && rendererOutputResult.isSuccessful()) { + LOG.info("Renderer replied to serviceDelete Request!"); + setSuccess(true); + ServiceDeleteOutput rendererOutput = rendererOutputResult.getResult(); + output = new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(rendererOutput.getConfigurationResponseCommon()) + .build(); + setSuccess(true); + } + } + return output; + } + }); + + } + + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingConstraints.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingConstraints.java new file mode 100644 index 000000000..e61f605e5 --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MappingConstraints.java @@ -0,0 +1,289 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.servicehandler; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.CoRoutingOrGeneral; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.CoRouting; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.General; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.general.Diversity; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.general.Exclude; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.general.Include; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.constraints.co.routing.or.general.general.Latency; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.routing.constraints.HardConstraints; +import org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014.routing.constraints.SoftConstraints; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.co.routing.CoRoutingBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.DiversityBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.ExcludeBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.IncludeBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.LatencyBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.diversity.existing.service.contraints.sp.ExistingServiceApplicabilityBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraintsBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraintsBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class for mapping + * Hard/soft constraint from Service 1.2 + * to servicePath 1.4. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class MappingConstraints { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(MappingConstraints.class); + private HardConstraints serviceHardConstraints; + private SoftConstraints serviceSoftConstraints; + private org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.HardConstraints servicePathHardConstraints; + private org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.SoftConstraints servicePathSoftConstraints; + + + /* + * MappingConstraints class constructor + * for hard/soft from service 1.2. + * + * @param hard HardConstraints + * @param soft SoftConstraints + */ + public MappingConstraints(HardConstraints hard, SoftConstraints soft) { + setServiceHardConstraints(hard); + setServiceSoftConstraints(soft); + } + + /* + * MappingConstraints class constructor + * for hard/soft from servicePath 1.4. + * + * @param hard HardConstraints + * @param soft SoftConstraints + */ + public MappingConstraints(org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.HardConstraints hard, + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.SoftConstraints soft) { + setServicePathHardConstraints(hard); + setServicePathSoftConstraints(soft); + } + + /* + * map hard/soft constraints from Service 1.2 + * to ServicePath 1.4. + */ + public void serviceToServicePathConstarints() { + LOG.info("Mapping Service Constraints to ServicePath Constraints"); + CoRoutingOrGeneral coRoutingOrGeneral = null; + if (serviceHardConstraints != null) { + HardConstraintsBuilder tempHard = new HardConstraintsBuilder(); + coRoutingOrGeneral = serviceHardConstraints.getCoRoutingOrGeneral(); + General tmpGeneral = null; + CoRouting tmpCoRouting = null; + if (coRoutingOrGeneral != null) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.GeneralBuilder finalGeneral = + new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.GeneralBuilder(); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.CoRoutingBuilder finalCoRouting = + new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.CoRoutingBuilder(); + if (coRoutingOrGeneral instanceof General) { + tmpGeneral = (General) coRoutingOrGeneral; + if (tmpGeneral != null) { + Diversity tmpDiversity = tmpGeneral.getDiversity(); + if (tmpDiversity != null) { + finalGeneral.setDiversity( + new DiversityBuilder() + .setExistingService(tmpDiversity.getExistingService()) + .setExistingServiceApplicability( + new ExistingServiceApplicabilityBuilder() + .setClli(tmpDiversity.getExistingServiceApplicability().isSite()) + .setNode(tmpDiversity.getExistingServiceApplicability().isNode()) + .setSrlg(tmpDiversity.getExistingServiceApplicability().isSrlg()) + .build()) + .build()); + } + Exclude tmpExclude = tmpGeneral.getExclude(); + if (tmpExclude != null) { + finalGeneral.setExclude( + new ExcludeBuilder() + .setSupportingServiceName(tmpExclude.getSupportingServiceName()) + .setClli(tmpExclude.getSite()) + .setNodeId(tmpExclude.getNodeId()) + //.setAffinity(value) + //.setSRLG(value) + .build()); + } + Include tmpInclude = tmpGeneral.getInclude(); + if (tmpInclude != null) { + finalGeneral.setInclude( + new IncludeBuilder() + //.setOrderedHops() + .build()); + } + Latency tmpLatency = tmpGeneral.getLatency(); + if (tmpLatency != null) { + finalGeneral.setLatency( + new LatencyBuilder() + .setMaxLatency(tmpLatency.getMaxLatency()) + .build()); + } + } + tempHard + .setCoRoutingOrGeneral(finalGeneral.build()) + .setCustomerCode(serviceHardConstraints.getCustomerCode()); + } else if (coRoutingOrGeneral instanceof CoRouting) { + tmpCoRouting = (CoRouting)coRoutingOrGeneral; + if (tmpCoRouting != null) { + org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014 + .constraints.co.routing.or.general.co.routing.CoRouting tmpCoRoutingCoRouting = + tmpCoRouting.getCoRouting(); + if (tmpCoRoutingCoRouting != null) { + finalCoRouting.setCoRouting( + new CoRoutingBuilder() + .setExistingService(tmpCoRoutingCoRouting.getExistingService()) + .build()); + } + } + tempHard + .setCoRoutingOrGeneral(finalCoRouting.build()) + .setCustomerCode(serviceHardConstraints.getCustomerCode()); + + } + } + servicePathHardConstraints = tempHard.build(); + } else if (serviceSoftConstraints != null) { + SoftConstraintsBuilder tempSoft = new SoftConstraintsBuilder(); + coRoutingOrGeneral = serviceSoftConstraints.getCoRoutingOrGeneral(); + General tmpGeneral = null; + CoRouting tmpCoRouting = null; + if (coRoutingOrGeneral != null) { + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.GeneralBuilder finalGeneral = + new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.GeneralBuilder(); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.CoRoutingBuilder finalCoRouting = + new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints + .rev170426.constraints.sp.co.routing.or.general.CoRoutingBuilder(); + if (coRoutingOrGeneral instanceof General) { + tmpGeneral = (General) coRoutingOrGeneral; + if (tmpGeneral != null) { + Diversity tmpDiversity = tmpGeneral.getDiversity(); + if (tmpDiversity != null) { + finalGeneral.setDiversity( + new DiversityBuilder() + .setExistingService(tmpDiversity.getExistingService()) + .setExistingServiceApplicability( + new ExistingServiceApplicabilityBuilder() + .setClli(tmpDiversity.getExistingServiceApplicability().isSite()) + .setNode(tmpDiversity.getExistingServiceApplicability().isNode()) + .setSrlg(tmpDiversity.getExistingServiceApplicability().isSrlg()) + .build()) + .build()); + } + Exclude tmpExclude = tmpGeneral.getExclude(); + if (tmpExclude != null) { + finalGeneral.setExclude( + new ExcludeBuilder() + .setSupportingServiceName(tmpExclude.getSupportingServiceName()) + .setClli(tmpExclude.getSite()) + .setNodeId(tmpExclude.getNodeId()) + //.setAffinity(value) + //.setSRLG(value) + .build()); + } + Include tmpInclude = tmpGeneral.getInclude(); + if (tmpInclude != null) { + finalGeneral.setInclude( + new IncludeBuilder() + //.setOrderedHops() + .build()); + } + Latency tmpLatency = tmpGeneral.getLatency(); + if (tmpLatency != null) { + finalGeneral.setLatency( + new LatencyBuilder() + .setMaxLatency(tmpLatency.getMaxLatency()) + .build()); + } + } + tempSoft + .setCoRoutingOrGeneral(finalGeneral.build()) + .setCustomerCode(serviceSoftConstraints.getCustomerCode()); + } else if (coRoutingOrGeneral instanceof CoRouting) { + tmpCoRouting = (CoRouting)coRoutingOrGeneral; + if (tmpCoRouting != null) { + org.opendaylight.yang.gen.v1.http.org.openroadm.routing.constrains.rev161014 + .constraints.co.routing.or.general.co.routing.CoRouting tmpCoRoutingCoRouting = + tmpCoRouting.getCoRouting(); + if (tmpCoRoutingCoRouting != null) { + finalCoRouting.setCoRouting( + new CoRoutingBuilder() + .setExistingService(tmpCoRoutingCoRouting.getExistingService()) + .build()); + } + } + tempSoft + .setCoRoutingOrGeneral(finalCoRouting.build()) + .setCustomerCode(serviceSoftConstraints.getCustomerCode()); + + } + } + servicePathSoftConstraints = tempSoft.build(); + } + } + + + public HardConstraints getServiceHardConstraints() { + return serviceHardConstraints; + } + + + public void setServiceHardConstraints(HardConstraints serviceHardConstraints) { + this.serviceHardConstraints = serviceHardConstraints; + } + + + public SoftConstraints getServiceSoftConstraints() { + return serviceSoftConstraints; + } + + + public void setServiceSoftConstraints(SoftConstraints serviceSoftConstraints) { + this.serviceSoftConstraints = serviceSoftConstraints; + } + + + public org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.HardConstraints getServicePathHardConstraints() { + return servicePathHardConstraints; + } + + + public void setServicePathHardConstraints(org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.HardConstraints servicePathHardConstraints) { + this.servicePathHardConstraints = servicePathHardConstraints; + } + + + public org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.SoftConstraints getServicePathSoftConstraints() { + return servicePathSoftConstraints; + } + + + public void setServicePathSoftConstraints(org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .routing.constraints.rev170426.routing.constraints.sp.SoftConstraints servicePathSoftConstraints) { + this.servicePathSoftConstraints = servicePathSoftConstraints; + } + +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MyEndpoint.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MyEndpoint.java new file mode 100644 index 000000000..494ff75af --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/MyEndpoint.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import java.util.Map; + +/* + * Enum class to identify ServiceAEnd / serviceZEnd. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +enum MyEndpoint { + SERVICEAEND(1), + SERVICEZEND(2); + + int value; + private static final Map VALUE_MAP; + + MyEndpoint(int value) { + this.value = value; + } + + static { + final com.google.common.collect.ImmutableMap.Builder b = + com.google.common.collect.ImmutableMap.builder(); + for (MyEndpoint enumItem : MyEndpoint.values()) { + b.put(enumItem.value, enumItem); + } + + VALUE_MAP = b.build(); + } + + /* + * Get integer value. + * + * @return integer value. + */ + public int getIntValue() { + return value; + } + + /* + * Get Endpoint value. + * + * @param valueArg + * Integer to identify Enum + * @return corresponding ServiceFormat item + */ + public static MyEndpoint forValue(int valueArg) { + return VALUE_MAP.get(valueArg); + } +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerCompliancyCheck.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerCompliancyCheck.java new file mode 100644 index 000000000..63350057e --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerCompliancyCheck.java @@ -0,0 +1,180 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ConnectionType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.RpcActions; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.sdnc.request.header.SdncRequestHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class for checking service sdnc-request-header compliancy. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class ServicehandlerCompliancyCheck { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerCompliancyCheck.class); + /* SdncRequestHeader. */ + private SdncRequestHeader sndcRequestHeader; + /* Service Name. */ + private String serviceName; + /* Type of connection : service / infrastructure / roadm-line. */ + private ConnectionType conType; + /* type of service : service-create / service-delete ... */ + private RpcActions action; + /* Response message from procedure. */ + private String message; + + /* + * ServicehandlerCompliancyCheck class constructor. + * + * @param sdncRequestHeader + * SdncRequestHeader + * @param serviceName + * String Service Name + * @param conType + * Connection Type + * @param action + * RPC type + */ + public ServicehandlerCompliancyCheck(SdncRequestHeader sdncRequestHeader, String serviceName, + ConnectionType conType, RpcActions action) { + this.sndcRequestHeader = sdncRequestHeader; + this.serviceName = serviceName; + this.conType = conType; + this.action = action; + this.setMessage(""); + } + + /* + * ServicehandlerCompliancyCheck class constructor. + * + * @param sdncRequestHeader + * SdncRequestHeader + * @param serviceName + * String Service Name + * @param action + * RPC type + */ + public ServicehandlerCompliancyCheck(SdncRequestHeader sdncRequestHeader, String serviceName, RpcActions action) { + this.sndcRequestHeader = sdncRequestHeader; + this.serviceName = serviceName; + this.action = action; + this.setMessage(""); + } + + /* + * ServicehandlerCompliancyCheck class constructor. + * + * @param serviceName + * String Service Name + * @param conType + * Connection Type + * @param action + * RPC type + */ + public ServicehandlerCompliancyCheck(String serviceName, ConnectionType conType, RpcActions action) { + this.serviceName = serviceName; + this.conType = conType; + this.action = action; + this.setMessage(""); + } + + /* + * ServicehandlerCompliancyCheck class constructor. + * + * @param serviceName + * String Service Name + * @param action + * RPC type + */ + public ServicehandlerCompliancyCheck(String serviceName, RpcActions action) { + this.serviceName = serviceName; + this.action = action; + this.setMessage(""); + } + + /* + * Check if a String is not null and not equal to void. + * + * @param value + * String value + * @return true if String ok false if not + */ + public Boolean checkString(String value) { + Boolean result = false; + if (value != null && value.compareTo("") != 0) { + result = true; + } + return result; + + } + + /* + * Check Compliancy of Service request. + * + * @param contype + * Boolean to check connection Type + * @param sndcRequest + * Boolean to check sndcRequestHeader + * + * @return true if String ok false if not + */ + public Boolean check(Boolean contype, Boolean sndcRequest) { + Boolean result = true; + if (!checkString(serviceName)) { + result = false; + message = "Service Name is not set"; + LOG.debug(message); + } else if (contype && conType == null) { + result = false; + message = "Service ConnectionType is not set"; + LOG.debug(message); + } + if (sndcRequest) { + if (sndcRequestHeader != null) { + RpcActions serviceAction = sndcRequestHeader.getRpcAction(); + String requestId = sndcRequestHeader.getRequestId(); + if (!checkString(requestId)) { + result = false; + message = "Service sndcRequestHeader 'request-id' is not set"; + LOG.debug(message); + } else if (serviceAction != null) { + if (serviceAction.compareTo(action) != 0) { + result = false; + message = "Service sndcRequestHeader rpc-action '" + serviceAction + "' not equal to '" + + action.name() + "'"; + LOG.debug(message); + } + } else { + result = false; + message = "Service sndc-request-header 'rpc-action' is not set "; + LOG.debug(message); + } + + } else { + result = false; + message = "Service sndc-request-header is not set "; + LOG.debug(message); + } + } + return result; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerTxRxCheck.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerTxRxCheck.java new file mode 100644 index 000000000..d55d9d063 --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/ServicehandlerTxRxCheck.java @@ -0,0 +1,201 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceEndpoint; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceFormat; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.RxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.TxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.lgx.Lgx; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.Port; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class for checking missing info on Tx/Rx for A/Z end. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + */ +public class ServicehandlerTxRxCheck { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerTxRxCheck.class); + /* ServiceEndpoint. */ + private ServiceEndpoint serviceEnd; + /* Response message from procedure. */ + private String message; + /* type serviceEndpoint : serviceAEnd / serviceZEnd. */ + private String service = null; + + /* + * ServicehandlerTxRxCheck class constructor. + * + * @param endPoint + * ServiceEndpoint + * @param value + * Integer to define ServiceAEND/ZEND + */ + public ServicehandlerTxRxCheck(ServiceEndpoint endPoint, int value) { + this.serviceEnd = endPoint; + this.setMessage(""); + if (value > 0) { + service = MyEndpoint.forValue(value).name(); + } + } + + /* + * Check if a String is not null and not equal to ''. + * + * @param value + * String value + * @return true if String ok false if not + */ + public Boolean checkString(String value) { + Boolean result = false; + if (value != null && value.compareTo("") != 0) { + result = true; + } + return result; + + } + + /* + * check if Port info is compliant. + * + * @param port + * port info + * @return true if String ok false if not + */ + public Boolean checkPort(Port port) { + Boolean result = false; + if (port != null) { + String portDeviceName = port.getPortDeviceName(); + String portType = port.getPortType(); + String portName = port.getPortName(); + String portRack = port.getPortRack(); + String portShelf = port.getPortShelf(); + + if (checkString(portDeviceName) && checkString(portType) && checkString(portName) && checkString(portRack) + && checkString(portShelf)) { + result = true; + } + } + return result; + + } + + /* + * Check if lgx info is compliant. + * + * @param lgx + * lgx info + * @return true if String ok false if not + */ + public Boolean checkLgx(Lgx lgx) { + Boolean result = false; + if (lgx != null) { + String lgxDeviceName = lgx.getLgxDeviceName(); + String lgxPortName = lgx.getLgxPortName(); + String lgxPortRack = lgx.getLgxPortRack(); + String lgxPortShelf = lgx.getLgxPortShelf(); + if (checkString(lgxDeviceName) && checkString(lgxPortName) && checkString(lgxPortRack) + && checkString(lgxPortShelf)) { + result = true; + } + } + return result; + } + + /* + * Check if Tx/Rx Direction complaincy info. + * + * @param txDirection + * TxDirection + * @param rxDirection + * RxDirection + * + * @return true if check is ok false else + */ + public boolean checkTxOrRxInfo(TxDirection txDirection, RxDirection rxDirection) { + Boolean result = true; + if (txDirection != null) { + if (!checkPort(txDirection.getPort())) { + result = false; + message = "Service TxDirection Port is not correctly set"; + } else if (!checkLgx(txDirection.getLgx())) { + result = false; + message = "Service TxDirection Lgx is not correctly set"; + } else if (rxDirection != null) { + if (!checkPort(rxDirection.getPort())) { + result = false; + message = "Service RxDirection Port is not correctly set"; + } else if (!checkLgx(rxDirection.getLgx())) { + result = false; + message = "Service RxDirection Lgx is not correctly set"; + } + } else { + result = false; + message = "Service RxDirection is not correctly set"; + } + } else { + result = false; + message = "Service TxDirection is not correctly set"; + } + return result; + } + + /* + * Check Compliancy of Service TxRx info. + * + * @return true if String ok false if not + */ + public Boolean check() { + Boolean result = true; + if (serviceEnd != null) { + Long serviceRate = serviceEnd.getServiceRate(); + ServiceFormat serviceformat = serviceEnd.getServiceFormat(); + String clli = serviceEnd.getClli(); + if (serviceRate != null && serviceRate <= 0) { + result = false; + message = "Service " + service + " rate is not set"; + LOG.debug(message); + } else if (serviceformat == null) { + result = false; + message = "Service " + service + " format is not set"; + LOG.debug(message); + } else if (!checkString(clli)) { + result = false; + message = "Service" + service + " clli format is not set"; + LOG.debug(message); + } else { + if (!checkTxOrRxInfo(serviceEnd.getTxDirection(), serviceEnd.getRxDirection())) { + result = false; + } + } + } else { + result = false; + message = service + " is not set"; + LOG.debug(message); + } + return result; + + } + + public static void main(String[] args) { + + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java new file mode 100644 index 000000000..355681ebd --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java @@ -0,0 +1,2056 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler.impl; + +import com.google.common.base.Optional; + +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.transportpce.servicehandler.CheckCoherencyHardSoft; +import org.opendaylight.transportpce.servicehandler.LoggingFuturesCallBack; +import org.opendaylight.transportpce.servicehandler.MappingAndSendingPCRequest; +import org.opendaylight.transportpce.servicehandler.MappingAndSendingSIRequest; +import org.opendaylight.transportpce.servicehandler.ServicehandlerCompliancyCheck; +import org.opendaylight.transportpce.servicehandler.ServicehandlerTxRxCheck; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.EquipmentNotificationInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.EquipmentNotificationOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.NetworkReOptimizationInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.NetworkReOptimizationOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceCreateInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceCreateOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceCreateOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceDeleteInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceDeleteOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceFeasibilityCheckInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceFeasibilityCheckOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceFeasibilityCheckOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceList; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceListBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReconfigureInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReconfigureOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReconfigureOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRerouteConfirmInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRerouteConfirmOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRerouteInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRerouteOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRestorationInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRestorationOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRestorationOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReversionInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceReversionOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRollInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRollOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRpcResult; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServiceRpcResultBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServicehandlerService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.TempServiceCreateInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.TempServiceCreateOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.TempServiceDeleteInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.TempServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.feasibility.check.output.IntermediateSites; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.feasibility.check.output.IntermediateSitesBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.list.Services; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.list.ServicesBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.list.ServicesKey; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResult; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceListener; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceRpcResultSp; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererListener; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.RpcActions; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceFormat; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceNotificationTypes; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommon; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.response.parameters.ResponseParameters; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.response.parameters.ResponseParametersBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.ServiceAEnd; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.ServiceAEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.ServiceZEnd; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.ServiceZEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.Topology; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.TopologyBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.RxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.RxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.TxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.endpoint.TxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.lgx.Lgx; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.lgx.LgxBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.Port; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.PortBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.LifecycleState; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticTypes; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.State; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZ; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToA; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/* + * Class to implement ServicehandlerService & ServicehandlerListener. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class ServicehandlerImpl implements ServicehandlerService, StubpceListener, StubrendererListener, AutoCloseable { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerImpl.class); + /* Permit to access database. */ + private DataBroker db; + /* check service sdnc-request-header compliancy. */ + private ServicehandlerCompliancyCheck compliancyCheck; + /* check missing info on Tx/Rx for A/Z end. */ + private ServicehandlerTxRxCheck txrxCheck; + /* check coherency between hard & sof constraints. */ + private CheckCoherencyHardSoft checkCoherencyHardSoft; + /* + * Map and Send PCE requests : - + * path-computation-request/cancel-resource-reserve. + */ + private MappingAndSendingPCRequest mappingAndSendingPCRequest; + /* + * Map and Send Service Implemention requests : - service + * implementation/service delete. + */ + private MappingAndSendingSIRequest mappingAndSendingSIRequest; + + private RpcProviderRegistry rpcRegistry; + private NotificationPublishService notificationPublishService; + private final ListeningExecutorService executor; + + private ServicePathRpcResult servicePathRpcResult = null; + private ServiceRpcResultSp serviceRpcResultSp = null; + + private String notificationUrl = ""; + private RpcActions action; + + public ServicehandlerImpl(DataBroker databroker, RpcProviderRegistry rpcRegistry, + NotificationPublishService notificationPublishService) { + this.db = databroker; + this.rpcRegistry = rpcRegistry; + this.notificationPublishService = notificationPublishService; + executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5)); + initializeDataTree(db); + } + + @Override + public Future> serviceCreate(ServiceCreateInput input) { + LOG.info("RPC service creation received"); + action = RpcActions.ServiceCreate; + boolean commonId = true; + boolean coherencyHardSoft = false; + ServiceRpcResult notification = null; + notificationUrl = null;// input.getSdncRequestHeader().getnotificationUrl(); + LOG.info("notificationUrl : " + notificationUrl); + + ResponseParametersBuilder responseParameters = new ResponseParametersBuilder(); + ConfigurationResponseCommon configurationResponseCommon; + String message = ""; + String responseCode = ""; + + LOG.info("checking Service Compliancy ..."); + /* + * Upon receipt of service-create RPC, service header and sdnc-request + * header compliancy are verified. + */ + compliancyCheck = new ServicehandlerCompliancyCheck(input.getSdncRequestHeader(), input.getServiceName(), + input.getConnectionType(), RpcActions.ServiceCreate); + if (compliancyCheck.check(true, true)) { + LOG.info("Service compliant !"); + /* + * If compliant, service-request parameters are verified in order to + * check if there is no missing parameter that prevents calculating + * a path and implement a service. + */ + LOG.info("checking Tx/Rx Info for AEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceAEnd(), 1); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for AEnd checked !"); + LOG.info("checking Tx/Rx Info for ZEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceZEnd(), 2); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for ZEnd checked"); + /* + * If OK, common-id is verified in order to see if there is + * no routing policy provided. If yes, the routing + * constraints of the policy are recovered and coherency + * with hard/soft constraints provided in the input of the + * RPC. + */ + if (input.getCommonId() != null) { + LOG.info("Common-id specified"); + /* + * Check coherency with hard/soft constraints + */ + + checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(), + input.getSoftConstraints()); + if (checkCoherencyHardSoft.check()) { + LOG.info("hard/soft constraints coherent !"); + coherencyHardSoft = true; + } else { + LOG.info("hard/soft constraints are not coherent !"); + message = "hard/soft constraints are not coherent !"; + responseCode = "500"; + } + } else { + commonId = false; + } + + if (!commonId || (commonId && coherencyHardSoft)) { + /* + * Before sending the PCE request, input data need to be + * formatted according to the Service Handler PCE + * interface data model. + */ + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, input, true); + /* + * Once PCE request is being sent to the PCE on + * interface B, PCE reply is expected until a timer + * expires. + */ + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting PathComputation Request ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + FutureCallback pceCallback = + new FutureCallback() { + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + + @Override + public void onSuccess(PathComputationRequestOutput response) { + if (mappingAndSendingPCRequest.getSuccess() && response != null) { + /* + * If PCE reply is received before timer + * expiration with a positive result, a + * service is created with admin and + * operational status 'down'. + */ + LOG.info("PCE replied to PCR Request !"); + + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("PCE replied to PCR Request !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + String result = null; + if ((result = writeOrModifyOrDeleteServiceList(input.getServiceName(), input, + response, 2)) != null) { + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" " + result); + message = build.toString(); + } else { + /* + * Send Implementation order to renderer + */ + mappingAndSendingSIRequest = new MappingAndSendingSIRequest(rpcRegistry, input, + response); + + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Submitting ServiceImplementation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + /* + * Once PCE request is being sent to the + * PCE on interface B, PCE reply is + * expected until a timer expires. + */ + ServiceImplementationRequestOutput siOutput = null; + try { + siOutput = mappingAndSendingSIRequest.serviceImplementation().get(); + } catch (InterruptedException | ExecutionException e2) { + LOG.error("mappingAndSendingSIRequest.serviceImplementation().get() : " + + e2.getMessage()); + } + if (siOutput == null) { + LOG.info("siOutput is null "); + LOG.info("Success : " + mappingAndSendingPCRequest.getSuccess()); + } + if (mappingAndSendingSIRequest.getSuccess() && siOutput != null) { + ConfigurationResponseCommon siCommon = siOutput + .getConfigurationResponseCommon(); + // message = + // siCommon.getResponseMessage(); + responseCode = siCommon.getResponseCode(); + message = "Service implemented !"; + LOG.info(message); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Successful).setStatusMessage(message) + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + /* + * Service implemented setting + * Service op status to up + */ + if (writeOrModifyOrDeleteServiceList(input.getServiceName(), null, null, + 0) == null) { + /* + * Service modified. + */ + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" : Service Op Status changed to Up !"); + message = build.toString(); + } else { + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" but Failed to modify service from Service List !"); + message = build.toString(); + } + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Successful).setStatusMessage(message) + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } else { + LOG.info("Service not implemented !"); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage( + "Service not implemented, cancelling ResourceResv ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, + input, false); + /* + * Send Cancel resource Request to + * PCE. + */ + CancelResourceReserveOutput cancelOuptut = null; + try { + cancelOuptut = mappingAndSendingPCRequest.cancelResourceReserve().get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error(e1.getMessage()); + } + if (mappingAndSendingPCRequest.getSuccess() && cancelOuptut != null) { + LOG.info("Service ResourceResv cancelled !"); + message = response.getConfigurationResponseCommon() + .getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage("Service ResourceResv cancelled").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + message = cancelOuptut.getConfigurationResponseCommon() + .getResponseMessage(); + responseCode = cancelOuptut.getConfigurationResponseCommon() + .getResponseCode(); + + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + + LOG.info("PCE replied to CancelResourceResv Request !"); + } else { + message = "Cancelling Resource reserved failed "; + LOG.info(message); + responseCode = "500"; + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + + message = response.getConfigurationResponseCommon() + .getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage("Cancelling Resource reserved failed") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + + } + } + } else { + message = mappingAndSendingPCRequest.getError();// "Path + // not + // calculated"; + responseCode = "500"; + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName("").setStatus(RpcStatusEx.Failed).setStatusMessage(message) + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + + } + + @Override + public void onFailure(Throwable arg0) { + LOG.error("Path not calculated.."); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("PCR Request failed : " + arg0.getMessage()).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + }; + ListenableFuture pce = mappingAndSendingPCRequest + .pathComputationRequest(); + Futures.addCallback(pce, pceCallback); + LOG.info("PCR Request in progress "); + configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("No").setRequestId(input.getSdncRequestHeader().getRequestId()) + .setResponseMessage("Service compliant, serviceCreate in progress...") + .setResponseCode("200").build(); + + ServiceCreateOutputBuilder output = new ServiceCreateOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon) + .setResponseParameters(responseParameters.build()); + + return RpcResultBuilder.success(output.build()).buildFuture(); + } + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; + } + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; + } + } else { + message = compliancyCheck.getMessage(); + responseCode = "500"; + } + + configurationResponseCommon = new ConfigurationResponseCommonBuilder().setAckFinalIndicator("Yes") + .setRequestId(input.getSdncRequestHeader().getRequestId()).setResponseMessage(message) + .setResponseCode(responseCode).build(); + + ServiceCreateOutputBuilder output = new ServiceCreateOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon) + .setResponseParameters(responseParameters.build()); + + return RpcResultBuilder.success(output.build()).buildFuture(); + + } + + @Override + public Future> serviceDelete(ServiceDeleteInput input) { + LOG.info("RPC serviceDelete request received for Service '" + input.getServiceDeleteReqInfo().getServiceName() + + "'"); + notificationUrl = null;// input.getSdncRequestHeader().getnotificationUrl(); + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + ResponseParametersBuilder responseParameters = new ResponseParametersBuilder(); + LOG.info("checking Service Compliancy ..."); + /* + * Upon receipt of service-delete RPC, service header and sdnc-request + * header compliancy are verified. + */ + compliancyCheck = new ServicehandlerCompliancyCheck(input.getSdncRequestHeader(), + input.getServiceDeleteReqInfo().getServiceName(), RpcActions.ServiceDelete); + if (compliancyCheck.check(false, true)) { + LOG.info("Service compliant !"); + String serviceName = input.getServiceDeleteReqInfo().getServiceName(); + Services service = readServiceList(serviceName); + if (service != null) { + LOG.debug("Service '" + serviceName + "' present in datastore !"); + /* + * If compliant, service-delete order is send to renderer. + */ + mappingAndSendingSIRequest = new MappingAndSendingSIRequest(rpcRegistry, + input.getSdncRequestHeader().getRequestId(), input.getServiceDeleteReqInfo().getServiceName()); + + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceDeleteResult).setServiceName(serviceName) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting serviceDelete Request ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + FutureCallback rendererCallback = + new FutureCallback() { + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + + @Override + public void onFailure(Throwable arg0) { + LOG.error("ServiceDelete Request failed !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceDeleteResult) + .setServiceName(serviceName).setStatus(RpcStatusEx.Failed) + .setStatusMessage("ServiceDelete Request failed !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + + @Override + public void onSuccess(org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce + .stubrenderer.rev170426.ServiceDeleteOutput arg0) { + + if (mappingAndSendingPCRequest.getSuccess() && arg0 != null) { + message = "Service deleted !"; + LOG.info(message); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceDeleteResult) + .setServiceName(input.getServiceDeleteReqInfo().getServiceName()) + .setStatus(RpcStatusEx.Successful).setStatusMessage("Service deleted !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + // message = + // result.getConfigurationResponseCommon().getResponseMessage(); + responseCode = arg0.getConfigurationResponseCommon().getResponseCode(); + /* + * Service delete confirmed deleting service from + * database + */ + if (writeOrModifyOrDeleteServiceList(input.getServiceDeleteReqInfo().getServiceName(), null, + null, 1) == null) { + /* Service delete. */ + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" : Service deleted from database"); + message = build.toString(); + } else { + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" but Failed to delete service from database !"); + message = build.toString(); + } + LOG.info(message); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceDeleteResult) + .setServiceName(input.getServiceDeleteReqInfo().getServiceName()) + .setStatus(RpcStatusEx.Successful).setStatusMessage(message).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } else { + message = "deleting service failed"; + responseCode = "500"; + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceDeleteResult) + .setServiceName(input.getServiceDeleteReqInfo().getServiceName()) + .setStatus(RpcStatusEx.Failed).setStatusMessage(message).build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + } + }; + ListenableFuture renderer = + mappingAndSendingSIRequest.serviceDelete(); + Futures.addCallback(renderer, rendererCallback); + LOG.info("ServiceDelete Request in progress ... "); + ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("No").setRequestId(input.getSdncRequestHeader().getRequestId()) + .setResponseMessage("ServiceDelete Request in progress ...").setResponseCode("200").build(); + ServiceDeleteOutput output = new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon).build(); + return RpcResultBuilder.success(output).buildFuture(); + } else { + message = "Service '" + serviceName + "' not exists in datastore"; + LOG.error(message); + } + + } else { + message = "Service not compliant !"; + responseCode = "500"; + } + + /* + * Building output response. + */ + + ConfigurationResponseCommon configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("Yes").setRequestId(input.getSdncRequestHeader().getRequestId()) + .setResponseMessage(message).setResponseCode(responseCode).build(); + ServiceDeleteOutput output = new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon).build(); + return RpcResultBuilder.success(output).buildFuture(); + } + + @Override + public Future> serviceFeasibilityCheck( + ServiceFeasibilityCheckInput input) { + notificationUrl = null;// input.getSdncRequestHeader().getnotificationUrl(); + action = RpcActions.ServiceFeasibilityCheck; + LOG.info("RPC service feasibilityCheck received"); + boolean commonId = true; + boolean coherencyHardSoft = false; + ServiceRpcResult notification = null; + String name = "no name"; + mappingAndSendingPCRequest = null; + + ConfigurationResponseCommon configurationResponseCommon = null; + String message = ""; + String responseCode = ""; + LOG.info("checking Service Compliancy ..."); + /* + * Upon receipt of service-create RPC, service header and sdnc-request + * header compliancy are verified. + */ + compliancyCheck = new ServicehandlerCompliancyCheck(input.getSdncRequestHeader(), name, + input.getConnectionType(), RpcActions.ServiceFeasibilityCheck); + if (compliancyCheck.check(true, true)) { + LOG.info("Service compliant !"); + /* + * If compliant, service-request parameters are verified in order to + * check if there is no missing parameter that prevents calculating + * a path and implement a service. + */ + LOG.info("checking Tx/Rx Info for AEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceAEnd(), 1); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for AEnd checked !"); + LOG.info("checking Tx/Rx Info for ZEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceZEnd(), 2); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for ZEnd checked"); + /* + * If OK, common-id is verified in order to see if there is + * no routing policy provided. If yes, the routing + * constraints of the policy are recovered and coherency + * with hard/soft constraints provided in the input of the + * RPC. + */ + if (input.getCommonId() != null) { + LOG.info("Common-id specified"); + /* + * Check coherency with hard/soft constraints + */ + + checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(), + input.getSoftConstraints()); + if (checkCoherencyHardSoft.check()) { + LOG.info("hard/soft constraints coherent !"); + coherencyHardSoft = true; + } else { + LOG.info("hard/soft constraints are not coherent !"); + message = "hard/soft constraints are not coherent !"; + responseCode = "500"; + } + } else { + commonId = false; + } + + if (!commonId || (commonId && coherencyHardSoft)) { + /* + * Before sending the PCE request, input data need to be + * formatted according to the Service Handler - PCE + * interface data model. + */ + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, input, false); + /* + * Once PCE request is being sent to the PCE on + * interface B, PCE reply is expected until a timer + * expires. + */ + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult).setServiceName(name) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, Submitting PathComputation Request ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + FutureCallback pceCallback = + new FutureCallback() { + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + + @Override + public void onFailure(Throwable arg0) { + LOG.error("Path not calculated.."); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(name).setStatus(RpcStatusEx.Failed) + .setStatusMessage("PCR Request failed !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + } + + @Override + public void onSuccess(PathComputationRequestOutput response) { + + if (mappingAndSendingPCRequest.getSuccess() && response != null) { + /* + * If PCE reply is received before timer + * expiration with a positive result, a + * service is created with admin and + * operational status 'down'. + */ + LOG.info("PCE replied to PCR Request !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName("").setStatus(RpcStatusEx.Successful) + .setStatusMessage("Service Feasility Checked").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + message = response.getConfigurationResponseCommon().getResponseMessage(); + sendNotifToUrl(notification, notificationUrl); + } else { + message = mappingAndSendingPCRequest.getError();// "Path + // not + // calculated"; + responseCode = "500"; + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName("").setStatus(RpcStatusEx.Failed).setStatusMessage(message) + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + } + + }; + ListenableFuture pce = mappingAndSendingPCRequest + .pathComputationRequest(); + Futures.addCallback(pce, pceCallback); + LOG.info("PCR Request in progress "); + configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("No").setRequestId(input.getSdncRequestHeader().getRequestId()) + .setResponseMessage("Service compliant, ServiceFeasibilityCheck in progress...") + .setResponseCode("200").build(); + + ServiceFeasibilityCheckOutput output = new ServiceFeasibilityCheckOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon).build(); + + return RpcResultBuilder.success(output).buildFuture(); + + } + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; + } + } else { + message = txrxCheck.getMessage(); + responseCode = "500"; + } + } else { + message = compliancyCheck.getMessage(); + responseCode = "500"; + } + + configurationResponseCommon = new ConfigurationResponseCommonBuilder().setAckFinalIndicator("Yes") + .setRequestId(input.getSdncRequestHeader().getRequestId()).setResponseMessage(message) + .setResponseCode(responseCode).build(); + + ResponseParameters responseParameters = new ResponseParametersBuilder() + .setHardConstraints(input.getHardConstraints()) + // .setPceMetric(input.getPceMetric()) + .setSoftConstraints(input.getSoftConstraints()) + // .setLocallyProtectedLinks(input.isLocallyProtectedLinks()) + .build(); + + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.feasibility + .check.output.ServiceAEnd serviceAEnd = new org.opendaylight.yang.gen.v1.http.org.opendaylight + .transportpce.servicehandler.rev161014.service.feasibility + .check.output.ServiceAEndBuilder(input.getServiceAEnd()).build(); + + org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.service.feasibility + .check.output.ServiceZEnd serviceZEnd = new org.opendaylight.yang.gen.v1.http.org.opendaylight + .transportpce.servicehandler.rev161014.service.feasibility + .check.output.ServiceZEndBuilder(input.getServiceZEnd()).build(); + + /* TxDirection. */ + Port txPort = new PortBuilder().setPortDeviceName("ROUTER_SNJSCAMCJW1_000000.00_00").setPortType("router") + .setPortName("Gigabit Ethernet_Tx.ge-1/0/0.0").setPortRack("000000.00").setPortShelf("00").build(); + Lgx txLgx = new LgxBuilder().setLgxDeviceName("LGX Panel_SNJSCAMCJW1_000000.00_00") + .setLgxPortName("LGX_Back.23").setLgxPortRack("000000.00").setLgxPortShelf("00").build(); + TxDirection txDirection = new TxDirectionBuilder().setPort(txPort).setLgx(txLgx).build(); + + /* RxDirection. */ + Port rxPort = new PortBuilder().setPortDeviceName("ROUTER_SNJSCAMCJW1_000000.00_00").setPortType("router") + .setPortName("Gigabit Ethernet_Rx.ge-1/0/0.0").setPortRack("000000.00").setPortShelf("00").build(); + Lgx rxLgx = new LgxBuilder().setLgxDeviceName("LGX Panel_SNJSCAMCJW1_000000.00_00").setLgxPortName("LGX_Back.6") + .setLgxPortRack("000000.00").setLgxPortShelf("00").build(); + RxDirection rxDirection = new RxDirectionBuilder().setPort(rxPort).setLgx(rxLgx).build(); + + IntermediateSites inter = new IntermediateSitesBuilder().setClli("SNJSCAMCJW1").setServiceRate((long) 100) + .setServiceFormat(ServiceFormat.Ethernet).setOpticType(OpticTypes.Gray).setTxDirection(txDirection) + .setRxDirection(rxDirection).build(); + + List intersites = new ArrayList(); + intersites.add(inter); + ServiceFeasibilityCheckOutput output = new ServiceFeasibilityCheckOutputBuilder() + .setIntermediateSites(intersites).setResponseParameters(responseParameters) + .setConfigurationResponseCommon(configurationResponseCommon).setServiceAEnd(serviceAEnd) + .setServiceZEnd(serviceZEnd).build(); + + return RpcResultBuilder.success(output).buildFuture(); + } + + @Override + public Future> serviceReconfigure(ServiceReconfigureInput input) { + + LOG.info("RPC service reconfigure received"); + notificationUrl = null;// input.getnotificationUrl(); + boolean commonId = true; + boolean coherencyHardSoft = false; + ServiceRpcResult notification = null; + + String message = ""; + LOG.info("checking Service Compliancy ..."); + /* + * Upon receipt of service-create RPC, service header and sdnc-request + * header compliancy are verified. + */ + compliancyCheck = new ServicehandlerCompliancyCheck(input.getServiceName(), input.getConnectionType(), + RpcActions.ServiceReconfigure); + if (compliancyCheck.check(true, false)) { + LOG.info("Service compliant !"); + /* + * If compliant, service-request parameters are verified in order to + * check if there is no missing parameter that prevents calculating + * a path and implement a service. + */ + LOG.info("checking Tx/Rx Info for AEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceAEnd(), 1); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for AEnd checked !"); + LOG.info("checking Tx/Rx Info for ZEnd ..."); + txrxCheck = new ServicehandlerTxRxCheck(input.getServiceZEnd(), 2); + if (txrxCheck.check()) { + LOG.info("Tx/Rx Info for ZEnd checked"); + /* + * If OK, common-id is verified in order to see if there is + * no routing policy provided. If yes, the routing + * constraints of the policy are recovered and coherency + * with hard/soft constraints provided in the input of the + * RPC. + */ + if (input.getCommonId() != null) { + LOG.info("Common-id specified"); + /* + * Check coherency with hard/soft constraints + */ + + checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(), + input.getSoftConstraints()); + if (checkCoherencyHardSoft.check()) { + LOG.info("hard/soft constraints coherent !"); + coherencyHardSoft = true; + } else { + LOG.info("hard/soft constraints are not coherent !"); + message = "hard/soft constraints are not coherent !"; + } + } else { + commonId = false; + } + + if (!commonId || (commonId && coherencyHardSoft)) { + /* + * Retrieving initial service topology. + */ + String serviceName = input.getServiceName(); + Services service = readServiceList(serviceName); + if (service != null) { + LOG.debug("Service '" + serviceName + "' present in datastore !"); + /* + * Sending cancel resource resv request to PCE + */ + + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, input, false); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Cancelling ResourceResv ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + FutureCallback pceCallback = + new FutureCallback() { + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + + @Override + public void onFailure(Throwable arg0) { + LOG.error("Failed to cancel ResourceResv ! "); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(serviceName).setStatus(RpcStatusEx.Failed) + .setStatusMessage("PCR Request failed !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + } + + @Override + public void onSuccess(CancelResourceReserveOutput arg0) { + if (mappingAndSendingPCRequest.getSuccess() && arg0 != null) { + LOG.info("Service ResourceResv cancelled !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage( + "Service '" + serviceName + "' ResourceResv cancelled") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + message = "Service '" + serviceName + "' ResourceResv cancelled"; + + LOG.info("PCE replied to CancelResourceResv Request !"); + /* + * Before sending the PCE request, input + * data need to be formatted according + * to the Service Handler - PCE + * interface data model. + */ + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, input, + true); + /* + * Once PCE request is being sent to the + * PCE on interface B, PCE reply is + * expected until a timer expires. + */ + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(serviceName).setStatus(RpcStatusEx.Pending) + .setStatusMessage(message + ", submitting PathComputation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + PathComputationRequestOutput response = null; + try { + response = mappingAndSendingPCRequest.pathComputationRequest().get(); + } catch (InterruptedException | ExecutionException e2) { + LOG.error(e2.getMessage()); + } + + if (mappingAndSendingPCRequest.getSuccess() && response != null) { + /* + * If PCE reply is received before + * timer expiration with a positive + * result, a service is created with + * admin and operational status + * 'down'. + */ + LOG.info("PCE replied to PCR Request !"); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(serviceName).setStatus(RpcStatusEx.Pending) + .setStatusMessage("PCE replied to PCR Request !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + /* + * Send Implementation order to + * renderer + */ + mappingAndSendingSIRequest = new MappingAndSendingSIRequest(rpcRegistry, + input, response); + + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Submitting ServiceImplementation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + ServiceImplementationRequestOutput siOutput = null; + try { + siOutput = mappingAndSendingSIRequest.serviceImplementation().get(); + } catch (InterruptedException | ExecutionException e2) { + LOG.error(e2.getMessage()); + } + ConfigurationResponseCommon siCommon = siOutput + .getConfigurationResponseCommon(); + message = siCommon.getResponseMessage(); + + if (mappingAndSendingSIRequest.getSuccess() && siOutput != null) { + message = "Service reconfigured "; + LOG.info("Service reconfigured !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service reconfigure !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + /* + * Service implemented Update in + * DB. + */ + Boolean update = false; + Boolean delete = false; + Services modifService = mappingServices(null, input, response); + InstanceIdentifier iid = InstanceIdentifier + .create(ServiceList.class) + .child(Services.class, new ServicesKey(serviceName)); + WriteTransaction writeTx = db.newWriteOnlyTransaction(); + writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid); + try { + LOG.info("Deleting service info ..."); + writeTx.submit().checkedGet(); + delete = true; + } catch (TransactionCommitFailedException e) { + LOG.error("Failed to delete service from Service List"); + } + if (delete) { + iid = InstanceIdentifier.create(ServiceList.class).child( + Services.class, new ServicesKey(input.getNewServiceName())); + writeTx = db.newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, modifService); + try { + LOG.info("Updating service info ..."); + writeTx.submit().checkedGet(); + update = true; + } catch (TransactionCommitFailedException e) { + LOG.error("Failed to modify service from Service List"); + } + } + if (update) { + LOG.info("Service '" + serviceName + "' updated with new name '" + + input.getNewServiceName() + "' ! "); + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" : Service updated on DataBase !"); + message = build.toString(); + } else { + LOG.info("Service '" + serviceName + "' update failed ! "); + StringBuilder build = new StringBuilder(); + build.append(message); + build.append(" : Failed to modify service from Service List "); + message = build.toString(); + } + } else { + LOG.info("Service not implemented !"); + message = response.getConfigurationResponseCommon() + .getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage( + "Service not implemented, cancelling ResourceResv") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, + input, false); + /* + * Send Cancel resource Request + * to PCE. + */ + CancelResourceReserveOutput cancelOuptut = null; + try { + cancelOuptut = mappingAndSendingPCRequest.cancelResourceReserve() + .get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error(e1.getMessage()); + } + if (mappingAndSendingPCRequest.getSuccess() && cancelOuptut != null) { + LOG.info("Service ResourceResv cancelled !"); + message = response.getConfigurationResponseCommon() + .getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage("Service ResourceResv cancelled").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + message = cancelOuptut.getConfigurationResponseCommon() + .getResponseMessage(); + + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + + LOG.info("PCE replied to CancelResourceResv Request !"); + } else { + message = "Cancelling Resource reserved failed "; + LOG.info(message); + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + + message = response.getConfigurationResponseCommon() + .getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage("Cancelling Resource reserved failed") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + } + + } else { + LOG.error("PCE pathcomputation request failed !"); + message = "PCE pathcomputation request failed : " + + mappingAndSendingPCRequest.getError();// "Path + // not + // calculated"; + } + } else { + message = "Cancelling Resource reserved failed "; + LOG.info(message); + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceReconfigureResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("Cancelling Resource reserved failed").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + + } + }; + ListenableFuture pce = mappingAndSendingPCRequest + .cancelResourceReserve(); + Futures.addCallback(pce, pceCallback); + LOG.info("CancelResRev Request in progress "); + ServiceReconfigureOutput output = new ServiceReconfigureOutputBuilder() + .setStatus(RpcStatusEx.Pending).setStatusMessage(message).build(); + + return RpcResultBuilder.success(output).buildFuture(); + + } else { + message = "Service '" + serviceName + "' not exists in datastore"; + LOG.error(message); + } + } + } else { + message = txrxCheck.getMessage(); + } + } else { + message = txrxCheck.getMessage(); + } + } else { + message = compliancyCheck.getMessage(); + } + + ServiceReconfigureOutput output = new ServiceReconfigureOutputBuilder().setStatus(RpcStatusEx.Successful) + .setStatusMessage(message).build(); + + return RpcResultBuilder.success(output).buildFuture(); + } + + @Override + public Future> serviceRestoration(ServiceRestorationInput input) { + LOG.info("RPC service restoration received"); + ServiceRpcResult notification = null; + notificationUrl = null;// input.getnotificationUrl(); + String message = ""; + LOG.info("checking Service Compliancy ..."); + compliancyCheck = new ServicehandlerCompliancyCheck(input.getServiceName(), RpcActions.ServiceRestoration); + if (compliancyCheck.check(false, false)) { + LOG.info("Service compliant !"); + /* + * If compliant, Getting path from service DB. + */ + + String serviceName = input.getServiceName(); + Services service = readServiceList(serviceName); + if (service != null) { + LOG.debug("Service '" + serviceName + "' present in datastore !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service '" + serviceName + "' present in datastore, deleting service ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + /* + * Sending delete order to renderer + */ + mappingAndSendingSIRequest = new MappingAndSendingSIRequest(rpcRegistry, null, input.getServiceName()); + + ListenableFuture renderer = + mappingAndSendingSIRequest.serviceDelete(); + FutureCallback rendererCallback = + new FutureCallback() { + String message = ""; + String responseCode = ""; + ServiceRpcResult notification = null; + + @Override + public void onFailure(Throwable arg0) { + LOG.error("ServiceDelete Request failed !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(serviceName).setStatus(RpcStatusEx.Failed) + .setStatusMessage("ServiceDelete Request failed !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + + @Override + public void onSuccess(org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce + .stubrenderer.rev170426.ServiceDeleteOutput arg0) { + if (arg0 != null) { + message = arg0.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service deleted !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, service, true); + /* + * Once PCE request is being sent to the PCE on + * interface B, PCE reply is expected until a timer + * expires. + */ + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service deleted, submitting PathComputation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + PathComputationRequestOutput response = null; + try { + response = mappingAndSendingPCRequest.pathComputationRequest().get(); + } catch (InterruptedException | ExecutionException e2) { + LOG.error(e2.getMessage()); + } + + if (mappingAndSendingPCRequest.getSuccess() && response != null) { + /* + * If PCE reply is received before timer + * expiration with a positive result, a service + * is created with admin and operational status + * 'down'. + */ + LOG.info("Path calculated !"); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Path calculated, modifying Service Admin / Op ...").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + /* + * creating Service with Admin / Op to down. + * + */ + + ServicesBuilder serviceRestoration = new ServicesBuilder(service) + .setAdministrativeState(State.OutOfService) + .setOperationalState(State.OutOfService) + .setLifecycleState(LifecycleState.Planned); + + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .service.types.rev170426.response + .parameters.sp.ResponseParameters responseParameters = + response.getResponseParameters(); + if (responseParameters != null) { + // serviceRestoration.setPceMetric(responseParameters.getPceMetric()); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .service.types.rev170426.response.parameters.sp.response + .parameters.PathDescription pathDescription = + responseParameters.getPathDescription(); + if (pathDescription != null) { + List atozList = new ArrayList(); + List ztoaList = new ArrayList(); + + for (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .pathdescription.rev170426.path.description.atoz.direction.AToZ + tmp : pathDescription.getAToZDirection().getAToZ()) { + + AToZKey key = new AToZKey(tmp.getKey().getId()); + tmp.getResource().getResource(); + AToZ atoz = new AToZBuilder().setId(tmp.getId()).setKey(key) + // .setResource(tmp.getResource()) + .build(); + atozList.add(atoz); + } + + for (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface + .pathdescription.rev170426.path.description.ztoa.direction.ZToA + tmp : pathDescription.getZToADirection().getZToA()) { + ZToAKey key = new ZToAKey(tmp.getKey().getId()); + ZToA ztoa = new ZToABuilder().setId(tmp.getId()).setKey(key) + // .setResource(tmp.getResource()) + .build(); + ztoaList.add(ztoa); + } + Topology topology = new TopologyBuilder().setAToZ(atozList).setZToA(ztoaList) + .build(); + serviceRestoration.setTopology(topology); + } + } + Boolean update = false; + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class) + .child(Services.class, new ServicesKey(serviceName)); + WriteTransaction writeTx = db.newWriteOnlyTransaction(); + writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, service); + + try { + writeTx.submit().checkedGet(); + update = true; + } catch (TransactionCommitFailedException e) { + LOG.error("Failed to modify service from Service List"); + } + if (update) { + LOG.info("Service modified !"); + /* + * Send Implementation order to renderer + */ + mappingAndSendingSIRequest = new MappingAndSendingSIRequest(rpcRegistry, service); + + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage( + "Service modified, submitting ServiceImplementation Request") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + + ServiceImplementationRequestOutput siOutput = null; + try { + siOutput = mappingAndSendingSIRequest.serviceImplementation().get(); + } catch (InterruptedException | ExecutionException e2) { + LOG.error(e2.getMessage()); + } + if (mappingAndSendingSIRequest.getSuccess() && siOutput != null) { + ConfigurationResponseCommon siCommon = siOutput + .getConfigurationResponseCommon(); + message = siCommon.getResponseMessage(); + LOG.info("Service restored !"); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service restored !").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + /* + * Service implemented setting Service + * op status to up + */ + if (writeOrModifyOrDeleteServiceList(serviceName, null, null, 0) == null) { + message = "Service restored : Service Op Status changed to Up !"; + } else { + message = "Service restored : " + + "but Failed to modify service from Service List !"; + } + } else { + LOG.info("Service not restored !"); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed) + .setStatusMessage("Service not restored, cancelling ResourceResv ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + mappingAndSendingPCRequest = new MappingAndSendingPCRequest(rpcRegistry, + service, false); + /* + * Send Cancel resource Request to PCE. + */ + CancelResourceReserveOutput cancelOuptut = null; + try { + cancelOuptut = mappingAndSendingPCRequest.cancelResourceReserve().get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error(e1.getMessage()); + } + if (mappingAndSendingPCRequest.getSuccess() && cancelOuptut != null) { + LOG.info("Service ResourceResv cancelled !"); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType( + ServiceNotificationTypes.ServiceRestorationResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service ResourceResv cancelled").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + message = cancelOuptut.getConfigurationResponseCommon() + .getResponseMessage(); + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + LOG.info("PCE replied to CancelResourceResv Request !"); + } else { + message = "Cancelling Resource reserved failed "; + LOG.info(message); + StringBuilder build = new StringBuilder(); + build.append("Service not implemented - "); + build.append(message); + message = build.toString(); + message = response.getConfigurationResponseCommon().getResponseMessage(); + notification = new ServiceRpcResultBuilder() + .setNotificationType(ServiceNotificationTypes.ServiceCreateResult) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Failed) + .setStatusMessage("Cancelling Resource reserved failed").build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + sendNotifToUrl(notification, notificationUrl); + } + } + } else { + LOG.error("Failed to modify service from service list !"); + } + } else { + message = mappingAndSendingPCRequest.getError(); + /* Path not calculated. */ + LOG.error("Path Computation request failed : " + message); + } + } else { + message = "deleting service failed"; + LOG.error(message); + } + } + }; + Futures.addCallback(renderer, rendererCallback); + ServiceRestorationOutput output = new ServiceRestorationOutputBuilder().setStatus(RpcStatusEx.Pending) + .setStatusMessage(message).build(); + + return RpcResultBuilder.success(output).buildFuture(); + + } else { + message = "Service '" + serviceName + "' not exists in datastore"; + LOG.error(message); + } + + } else { + message = compliancyCheck.getMessage(); + LOG.error(message); + } + + ServiceRestorationOutput output = new ServiceRestorationOutputBuilder().setStatus(RpcStatusEx.Successful) + .setStatusMessage(message).build(); + + return RpcResultBuilder.success(output).buildFuture(); + } + + /* + * Initialize ServiceList Structure on Datastore. + * + * @param DataBroker + * Access Datastore + */ + private void initializeDataTree(DataBroker db) { + LOG.info("Preparing to initialize the greeting registry"); + WriteTransaction transaction = db.newWriteOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class); + ServiceList greetingRegistry = new ServiceListBuilder().build(); + transaction.put(LogicalDatastoreType.OPERATIONAL, iid, greetingRegistry); + CheckedFuture future = transaction.submit(); + Futures.addCallback(future, new LoggingFuturesCallBack<>("Failed to create Service List", LOG)); + } + + /* + * Map Input (ServiceCreateInmput, ServiceReconfigureInput) & output + * (PathComputationRequestOutput) to Service. + * + * @param serviceCreateInput + * ServiceCreateInput parameter + * @param serviceReconfigureInput + * serviceReconfigureInput parameter + * @param output + * PathComputationRequestOutput parameter + * + * @return Services Service data + */ + private Services mappingServices(ServiceCreateInput serviceCreateInput, + ServiceReconfigureInput serviceReconfigureInput, PathComputationRequestOutput output) { + LOG.info("Mapping informations to Services"); + ServiceAEnd aend = null; + ServiceZEnd zend = null; + ServicesBuilder service = new ServicesBuilder(); + if (serviceCreateInput != null) { + aend = new ServiceAEndBuilder(serviceCreateInput.getServiceAEnd()).build(); + zend = new ServiceZEndBuilder(serviceCreateInput.getServiceZEnd()).build(); + service.setServiceName(serviceCreateInput.getServiceName()).setAdministrativeState(State.OutOfService) + .setOperationalState(State.OutOfService).setCommonId(serviceCreateInput.getCommonId()) + .setConnectionType(serviceCreateInput.getConnectionType()) + .setCustomer(serviceCreateInput.getCustomer()) + .setCustomerContact(serviceCreateInput.getCustomerContact()) + .setHardConstraints(serviceCreateInput.getHardConstraints()) + .setSoftConstraints(serviceCreateInput.getSoftConstraints()) + .setLifecycleState(LifecycleState.Planned).setServiceAEnd(aend).setServiceZEnd(zend); + + } else if (serviceReconfigureInput != null) { + aend = new ServiceAEndBuilder(serviceReconfigureInput.getServiceAEnd()).build(); + zend = new ServiceZEndBuilder(serviceReconfigureInput.getServiceZEnd()).build(); + service.setServiceName(serviceReconfigureInput.getNewServiceName()) + .setAdministrativeState(State.OutOfService).setOperationalState(State.OutOfService) + .setCommonId(serviceReconfigureInput.getCommonId()) + .setConnectionType(serviceReconfigureInput.getConnectionType()) + .setCustomer(serviceReconfigureInput.getCustomer()) + .setCustomerContact(serviceReconfigureInput.getCustomerContact()) + .setHardConstraints(serviceReconfigureInput.getHardConstraints()) + .setSoftConstraints(serviceReconfigureInput.getSoftConstraints()) + .setLifecycleState(LifecycleState.Planned).setServiceAEnd(aend).setServiceZEnd(zend); + } + + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response + .parameters.sp.ResponseParameters responseParameters = output.getResponseParameters(); + if (responseParameters != null) { + // service.setPceMetric(responseParameters.getPceMetric()); + org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426 + .response.parameters.sp.response.parameters.PathDescription pathDescription = + responseParameters.getPathDescription(); + if (pathDescription != null) { + List atozList = new ArrayList(); + List ztoaList = new ArrayList(); + + for (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426 + .path.description.atoz.direction.AToZ + tmp : pathDescription.getAToZDirection().getAToZ()) { + + AToZKey key = new AToZKey(tmp.getKey().getId()); + AToZ atoz = new AToZBuilder().setId(tmp.getId()).setKey(key) + // .setResource(tmp.getResource()) + .build(); + atozList.add(atoz); + } + + for (org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426 + .path.description.ztoa.direction.ZToA + tmp : pathDescription.getZToADirection().getZToA()) { + ZToAKey key = new ZToAKey(tmp.getKey().getId()); + ZToA ztoa = new ZToABuilder().setId(tmp.getId()).setKey(key) + // .setResource(tmp.getResource()) + .build(); + ztoaList.add(ztoa); + } + + Topology topology = new TopologyBuilder().setAToZ(atozList).setZToA(ztoaList).build(); + service.setTopology(topology); + } + } + return service.build(); + } + + /* + * read Service from ServiceList DataStore. + * + * @param serviceName + * Name of Service + * + * @return Services + */ + private Services readServiceList(String serviceName) { + Services result = null; + ReadOnlyTransaction readTx = db.newReadOnlyTransaction(); + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class).child(Services.class, + new ServicesKey(serviceName)); + CheckedFuture, ReadFailedException> future = readTx.read(LogicalDatastoreType.OPERATIONAL, + iid); + Optional optional = Optional.absent(); + try { + optional = future.checkedGet(); + } catch (ReadFailedException e) { + LOG.error("Reading service failed:", e); + } + if (optional.isPresent()) { + LOG.debug("Service '" + serviceName + "' present !"); + result = new ServicesBuilder(optional.get()).build(); + } + return result; + } + + /* + * Write or Modify or Delete Service from/to SreviceList. + * + * @param serviceName + * Name of service + * @param input + * ServiceCreateInput + * @param output + * PathComputationRequestOutput + * @param choice + * 0 - Modify 1 - Delete 2 - Write + * @return String operations result, null if ok or not otherwise + */ + private String writeOrModifyOrDeleteServiceList(String serviceName, ServiceCreateInput input, + PathComputationRequestOutput output, int choice) { + LOG.debug("WriteOrModifyOrDeleting '" + serviceName + "' Service"); + WriteTransaction writeTx = db.newWriteOnlyTransaction(); + String result = null; + Services readService = readServiceList(serviceName); + if (readService != null) { + /* + * Modify / Delete Service. + */ + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class).child(Services.class, + new ServicesKey(serviceName)); + ServicesBuilder service = new ServicesBuilder(readService); + + String action = null; + switch (choice) { + case 0: /* Modify. */ + LOG.debug("Modifying '" + serviceName + "' Service"); + service.setOperationalState(State.InService).setAdministrativeState(State.InService); + writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, service.build()); + action = "modify"; + break; + + case 1: /* Delete */ + LOG.debug("Deleting '" + serviceName + "' Service"); + writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid); + action = "delete"; + break; + + default: + LOG.debug("No choice found"); + break; + + } + try { + writeTx.submit().checkedGet(); + } catch (TransactionCommitFailedException e) { + LOG.error("Failed to " + action + " service from Service List"); + result = "Failed to " + action + " service from Service List"; + } + } else { + if (choice == 2) { /* Write Service */ + LOG.debug("Writing '" + serviceName + "' Service"); + InstanceIdentifier iid = InstanceIdentifier.create(ServiceList.class).child(Services.class, + new ServicesKey(serviceName)); + + Services service = mappingServices(input, null, output); + writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service); + try { + writeTx.submit().checkedGet(); + result = null; + } catch (TransactionCommitFailedException e) { + LOG.error("Failed to write service to Service List"); + result = "Failed to write service to Service List"; + } + } else { + LOG.info("Service is not present ! "); + result = "Service is not present ! "; + } + } + return result; + } + + private void sendNotifToUrl(ServiceRpcResult notification, String url) { + Gson gson = new GsonBuilder().setPrettyPrinting() + // .serializeNulls() + .create(); + String data = gson.toJson(notification); + URL obj; + try { + obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request header + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "application/json"); + con.setRequestProperty("Accept", "application/json"); + + // Send post request + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(data); + wr.flush(); + wr.close(); + int responseCode = con.getResponseCode(); + LOG.info("Response Code : " + responseCode); + } catch (IOException e) { + LOG.error("IOException : " + e.toString()); + } + + } + + @Override + public void close() throws Exception { + executor.shutdown(); + } + + @Override + public Future> equipmentNotification(EquipmentNotificationInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> serviceRerouteConfirm(ServiceRerouteConfirmInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> serviceReroute(ServiceRerouteInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> serviceReversion(ServiceReversionInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> serviceRoll(ServiceRollInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> networkReOptimization(NetworkReOptimizationInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> tempServiceDelete(TempServiceDeleteInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Future> tempServiceCreate(TempServiceCreateInput input) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void onServiceRpcResultSp(ServiceRpcResultSp notification) { + if (!compareServiceRpcResultSp(notification)) { + serviceRpcResultSp = notification; + StringBuilder build = new StringBuilder(); + build.append( + "Received '" + notification.getNotificationType() + "' StubRenderer notification" + "from service '" + + notification.getServiceName() + "' " + "with status '" + notification.getStatus() + "'"); + build.append(" with StatusMessage '" + notification.getStatusMessage() + "'"); + if (notification.getStatus() == RpcStatusEx.Successful && notification.getNotificationType() + .getIntValue() == ServicePathNotificationTypes.ServiceImplementationRequest.getIntValue()) { + build.append(" PathTopology : " + notification.getPathTopology().toString()); + } + LOG.info(build.toString()); + } else { + LOG.info("ServicePathRpcResult already wired !"); + } + + } + + @Override + public void onServicePathRpcResult(ServicePathRpcResult notification) { + if (!compareServicePathRpcResult(notification)) { + servicePathRpcResult = notification; + StringBuilder build = new StringBuilder(); + build.append( + "Received '" + notification.getNotificationType() + "' StubPce notification " + "from service '" + + notification.getServiceName() + "' " + "with status '" + notification.getStatus() + "'"); + build.append(" with StatusMessage '" + notification.getStatusMessage() + "'"); + if (notification.getStatus() == RpcStatusEx.Successful && notification.getNotificationType() + .getIntValue() == ServicePathNotificationTypes.PathComputationRequest.getIntValue()) { + build.append(" PathDescription : " + notification.getPathDescription().toString()); + /* + * switch (action.getIntValue()) { case 1: //service-create case + * 3: //service-delete case 8: //service-reconfigure case 9: + * //service-restoration case 10://service-reversion case + * 11://service-reroute break; + * + * default: break; } + */ + } + + LOG.info(build.toString()); + } else { + LOG.info("ServicePathRpcResult already wired !"); + } + } + + public RpcActions getAction() { + return action; + } + + public void setAction(RpcActions action) { + this.action = action; + } + + public Boolean compareServicePathRpcResult(ServicePathRpcResult notification) { + Boolean result = true; + if (servicePathRpcResult == null) { + result = false; + } else { + if (servicePathRpcResult.getNotificationType() != notification.getNotificationType()) { + result = false; + } + if (servicePathRpcResult.getServiceName() != notification.getServiceName()) { + result = false; + } + if (servicePathRpcResult.getStatus() != notification.getStatus()) { + result = false; + } + if (servicePathRpcResult.getStatusMessage() != notification.getStatusMessage()) { + result = false; + } + } + return result; + } + + public Boolean compareServiceRpcResultSp(ServiceRpcResultSp notification) { + Boolean result = true; + if (serviceRpcResultSp == null) { + result = false; + } else { + if (serviceRpcResultSp.getNotificationType() != notification.getNotificationType()) { + result = false; + } + if (serviceRpcResultSp.getServiceName() != notification.getServiceName()) { + result = false; + } + if (serviceRpcResultSp.getStatus() != notification.getStatus()) { + result = false; + } + if (serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) { + result = false; + } + } + return result; + } +} diff --git a/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerProvider.java b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerProvider.java new file mode 100644 index 000000000..32929b9a4 --- /dev/null +++ b/servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerProvider.java @@ -0,0 +1,74 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.servicehandler.impl; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.NotificationService; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.servicehandler.rev161014.ServicehandlerService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceListener; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererListener; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class to register + * Servicehandler Service and Notification. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class ServicehandlerProvider { + + private static final Logger LOG = LoggerFactory.getLogger(ServicehandlerProvider.class); + + private final DataBroker dataBroker; + private final RpcProviderRegistry rpcRegistry; + private final NotificationService notificationService; + private final NotificationPublishService notificationPublishService; + + //private ListenerRegistration ServicehandlerlistenerRegistration; + /* Listener register for StubPce Notification. */ + private ListenerRegistration stubPcelistenerRegistration; + /* Listener register for StubRender Notification. */ + private ListenerRegistration stubRendererlistenerRegistration; + private RpcRegistration rpcRegistration; + + + public ServicehandlerProvider(final DataBroker dataBroker, RpcProviderRegistry rpcProviderRegistry, + NotificationService notificationService, NotificationPublishService notificationPublishService) { + this.dataBroker = dataBroker; + this.rpcRegistry = rpcProviderRegistry; + this.notificationService = notificationService; + this.notificationPublishService = notificationPublishService; + } + + /* + * Method called when the blueprint container is created. + */ + public void init() { + LOG.info("ServicehandlerProvider Session Initiated"); + final ServicehandlerImpl consumer = new ServicehandlerImpl(dataBroker, rpcRegistry, notificationPublishService); + stubPcelistenerRegistration = notificationService.registerNotificationListener(consumer); + stubRendererlistenerRegistration = notificationService.registerNotificationListener(consumer); + rpcRegistration = rpcRegistry.addRpcImplementation(ServicehandlerService.class, consumer); + } + + /* + * Method called when the blueprint container is destroyed. + */ + public void close() { + LOG.info("ServicehandlerProvider Closed"); + stubPcelistenerRegistration.close(); + stubRendererlistenerRegistration.close(); + rpcRegistration.close(); + } +} diff --git a/servicehandler/src/main/resources/org/opendaylight/blueprint/Servicehandler-blueprint.xml b/servicehandler/src/main/resources/org/opendaylight/blueprint/Servicehandler-blueprint.xml new file mode 100644 index 000000000..5f781321d --- /dev/null +++ b/servicehandler/src/main/resources/org/opendaylight/blueprint/Servicehandler-blueprint.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/stubpce/pom.xml b/stubpce/pom.xml new file mode 100644 index 000000000..fe56b0943 --- /dev/null +++ b/stubpce/pom.xml @@ -0,0 +1,54 @@ + + + + + + 4.0.0 + + + org.opendaylight.controller + config-parent + 0.6.0-SNAPSHOT + + + + org.opendaylight.transportpce + transportpce-stubpce + 0.1.0-SNAPSHOT + bundle + + + + ${project.groupId} + transportpce-api + ${project.version} + + + ${project.groupId} + transportpce-ordmodels + ${project.version} + + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + diff --git a/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java new file mode 100644 index 000000000..023c2b4e9 --- /dev/null +++ b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java @@ -0,0 +1,80 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubpce; + +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/* + * Class to check RPCs Compliancy. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class CompliancyCheck { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(CompliancyCheck.class); + /* Response message from procedure. */ + private String message; + + private PathComputationRequestInput input; + + public CompliancyCheck(PathComputationRequestInput prcInput) { + input = prcInput; + } + + /* + * Check if a String is not + * null and not equal to ''. + * + * @param value String value + * @return true if String ok + * false if not + */ + public Boolean checkString(String value) { + Boolean result = false; + if ((value != null) && (value.compareTo("") != 0)) { + result = true; + } + return result; + + } + + public Boolean check() { + Boolean result = true; + if (input != null) { + if (!checkString(input.getServiceName())) { + result = false; + message = "Service Name is not set"; + LOG.debug(message); + } else { + if (!checkString(input.getServiceHandlerHeader().getRequestId())) { + result = false; + message = "ServiceHandlerHeader Request-ID is not set"; + LOG.debug(message); + } + } + } else { + result = false; + } + return result; + } + + public String getMessage() { + return message; + } + + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java new file mode 100644 index 000000000..9a710c6e6 --- /dev/null +++ b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java @@ -0,0 +1,275 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubpce; + +import java.util.ArrayList; +import java.util.List; + +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.NodeBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class for Sending + * PCE requests : + * - path-computation-request + * - cancel-resource-reserve. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class SendingPceRPCs { + + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(SendingPceRPCs.class); + /* define procedure success (or not ). */ + private Boolean success; + /* define type of request
+ * true pathcomputation
+ * false cancelresourcereserve .*/ + private AToZDirection atozdirection; + private ZToADirection ztoadirection; + private PathDescriptionBuilder pathDescription; + + + public SendingPceRPCs() { + success = true; + atozdirection = null; + ztoadirection = null; + setPathDescription(null); + } + + public void cancelResourceReserve() { + LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request"); + try { + Thread.sleep(10000); //sleep for 10s + } catch (InterruptedException e) { + LOG.error(e.toString()); + } + LOG.info("cancelResourceReserve ..."); + } + + public void pathComputation() { + LOG.info("Wait for 10s til beginning the PCE pathComputation request"); + try { + Thread.sleep(10000); //sleep for 10s + } catch (InterruptedException e) { + LOG.error(e.toString()); + } + LOG.info("PathComputation ..."); + buildAToZ(); + buildZToA(); + + setPathDescription(new PathDescriptionBuilder() + .setAToZDirection(atozdirection) + .setZToADirection(ztoadirection)); + } + + public void buildAToZ() { + Link atoB = new LinkBuilder() + .setLinkId("AtoB") + .build(); + Link btoZ = new LinkBuilder() + .setLinkId("BtoZ") + .build(); + + Node roadmA = new NodeBuilder() + .setNodeId("RoadmA") + .build(); + Node roadmB = new NodeBuilder() + .setNodeId("RoadmB") + .build(); + Node roadmZ = new NodeBuilder() + .setNodeId("RoadmZ") + .build(); + + /*A -> Z*/ + /*RoadmA*/ + AToZKey roadmAKey = new AToZKey("RoadmA"); + Resource roadmAResource = new ResourceBuilder() + .setResource(roadmA) + .build(); + AToZ atoz = new AToZBuilder() + .setId("RoadmA") + .setKey(roadmAKey) + .setResource(roadmAResource) + .build(); + /*Link AtoB*/ + AToZKey atoBKey = new AToZKey("AtoB"); + Resource atozResource = new ResourceBuilder() + .setResource(atoB) + .build(); + AToZ atob = new AToZBuilder() + .setId("AtoB") + .setKey(atoBKey) + .setResource(atozResource) + .build(); + /*RoadmB*/ + AToZKey roadmBKey = new AToZKey("RoadmB"); + Resource roadmBResource = new ResourceBuilder() + .setResource(roadmB) + .build(); + AToZ roadmb = new AToZBuilder() + .setId("RoadmB") + .setKey(roadmBKey) + .setResource(roadmBResource) + .build(); + /*Link BtoZ*/ + AToZKey btoZKey = new AToZKey("BtoZ"); + Resource botzResource = new ResourceBuilder() + .setResource(btoZ) + .build(); + AToZ btoz = new AToZBuilder() + .setId("BtoZ") + .setKey(btoZKey) + .setResource(botzResource) + .build(); + /*RoadmZ*/ + AToZKey roadmZKey = new AToZKey("RoadmZ"); + Resource roadmZResource = new ResourceBuilder() + .setResource(roadmZ) + .build(); + AToZ roadmz = new AToZBuilder() + .setId("RoadmZ") + .setKey(roadmZKey) + .setResource(roadmZResource) + .build(); + + List atozList = new ArrayList(); + atozList.add(atoz); + atozList.add(atob); + atozList.add(roadmb); + atozList.add(btoz); + atozList.add(roadmz); + + atozdirection = new AToZDirectionBuilder() + .setRate((long)100) + .setAToZWavelengthNumber((long)200) + .setAToZ(atozList) + .build(); + } + + public void buildZToA() { + + Link btoA = new LinkBuilder() + .setLinkId("BtoA") + .build(); + Link ztoB = new LinkBuilder() + .setLinkId("ZtoB") + .build(); + + Node roadmA = new NodeBuilder() + .setNodeId("RoadmA") + .build(); + Node roadmB = new NodeBuilder() + .setNodeId("RoadmB") + .build(); + Node roadmZ = new NodeBuilder() + .setNodeId("RoadmZ") + .build(); + + /*Z -> A*/ + /*RoadmZ*/ + ZToAKey roadmZKey = new ZToAKey("RoadmZ"); + Resource roadmZResource = new ResourceBuilder() + .setResource(roadmZ) + .build(); + ZToA ztoa = new ZToABuilder() + .setId("RoadmZ") + .setKey(roadmZKey) + .setResource(roadmZResource) + .build(); + /*Link ZtoB*/ + ZToAKey ztoBKey = new ZToAKey("ZtoB"); + Resource ztoBResource = new ResourceBuilder() + .setResource(ztoB) + .build(); + ZToA ztob = new ZToABuilder() + .setId("ZtoB") + .setKey(ztoBKey) + .setResource(ztoBResource) + .build(); + /*RoadmB*/ + ZToAKey roadmBKey = new ZToAKey("RoadmB"); + Resource roadmBResource = new ResourceBuilder() + .setResource(roadmB) + .build(); + ZToA roadmb = new ZToABuilder() + .setId("RoadmB") + .setKey(roadmBKey) + .setResource(roadmBResource) + .build(); + /*Link BtoA*/ + ZToAKey btoAKey = new ZToAKey("BtoA"); + Resource btoAResource = new ResourceBuilder() + .setResource(btoA) + .build(); + ZToA btoa = new ZToABuilder() + .setId("BtoA") + .setKey(btoAKey) + .setResource(btoAResource) + .build(); + /* RoadmA*/ + ZToAKey roadmAKey = new ZToAKey("RoadmA"); + Resource roadmAResource = new ResourceBuilder() + .setResource(roadmA) + .build(); + ZToA roadma = new ZToABuilder() + .setId("RoadmA") + .setKey(roadmAKey) + .setResource(roadmAResource) + .build(); + + List ztoaList = new ArrayList(); + ztoaList.add(ztoa); + ztoaList.add(ztob); + ztoaList.add(roadmb); + ztoaList.add(btoa); + ztoaList.add(roadma); + + ztoadirection = new ZToADirectionBuilder() + .setRate((long)100) + .setZToAWavelengthNumber((long)100) + .setZToA(ztoaList) + .build(); + } + + public PathDescriptionBuilder getPathDescription() { + return pathDescription; + } + + public void setPathDescription(PathDescriptionBuilder pathDescription) { + this.pathDescription = pathDescription; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + +} diff --git a/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java new file mode 100644 index 000000000..558b56610 --- /dev/null +++ b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubpce.impl; + +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.transportpce.stubpce.CompliancyCheck; +import org.opendaylight.transportpce.stubpce.SendingPceRPCs; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResult; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResultBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.rpc.result.PathDescription; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/* + * Class to implement + * StubpceService + * StubpceListener. + * + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ + +public class StubpceImpl implements StubpceService { + + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(StubpceImpl.class); + + private CompliancyCheck compliancyCheck; + /* send notification. */ + private NotificationPublishService notificationPublishService; + private ServicePathRpcResult notification; + + public StubpceImpl(NotificationPublishService notificationPublishService) { + this.notificationPublishService = notificationPublishService; + } + + @Override + public Future> cancelResourceReserve(CancelResourceReserveInput input) { + LOG.info("RPC cancelResourceReserve request received"); + String message = ""; + + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting cancelResourceReserve Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + SendingPceRPCs sendingPCE = new SendingPceRPCs(); + sendingPCE.cancelResourceReserve(); + if (sendingPCE.getSuccess()) { + message = "ResourceReserve cancelled ! "; + } else { + message = "Cancelling ResourceReserve failed ! "; + } + LOG.info(message); + ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder(); + configurationResponseCommon + .setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseCode("200") + .setResponseMessage("") + .setResponseMessage(message); + CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder(); + output + .setConfigurationResponseCommon(configurationResponseCommon.build()); + return RpcResultBuilder.success(output.build()).buildFuture(); + } + + + @Override + public Future> pathComputationRequest(PathComputationRequestInput input) { + LOG.info("RPC pathcomputation request received"); + String message = ""; + PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder(); + ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder(); + + compliancyCheck = new CompliancyCheck(input); + if (!compliancyCheck.check()) { + configurationResponseCommon + .setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseCode("Path not calculated") + .setResponseMessage(compliancyCheck.getMessage()); + + output + .setConfigurationResponseCommon(configurationResponseCommon.build()) + .setResponseParameters(null); + + return RpcResultBuilder.success(output.build()).buildFuture(); + } + notification = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting pathComputation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + SendingPceRPCs sendingPCE = new SendingPceRPCs(); + sendingPCE.pathComputation(); + if (sendingPCE.getSuccess()) { + message = "Path Computated !"; + ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder() + .setNotificationType(ServicePathNotificationTypes.PathComputationRequest) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Successful) + .setStatusMessage(message); + PathDescriptionBuilder path = sendingPCE.getPathDescription(); + if (path != null) { + PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce + .stubpce.rev170426.service.path.rpc.result.PathDescriptionBuilder() + .setAToZDirection(path.getAToZDirection()) + .setZToADirection(path.getZToADirection()) + .build(); + tmp.setPathDescription(pathDescription); + } + notification = tmp.build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + } else { + message = "Path Computating failed !"; + } + LOG.info(message); + configurationResponseCommon + .setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseCode("200") + .setResponseMessage(message); + + output + .setConfigurationResponseCommon(configurationResponseCommon.build()); + return RpcResultBuilder.success(output.build()).buildFuture(); + + } +} diff --git a/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java new file mode 100644 index 000000000..a1f216218 --- /dev/null +++ b/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubpce.impl; + +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.NotificationService; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceListener; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * Class to register + * Stubpce Service & Notification. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class StubpceProvider { + private static final Logger LOG = LoggerFactory.getLogger(StubpceProvider.class); + private final RpcProviderRegistry rpcRegistry; + private final NotificationPublishService notificationPublishService; + + + private BindingAwareBroker.RpcRegistration rpcRegistration; + private ListenerRegistration stubPcelistenerRegistration; + + public StubpceProvider(RpcProviderRegistry rpcProviderRegistry, + NotificationService notificationService, + NotificationPublishService notificationPublishService) { + this.rpcRegistry = rpcProviderRegistry; + this.notificationPublishService = notificationPublishService; + } + + /* + * Method called when the blueprint container is created. + */ + public void init() { + LOG.info("StubpceProvider Session Initiated"); + final StubpceImpl consumer = new StubpceImpl(notificationPublishService); + rpcRegistration = rpcRegistry.addRpcImplementation(StubpceService.class, consumer); + } + + /* + * Method called when the blueprint container is destroyed. + */ + public void close() { + LOG.info("StubpceProvider Closed"); + rpcRegistration.close(); + stubPcelistenerRegistration.close(); + } +} diff --git a/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml b/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml new file mode 100644 index 000000000..c585e88cf --- /dev/null +++ b/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + diff --git a/stubrenderer/pom.xml b/stubrenderer/pom.xml new file mode 100644 index 000000000..0b6c9aaeb --- /dev/null +++ b/stubrenderer/pom.xml @@ -0,0 +1,52 @@ + + + + + 4.0.0 + + + org.opendaylight.controller + config-parent + 0.6.0-SNAPSHOT + + + + org.opendaylight.transportpce + transportpce-stubrenderer + 0.1.0-SNAPSHOT + bundle + + + + ${project.groupId} + transportpce-api + ${project.version} + + + ${project.groupId} + transportpce-ordmodels + ${project.version} + + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + diff --git a/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/SendingRendererRPCs.java b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/SendingRendererRPCs.java new file mode 100644 index 000000000..36751b1ca --- /dev/null +++ b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/SendingRendererRPCs.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.transportpce.stubrenderer; + +import java.util.ArrayList; +import java.util.List; + +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.TopologyBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.AToZ; +import org.opendaylight.yang.gen.v1.http.org.openroadm.topology.rev161014.topology.ZToA; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + *Class for Sending + * Renderer requests : + * - Service-implementation-request + * - Service-delete-request. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class SendingRendererRPCs { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(SendingRendererRPCs.class); + /* define procedure success (or not ). */ + private Boolean success; + /* define type of request
+ * true pathcomputation
+ * false cancelresourcereserve. */ + private TopologyBuilder topology; + private List atoz; + private List ztoa; + + public SendingRendererRPCs() { + success = true; + setTopology(null); + } + + private void buildAtoZ() { + atoz = new ArrayList(); + } + + private void buildZtoA() { + ztoa = new ArrayList(); + } + + public void serviceDelete() { + LOG.info("Wait for 10s til beginning the Renderer ServiceDelete request"); + try { + Thread.sleep(10000); //sleep for 10s + } catch (InterruptedException e) { + LOG.error(e.toString()); + } + LOG.info("ServiceDelete ..."); + } + + public void serviceImplementation() { + LOG.info("Wait for 10s til beginning the Renderer serviceImplementation request"); + try { + Thread.sleep(10000); //sleep for 10s + } catch (InterruptedException e) { + LOG.error(e.toString()); + } + LOG.info("serviceImplementation ..."); + buildAtoZ(); + buildZtoA(); + + setTopology(new TopologyBuilder() + .setAToZ(atoz) + .setZToA(ztoa)); + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public TopologyBuilder getTopology() { + return topology; + } + + public void setTopology(TopologyBuilder topo) { + this.topology = topo; + } +} diff --git a/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererImpl.java b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererImpl.java new file mode 100644 index 000000000..aa39144e4 --- /dev/null +++ b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererImpl.java @@ -0,0 +1,161 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubrenderer.impl; + +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.transportpce.stubrenderer.SendingRendererRPCs; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceDeleteOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestInput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestOutput; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceImplementationRequestOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceRpcResultSp; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.ServiceRpcResultSpBuilder; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererService; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.rpc.result.sp.PathTopology; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.service.rpc.result.sp.PathTopologyBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.TopologyBuilder; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx; +import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/* + * Class to implement StubrendererService. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class StubrendererImpl implements StubrendererService { + /* Logging. */ + private static final Logger LOG = LoggerFactory.getLogger(StubrendererImpl.class); + /* send notification. */ + private NotificationPublishService notificationPublishService; + private ServiceRpcResultSp notification; + + public StubrendererImpl(NotificationPublishService notificationPublishService) { + this.notificationPublishService = notificationPublishService; + } + + @Override + public Future> serviceImplementationRequest( + ServiceImplementationRequestInput input) { + String message = ""; + LOG.info("RPC serviceImplementationRequest request received"); + + notification = new ServiceRpcResultSpBuilder() + .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting serviceImplementation Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + SendingRendererRPCs sendingRenderer = new SendingRendererRPCs(); + sendingRenderer.serviceImplementation(); + if (sendingRenderer.getSuccess()) { + message = "Service implemented !"; + ServiceRpcResultSpBuilder tmp = new ServiceRpcResultSpBuilder() + .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Successful) + .setStatusMessage(message); + TopologyBuilder topo = sendingRenderer.getTopology(); + if (topo != null) { + PathTopology path = new PathTopologyBuilder() + .setAToZ(topo.getAToZ()) + .setZToA(topo.getZToA()) + .build(); + tmp.setPathTopology(path); + } + notification = tmp.build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + } else { + message = "Service not implemented !"; + } + LOG.info(message); + ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("Yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseCode("200") + .setResponseMessage(message); + + ServiceImplementationRequestOutput output = new ServiceImplementationRequestOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon.build()) + .build(); + + return RpcResultBuilder.success(output).buildFuture(); + } + + @Override + public Future> serviceDelete(ServiceDeleteInput input) { + String message = ""; + LOG.info("RPC serviceDelete request received"); + + notification = new ServiceRpcResultSpBuilder() + .setNotificationType(ServicePathNotificationTypes.ServiceDelete) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Pending) + .setStatusMessage("Service compliant, submitting ServiceDelete Request ...") + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + + SendingRendererRPCs sendingRenderer = new SendingRendererRPCs(); + sendingRenderer.serviceDelete(); + if (sendingRenderer.getSuccess()) { + message = "Service deleted ! "; + LOG.info(message); + ServiceRpcResultSpBuilder tmp = new ServiceRpcResultSpBuilder() + .setNotificationType(ServicePathNotificationTypes.ServiceDelete) + .setServiceName(input.getServiceName()) + .setStatus(RpcStatusEx.Successful) + .setStatusMessage(message); + notification = tmp.build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.info("notification offer rejected : " + e); + } + } else { + message = "Service not deleted !"; + } + LOG.info(message); + ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder() + .setAckFinalIndicator("yes") + .setRequestId(input.getServiceHandlerHeader().getRequestId()) + .setResponseCode("200") + .setResponseMessage(message); + ServiceDeleteOutput output = new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(configurationResponseCommon.build()) + .build(); + + return RpcResultBuilder.success(output).buildFuture(); + + } +} diff --git a/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererProvider.java b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererProvider.java new file mode 100644 index 000000000..7b5b4c18d --- /dev/null +++ b/stubrenderer/src/main/java/org/opendaylight/transportpce/stubrenderer/impl/StubrendererProvider.java @@ -0,0 +1,60 @@ +/* + * Copyright © 2017 Orange, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.transportpce.stubrenderer.impl; + +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.NotificationService; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererListener; +import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubrenderer.rev170426.StubrendererService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + *Class to register Stubrenderer Service & Notification. + * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange + * + */ +public class StubrendererProvider { + private static final Logger LOG = LoggerFactory.getLogger(StubrendererProvider.class); + private final RpcProviderRegistry rpcRegistry; + private final NotificationPublishService notificationPublishService; + + + private BindingAwareBroker.RpcRegistration rpcRegistration; + private ListenerRegistration stubRendererlistenerRegistration; + + public StubrendererProvider(RpcProviderRegistry rpcProviderRegistry, + NotificationService notificationService, + NotificationPublishService notificationPublishService) { + this.rpcRegistry = rpcProviderRegistry; + this.notificationPublishService = notificationPublishService; + } + + /* + * Method called when the blueprint container is created. + */ + public void init() { + LOG.info("StubrendererProvider Session Initiated"); + final StubrendererImpl consumer = new StubrendererImpl(notificationPublishService); + rpcRegistration = rpcRegistry.addRpcImplementation(StubrendererService.class, consumer); + } + + /* + * Method called when the blueprint container is destroyed. + */ + public void close() { + LOG.info("StubrendererProvider Closed"); + rpcRegistration.close(); + stubRendererlistenerRegistration.close(); + } +} diff --git a/stubrenderer/src/main/resources/org/opendaylight/blueprint/stubrenderer-blueprint.xml b/stubrenderer/src/main/resources/org/opendaylight/blueprint/stubrenderer-blueprint.xml new file mode 100644 index 000000000..dff469168 --- /dev/null +++ b/stubrenderer/src/main/resources/org/opendaylight/blueprint/stubrenderer-blueprint.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + -- 2.36.6