[ONOS-5805] MEF SCA REST API app for CE App
Migrating MEF SCA API translation app to onos-app-samples.
- Originally developed mainly by Konstantinos Kanonakis <kanonakisk@gmail.com>
Change-Id: Ibf9f9e60c4dcd6375dd135a2f2c7714e3cd7d127
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/ApiDocRegistrator.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/ApiDocRegistrator.java
new file mode 100644
index 0000000..20ca056
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/ApiDocRegistrator.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.mefscaapi;
+
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.rest.AbstractApiDocRegistrator;
+import org.onosproject.rest.ApiDocProvider;
+
+// Usually onos-maven-plugin generates swagger.json and generate equivalent.
+// But this app is generated "from" swagger, so equivalent is not auto-generated
+// by the plugin. Manually creating one.
+@Component(immediate = true)
+public class ApiDocRegistrator extends AbstractApiDocRegistrator {
+ public ApiDocRegistrator() {
+ // sync with pom.xml web.context
+ super(new ApiDocProvider("/onos/mef-sca-api",
+ "MEF SCA REST API",
+ ApiDocRegistrator.class.getClassLoader()));
+ }
+}
\ No newline at end of file
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiAppComponent.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiAppComponent.java
new file mode 100644
index 0000000..c9931ef
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiAppComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.mefscaapi;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Skeletal ONOS application component.
+ */
+@Component(immediate = true)
+public class MefScaApiAppComponent {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Activate
+ protected void activate() {
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Stopped");
+ }
+
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiWebApplication.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiWebApplication.java
new file mode 100644
index 0000000..57b3d01
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/MefScaApiWebApplication.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.mefscaapi;
+
+import org.onlab.rest.AbstractWebApplication;
+import org.onosproject.mefscaapi.api.JacksonJsonProvider;
+import org.onosproject.mefscaapi.api.SCAETHFDFrECApi;
+import org.onosproject.mefscaapi.api.SCAETHFPPUNINApi;
+import org.onosproject.mefscaapi.api.SCAETHFlowDomainApi;
+
+import java.util.Set;
+
+/**
+ * MEF SCA API web application.
+ */
+public class MefScaApiWebApplication extends AbstractWebApplication {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return getClasses(SCAETHFDFrECApi.class, SCAETHFlowDomainApi.class, SCAETHFPPUNINApi.class,
+ JacksonJsonProvider.class);
+ }
+}
+
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFDFrECApiServiceFactory.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFDFrECApiServiceFactory.java
new file mode 100644
index 0000000..7d24646
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFDFrECApiServiceFactory.java
@@ -0,0 +1,12 @@
+package org.onosproject.mefscaapi.api.factories;
+
+import org.onosproject.mefscaapi.api.SCAETHFDFrECApiService;
+import org.onosproject.mefscaapi.api.impl.ScaEthFdFrEcApiServiceImpl;
+
+public class SCAETHFDFrECApiServiceFactory {
+ private final static SCAETHFDFrECApiService service = new ScaEthFdFrEcApiServiceImpl();
+
+ public static SCAETHFDFrECApiService getSCAETHFDFrECApi() {
+ return service;
+ }
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFPPUNINApiServiceFactory.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFPPUNINApiServiceFactory.java
new file mode 100644
index 0000000..7659458
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFPPUNINApiServiceFactory.java
@@ -0,0 +1,12 @@
+package org.onosproject.mefscaapi.api.factories;
+
+import org.onosproject.mefscaapi.api.SCAETHFPPUNINApiService;
+import org.onosproject.mefscaapi.api.impl.ScaEthFppUniNApiServiceImpl;
+
+public class SCAETHFPPUNINApiServiceFactory {
+ private final static SCAETHFPPUNINApiService service = new ScaEthFppUniNApiServiceImpl();
+
+ public static SCAETHFPPUNINApiService getSCAETHFPPUNINApi() {
+ return service;
+ }
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFlowDomainApiServiceFactory.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFlowDomainApiServiceFactory.java
new file mode 100644
index 0000000..98b0545
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/factories/SCAETHFlowDomainApiServiceFactory.java
@@ -0,0 +1,12 @@
+package org.onosproject.mefscaapi.api.factories;
+
+import org.onosproject.mefscaapi.api.SCAETHFlowDomainApiService;
+import org.onosproject.mefscaapi.api.impl.ScaEthFlowDomainApiServiceImpl;
+
+public class SCAETHFlowDomainApiServiceFactory {
+ private final static SCAETHFlowDomainApiService service = new ScaEthFlowDomainApiServiceImpl();
+
+ public static SCAETHFlowDomainApiService getSCAETHFlowDomainApi() {
+ return service;
+ }
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFdFrEcApiServiceImpl.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFdFrEcApiServiceImpl.java
new file mode 100755
index 0000000..8a3c8cc
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFdFrEcApiServiceImpl.java
@@ -0,0 +1,150 @@
+package org.onosproject.mefscaapi.api.impl;
+
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection;
+import org.onosproject.mefscaapi.api.ApiResponseMessage;
+import org.onosproject.mefscaapi.api.SCAETHFDFrECApiService;
+import org.onosproject.mefscaapi.api.model.SCAETHFDFrEC;
+import org.onosproject.mefscaapi.translate.ScaApiTranslator;
+import org.slf4j.Logger;
+
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriBuilder;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class ScaEthFdFrEcApiServiceImpl extends SCAETHFDFrECApiService {
+
+ CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
+
+ private static final Logger log = getLogger(ScaEthFdFrEcApiServiceImpl.class);
+
+ private static final String CHECK_LOG = " Check ONOS log for details.";
+ private static final String NOT_TRANSLATED = "Could not translate EVC.";
+ private static final String NOT_EXISTS = "EVC does not exist.";
+ private static final String CREATED = "EVC was created successfully.";
+ private static final String UPDATED = "EVC was updated successfully.";
+ private static final String NOT_CREATED = "EVC could not be created.";
+ private static final String REMOVED = "EVC was removed successfully.";
+ private static final String NOT_REMOVED = "EVC could not be removed.";
+ private static final String REFCOUNT_NOT_ZERO = " RefCount is not zero.";
+ private static final String EVC_REL_URI = "SCA_ETH_FDFr_EC/";
+
+ @Override
+ public Response deleteSCAETHFDFrEC(String id, SecurityContext securityContext)
+ throws NotFoundException {
+
+ if (ceManager.getEvc(id) == null) {
+ return response(Response.Status.NOT_FOUND,
+ responseMsg(ApiResponseMessage.ERROR, NOT_EXISTS));
+ } else {
+ // Remove the EVC
+ ceManager.removeEvc(id);
+ return response(Response.Status.OK,
+ responseMsg(ApiResponseMessage.INFO, REMOVED));
+ }
+ }
+
+ @Override
+ public Response findSCAETHFDFrECById(String id, SecurityContext securityContext)
+ throws NotFoundException {
+
+ CarrierEthernetVirtualConnection evc = ceManager.getEvc(id);
+
+ if (evc == null) {
+ return response(Response.Status.NOT_FOUND,
+ responseMsg(ApiResponseMessage.ERROR, NOT_EXISTS));
+ } else {
+ SCAETHFDFrEC scaEvc = ScaApiTranslator.fromCarrierEthernetVirtualConnection(evc);
+ if (scaEvc == null) {
+ return response(Response.Status.INTERNAL_SERVER_ERROR,
+ responseMsg(ApiResponseMessage.ERROR, NOT_TRANSLATED));
+ } else {
+ return response(Response.Status.OK,
+ scaEvc);
+ }
+ }
+ }
+
+ @Override
+ public Response findSCAETHFDFrECByState(String state, SecurityContext securityContext)
+ throws NotFoundException {
+
+ List<SCAETHFDFrEC> scaEvcList = new LinkedList<>();
+ // Browse through all CE FCs and translate them to NRP ones
+ for (CarrierEthernetVirtualConnection ceEvc : ceManager.evcMap().values()) {
+ SCAETHFDFrEC scaEvc =
+ ScaApiTranslator.fromCarrierEthernetVirtualConnection(ceEvc);
+ // If no state is provided, return all EVCs
+ if (scaEvc != null &&
+ (state == null || state.equalsIgnoreCase(scaEvc.getState().toString()))) {
+ scaEvcList.add(scaEvc);
+ }
+ }
+
+ // TODO: Indicate if some of the EVCs could not be translated?
+ return response(Response.Status.OK, scaEvcList);
+ }
+
+ @Override
+ public Response sCAETHFDFrECIdPatch(String id, String state, SecurityContext securityContext)
+ throws NotFoundException {
+ // do some magic!
+ return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
+ }
+
+ @Override
+ public Response sCAETHFDFrECPost(SCAETHFDFrEC scaEthFdFrEc, SecurityContext securityContext)
+ throws NotFoundException {
+
+ log.trace("input: {}", scaEthFdFrEc);
+
+ CarrierEthernetVirtualConnection evc =
+ ScaApiTranslator.toCarrierEthernetVirtualConnection(scaEthFdFrEc);
+
+ if (evc == null) {
+ return response(Response.Status.BAD_REQUEST,
+ responseMsg(ApiResponseMessage.ERROR, NOT_TRANSLATED));
+ } else {
+ boolean serviceExisted =
+ evc.id() != null && ceManager.evcMap().containsKey(evc.id());
+
+ ceManager.installEvc(evc);
+
+ if (evc.isActive()) {
+ String message = serviceExisted ? UPDATED : CREATED;
+ return response(EVC_REL_URI + evc.id(),
+ responseMsg(ApiResponseMessage.INFO, message));
+ } else {
+ // TODO: Find out somehow the reason for the failure
+ return response(Response.Status.INTERNAL_SERVER_ERROR,
+ responseMsg(ApiResponseMessage.ERROR, NOT_CREATED + CHECK_LOG));
+ }
+ }
+ }
+
+ private <T> Response response(Response.Status status, T entity) {
+ return Response
+ .status(status)
+ .entity(entity)
+ .build();
+ }
+
+ private <T> Response response(String uri, T entity) {
+ return Response
+ .created(UriBuilder.fromUri(uri).build())
+ .entity(entity)
+ .build();
+ }
+
+ private ApiResponseMessage responseMsg(int msgCode, String msg) {
+ return new ApiResponseMessage(msgCode, msg == null ? "" : msg);
+ }
+}
+
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFlowDomainApiServiceImpl.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFlowDomainApiServiceImpl.java
new file mode 100755
index 0000000..e2e7a5d
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFlowDomainApiServiceImpl.java
@@ -0,0 +1,24 @@
+package org.onosproject.mefscaapi.api.impl;
+
+import org.onosproject.mefscaapi.api.ApiResponseMessage;
+import org.onosproject.mefscaapi.api.NotFoundException;
+import org.onosproject.mefscaapi.api.SCAETHFlowDomainApiService;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+public class ScaEthFlowDomainApiServiceImpl extends SCAETHFlowDomainApiService {
+
+ @Override
+ public Response getSCAETHFlowDomain(SecurityContext securityContext) throws NotFoundException {
+ // do some magic!
+ return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
+ }
+
+ @Override
+ public Response getSCAETHFlowDomainById(String id, SecurityContext securityContext) throws NotFoundException {
+ // do some magic!
+ return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
+ }
+
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFppUniNApiServiceImpl.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFppUniNApiServiceImpl.java
new file mode 100755
index 0000000..3090404
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/ScaEthFppUniNApiServiceImpl.java
@@ -0,0 +1,120 @@
+package org.onosproject.mefscaapi.api.impl;
+
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni;
+import org.onosproject.mefscaapi.api.ApiResponseMessage;
+import org.onosproject.mefscaapi.api.NotFoundException;
+import org.onosproject.mefscaapi.api.SCAETHFPPUNINApiService;
+import org.onosproject.mefscaapi.api.model.SCAETHFPPUNIN;
+import org.onosproject.mefscaapi.api.model.SCAETHFlowPoint;
+import org.onosproject.mefscaapi.translate.ScaApiTranslator;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriBuilder;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ScaEthFppUniNApiServiceImpl extends SCAETHFPPUNINApiService {
+
+ CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
+
+ private static final String NOT_TRANSLATED = "Could not translate UNI.";
+ private static final String EXISTS = "UNI already exists.";
+ private static final String NOT_EXISTS = "UNI does not exist.";
+ private static final String CREATED = "UNI was created successfully.";
+ private static final String REMOVED = "UNI was removed successfully.";
+ private static final String NOT_REMOVED = "UNI could not be removed.";
+ private static final String REFCOUNT_NOT_ZERO = " RefCount is not zero.";
+ private static final String UNI_REL_URI = "SCA_ETH_FPP_UNI_N/";
+
+ @Override
+ public Response createSCAETHFPPUNIN(SCAETHFPPUNIN uni, SecurityContext securityContext) throws NotFoundException {
+
+ // Create SCA Flow Point and add provided SCA UNI to it
+ SCAETHFlowPoint scaFlowPoint = new SCAETHFlowPoint();
+ scaFlowPoint.setScaEthFppUniN(uni);
+
+ CarrierEthernetUni ceUni = ScaApiTranslator.toCarrierEthernetUni(scaFlowPoint, null);
+ if (ceUni == null) {
+ return response(Response.Status.BAD_REQUEST,
+ responseMsg(ApiResponseMessage.ERROR, NOT_TRANSLATED));
+ } else if (ceManager.addGlobalUni(ceUni) == null) {
+ return response(Response.Status.FORBIDDEN,
+ responseMsg(ApiResponseMessage.ERROR, EXISTS));
+ } else {
+ return response(UNI_REL_URI + ceUni.id(),
+ responseMsg(ApiResponseMessage.INFO, CREATED));
+ }
+ }
+
+ @Override
+ public Response deleteSCAETHFPPUNIN(String uniID, SecurityContext securityContext) throws NotFoundException {
+
+ if (ceManager.getUniMap().get(uniID) == null) {
+ return response(Response.Status.NOT_FOUND,
+ responseMsg(ApiResponseMessage.ERROR, NOT_EXISTS));
+ } else if (ceManager.removeGlobalUni(uniID) == null) {
+ return response(Response.Status.FORBIDDEN,
+ responseMsg(ApiResponseMessage.ERROR, NOT_REMOVED + REFCOUNT_NOT_ZERO));
+ } else {
+ return response(Response.Status.OK,
+ responseMsg(ApiResponseMessage.INFO, REMOVED));
+ }
+ }
+
+ @Override
+ public Response findSCAETHFPPUNIN(String fields, SecurityContext securityContext) throws NotFoundException {
+
+ List<SCAETHFPPUNIN> scaUniList = new LinkedList<>();
+
+ // Add all global UNIs if they are not there already
+ ceManager.getUnisFromTopo(false, false).forEach(uni -> ceManager.addGlobalUni(uni));
+
+ // Browse through all global CE UNIs and translate them to SCA ones
+ for (CarrierEthernetUni ceUni : ceManager.getUniMap().values()) {
+ // TODO: Match on provided fields
+ SCAETHFlowPoint scaFlowPoint = ScaApiTranslator.fromCarrierEthernetUni(ceUni);
+ if (scaFlowPoint != null) {
+ scaUniList.add(scaFlowPoint.getScaEthFppUniN());
+ }
+ }
+
+ // TODO: Indicate if some of the Flow Points could not be translated?
+ return response(Response.Status.OK, scaUniList);
+ }
+
+ @Override
+ public Response getSCAETHFPPUNIN(String uniID, String fields, SecurityContext securityContext)
+ throws NotFoundException {
+ // do some magic!
+ return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
+ }
+
+ @Override
+ public Response patchSCAETHFPPUNIN(String uniID, SCAETHFPPUNIN individual, SecurityContext securityContext)
+ throws NotFoundException {
+ // do some magic!
+ return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
+ }
+
+ private <T> Response response(Response.Status status, T entity) {
+ return Response
+ .status(status)
+ .entity(entity)
+ .build();
+ }
+
+ private <T> Response response(String uri, T entity) {
+ return Response
+ .created(UriBuilder.fromUri(uri).build())
+ .entity(entity)
+ .build();
+ }
+
+ private ApiResponseMessage responseMsg(int msgCode, String msg) {
+ return new ApiResponseMessage(msgCode, msg == null ? "" : msg);
+ }
+}
+
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/package-info.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/package-info.java
new file mode 100644
index 0000000..ba2296b
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/api/impl/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+/**
+ * MEF SCA API implementations.
+ */
+package org.onosproject.mefscaapi.api.impl;
\ No newline at end of file
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/package-info.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/package-info.java
new file mode 100644
index 0000000..324b59d
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+/**
+ * MEF SCA app.
+ */
+package org.onosproject.mefscaapi;
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/ScaApiTranslator.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/ScaApiTranslator.java
new file mode 100644
index 0000000..8c02670
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/ScaApiTranslator.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.mefscaapi.translate;
+
+import org.onlab.util.Bandwidth;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetBandwidthProfile;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetConnection;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection;
+import org.onlab.packet.VlanId;
+import org.onosproject.mefscaapi.api.model.SCAETHFDFrEC;
+import org.onosproject.mefscaapi.api.model.SCAETHFPPUNIN;
+import org.onosproject.mefscaapi.api.model.SCAETHFPPUNINTransportPort;
+import org.onosproject.mefscaapi.api.model.SCAETHFlowPoint;
+import org.onosproject.mefscaapi.api.model.SCAETHFlowPointClassOfServiceIdentifierIp;
+import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier;
+import org.onosproject.mefscaapi.api.model.SCAETHFlowPointIngressBandwidthProfilePerEvc;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Methods for translating between SCA API swagger-generated JAVA classes and CE App classes.
+ */
+public final class ScaApiTranslator {
+
+ private static DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+
+ private static final Logger log = getLogger(ScaApiTranslator.class);
+
+ // Not to be called
+ private ScaApiTranslator() {
+ }
+
+ public static CarrierEthernetVirtualConnection toCarrierEthernetVirtualConnection(SCAETHFDFrEC scaethfdFrEC) {
+
+ String evcId = scaethfdFrEC.getId();
+ String evcCfgId = scaethfdFrEC.getEvcCfgIdentifier();
+ CarrierEthernetVirtualConnection.Type evcType =
+ CarrierEthernetVirtualConnection.Type.valueOf(scaethfdFrEC.getEvcServiceType().name());
+ Integer maxNumUni = scaethfdFrEC.getEvcStatusMaxNumUni();
+ Set<CarrierEthernetUni> uniSet = new HashSet<>();
+
+ CarrierEthernetUni ceUni;
+ CarrierEthernetUni.Role ceUniRole = CarrierEthernetUni.Role.ROOT;
+ ListIterator<SCAETHFlowPoint> it = scaethfdFrEC.getSCAETHFlowPoints().listIterator();
+ while (it.hasNext()) {
+ if (evcType.equals(CarrierEthernetConnection.Type.ROOT_MULTIPOINT)) {
+ ceUniRole = (it.nextIndex() == 0) ? CarrierEthernetUni.Role.ROOT : CarrierEthernetUni.Role.LEAF;
+ }
+ SCAETHFlowPoint scaFlowPoint = it.next();
+ // Create new CE UNI
+ ceUni = toCarrierEthernetUni(scaFlowPoint, ceUniRole);
+ if (ceUni == null) {
+ return null;
+ }
+ uniSet.add(ceUni);
+ }
+
+ return CarrierEthernetVirtualConnection.builder()
+ .id(evcId)
+ .cfgId(evcCfgId)
+ .type(evcType)
+ .maxNumUni(maxNumUni)
+ .uniSet(uniSet)
+ .build();
+ }
+
+ public static SCAETHFDFrEC fromCarrierEthernetVirtualConnection(CarrierEthernetVirtualConnection ceService) {
+
+ SCAETHFDFrEC scaethfdFrEC = new SCAETHFDFrEC();
+
+ scaethfdFrEC.setId(ceService.id());
+ scaethfdFrEC.setEvcCfgIdentifier(ceService.cfgId());
+ scaethfdFrEC.setEvcServiceType(SCAETHFDFrEC.EvcServiceTypeEnum.valueOf(ceService.type().name()));
+ scaethfdFrEC.setEvcStatusMaxNumUni(ceService.maxNumUni());
+ scaethfdFrEC.setState(SCAETHFDFrEC.StateEnum.valueOf(ceService.state().name()));
+
+ List<SCAETHFlowPoint> scaFlowPointList = new ArrayList<>();
+ SCAETHFlowPoint scaFlowpoint;
+
+ Iterator<CarrierEthernetUni> it = ceService.uniSet().iterator();
+ while (it.hasNext()) {
+ CarrierEthernetUni ceUni = it.next();
+ // Create new SCA Flow Point from CE UNI (will also create an SCA UNI internally)
+ scaFlowpoint = fromCarrierEthernetUni(ceUni);
+ scaFlowPointList.add(scaFlowpoint);
+ }
+
+ scaethfdFrEC.setSCAETHFlowPoints(scaFlowPointList);
+
+ return scaethfdFrEC;
+ }
+
+ public static CarrierEthernetUni toCarrierEthernetUni(SCAETHFlowPoint scaFlowPoint,
+ CarrierEthernetUni.Role ceUniRole) {
+
+ // TODO: Check for null
+
+ // Get SCA UNI from SCA Flow Point
+ SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN();
+
+ // Get UNI id
+ String ceUniCfgId = scaUni.getInterfaceCfgIdentifier();
+
+ // Get CE UNI CE-VLAN id
+ VlanId ceVlanId = ((scaUni.getCeVlanId() == null) ? null :
+ VlanId.vlanId(Short.valueOf(scaUni.getCeVlanId())));
+
+ // TODO: Allow for both ingress and egress BW profiles
+ // Get CE UNI BW profile
+ CarrierEthernetBandwidthProfile ceBwp = getCeBwpFromScaFlowPoint(scaFlowPoint);
+
+ // Get CE UNI connect point
+ DeviceId deviceId = DeviceId.deviceId(scaUni.getTransportPort().getHostname());
+ if (deviceService.getDevice(deviceId) == null) {
+ log.error("Invalid deviceId {}", deviceId);
+ return null;
+ }
+ PortNumber portNumber = PortNumber.portNumber(scaUni.getTransportPort().getPort());
+ if (deviceService.getPort(deviceId, portNumber) == null) {
+ log.error("Invalid port {} for device {}", portNumber, deviceId);
+ return null;
+ }
+ ConnectPoint ceUniCp = new ConnectPoint(deviceId, portNumber);
+
+ // Create CE UNI
+ return CarrierEthernetUni.builder()
+ .cp(ceUniCp)
+ .cfgId(ceUniCfgId)
+ .role(ceUniRole)
+ .ceVlanId(ceVlanId)
+ .bwp(ceBwp)
+ .build();
+ }
+
+ public static SCAETHFlowPoint fromCarrierEthernetUni(CarrierEthernetUni ceUni) {
+
+ SCAETHFlowPoint scaFlowPoint = new SCAETHFlowPoint();
+ SCAETHFPPUNIN scaUni = new SCAETHFPPUNIN();
+
+ // Set SCA UNI Transport Port
+ SCAETHFPPUNINTransportPort scaPort = new SCAETHFPPUNINTransportPort();
+ scaPort.setHostname(ceUni.cp().deviceId().toString());
+ scaPort.setPort(ceUni.cp().port().toString());
+ scaPort.setVendor(deviceService.getDevice(ceUni.cp().deviceId()).manufacturer());
+ scaUni.setTransportPort(scaPort);
+ if (ceUni.ceVlanId() != null) {
+ scaUni.setCeVlanId(ceUni.ceVlanId().toString());
+ }
+
+ scaUni.setInterfaceCfgIdentifier(ceUni.cfgId());
+
+ // Add SCA UNI to SCA Flow Point
+ scaFlowPoint.setScaEthFppUniN(scaUni);
+
+ // TODO: Allow for both ingress and egress BW profiles
+ // FIXME: A CE UNI may have multiple bandwidth profiles
+
+ // Apply existing BW profile from CE UNI to SCA Flow Point (or UNI)
+ applyCeUniBwpToScaFlowPoint(ceUni, scaFlowPoint);
+
+ // TODO: Check if the UNI type needs to be specified
+
+ return scaFlowPoint;
+ }
+
+ private static CarrierEthernetBandwidthProfile getCeBwpFromScaFlowPoint(
+ SCAETHFlowPoint scaFlowPoint) {
+
+ SCAETHFPPUNIN scaUni = scaFlowPoint.getScaEthFppUniN();
+ SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = null;
+ SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaCosBwp = null;
+ String ceBwpId = null;
+ String ceBwpCfgId;
+ CarrierEthernetBandwidthProfile.Type ceBwpType;
+
+ SCAETHFlowPointIngressBandwidthProfilePerEvc ifaceBwp =
+ scaUni.getInterfaceCfgIngressBwp();
+ SCAETHFlowPointIngressBandwidthProfilePerEvc evcBwp =
+ scaFlowPoint.getIngressBandwidthProfilePerEvc();
+ SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier cosBwp =
+ scaFlowPoint.getIngressBandwidthProfilePerClassOfServiceIdentifier();
+
+ // TODO: Complete the COS part
+
+ // FIXME: Perform following check
+ /*Preconditions.checkArgument(ifaceBwp == null && evcBwp == null && cosBwp == null ||
+ (ifaceBwp != null ^ evcBwp != null ^ cosBwp != null),
+ "Only up to one BW profile can be set per UNI");*/
+
+ if (evcBwp != null) {
+ scaBwp = evcBwp;
+ ceBwpCfgId = scaBwp.getBwpCfgIdentifier();
+ ceBwpType = CarrierEthernetBandwidthProfile.Type.EVC;
+ } else if (ifaceBwp != null) {
+ scaBwp = ifaceBwp;
+ // Use the UNI connect point id
+ ceBwpId = scaUni.getTransportPort().getHostname() + "/" + scaUni.getTransportPort().getPort();
+ ceBwpType = CarrierEthernetBandwidthProfile.Type.INTERFACE;
+ ceBwpCfgId = ifaceBwp.getBwpCfgIdentifier();
+ if (ceBwpCfgId == null) {
+ ceBwpCfgId = ceBwpId;
+ }
+ } else if (cosBwp != null) {
+ // FIXME: Complete and test the COS part
+ scaCosBwp = cosBwp;
+ SCAETHFlowPointClassOfServiceIdentifierIp scaCosIdIp =
+ scaFlowPoint.getClassOfServiceIdentifierIp();
+ if (scaCosIdIp == null) {
+ log.error("CoS ID is required for COS BW profile");
+ return null;
+ }
+ ceBwpId = scaCosIdIp.getClassOfServiceName();
+ ceBwpCfgId = scaCosBwp.getBwpCfgIdentifier();
+ ceBwpType = CarrierEthernetBandwidthProfile.Type.COS;
+ } else {
+ return null;
+ }
+
+ CeBwpParams ceBwpParams = scaBwp != null ? new CeBwpParams(scaBwp) :
+ new CeBwpParams(scaCosBwp);
+
+ return CarrierEthernetBandwidthProfile.builder()
+ .id(ceBwpId)
+ .cfgId(ceBwpCfgId)
+ .type(ceBwpType)
+ .cir(ceBwpParams.cir())
+ .cbs(ceBwpParams.cbs())
+ .eir(ceBwpParams.eir())
+ .ebs(ceBwpParams.ebs())
+ .build();
+ }
+
+ private static class CeBwpParams {
+
+ private Bandwidth cir = Bandwidth.bps((long) 0);
+ private Bandwidth eir = Bandwidth.bps((long) 0);
+ private long cbs = (long) 0;
+ private long ebs = (long) 0;
+
+ CeBwpParams() {}
+
+ CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp) {
+ if (scaBwp.getBwpCfgCir() != null) {
+ cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir());
+ }
+ if (scaBwp.getBwpCfgEir() != null) {
+ eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir());
+ }
+ if (scaBwp.getBwpCfgCbs() != null) {
+ cbs = (long) scaBwp.getBwpCfgCbs();
+ }
+ if (scaBwp.getBwpCfgEbs() != null) {
+ ebs = (long) scaBwp.getBwpCfgEbs();
+ }
+ }
+
+ CeBwpParams(SCAETHFlowPointIngressBandwidthProfilePerClassOfServiceIdentifier scaBwp) {
+ if (scaBwp.getBwpCfgCir() != null) {
+ cir = Bandwidth.bps((long) scaBwp.getBwpCfgCir());
+ }
+ if (scaBwp.getBwpCfgEir() != null) {
+ eir = Bandwidth.bps((long) scaBwp.getBwpCfgEir());
+ }
+ if (scaBwp.getBwpCfgCbs() != null) {
+ cbs = (long) scaBwp.getBwpCfgCbs();
+ }
+ if (scaBwp.getBwpCfgEbs() != null) {
+ ebs = (long) scaBwp.getBwpCfgEbs();
+ }
+ }
+
+ public Bandwidth cir() {
+ return cir;
+ }
+
+ public Bandwidth eir() {
+ return eir;
+ }
+
+ public long cbs() {
+ return cbs;
+ }
+
+ public long ebs() {
+ return ebs;
+ }
+ }
+
+ private static SCAETHFlowPoint applyCeUniBwpToScaFlowPoint(
+ CarrierEthernetUni ceUni, SCAETHFlowPoint scaFlowPoint) {
+
+ CarrierEthernetBandwidthProfile ceBwp = ceUni.bwp();
+
+ SCAETHFlowPoint newScaFlowPoint = scaFlowPoint;
+ SCAETHFPPUNIN newScaUni = scaFlowPoint.getScaEthFppUniN();
+
+ if (ceBwp != null) {
+ // Prepare SCA bandwidth profile
+ SCAETHFlowPointIngressBandwidthProfilePerEvc scaBwp = new SCAETHFlowPointIngressBandwidthProfilePerEvc();
+
+ // TODO: Check for null?
+ scaBwp.setBwpCfgCir((int) ceBwp.cir().bps());
+ scaBwp.setBwpCfgCbs((int) ceBwp.cbs());
+ scaBwp.setBwpCfgEir((int) ceBwp.eir().bps());
+ scaBwp.setBwpCfgEbs((int) ceBwp.ebs());
+
+ // TODO: Add the CoS part when it's ready from the CE app side
+ if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
+ newScaUni.setEvcId(ceBwp.id());
+ newScaFlowPoint.setIngressBandwidthProfilePerEvc(scaBwp);
+ } else if (ceBwp.type().equals(CarrierEthernetBandwidthProfile.Type.INTERFACE)) {
+ newScaUni.setInterfaceCfgIdentifier(ceUni.cfgId());
+ newScaUni.setInterfaceCfgIngressBwp(scaBwp);
+ } else {
+ log.error("Could not add BW profile for Flow Point {}", scaFlowPoint.toString());
+ return null;
+ }
+ }
+
+ newScaFlowPoint.setScaEthFppUniN(newScaUni);
+
+ return newScaFlowPoint;
+ }
+
+}
diff --git a/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/package-info.java b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/package-info.java
new file mode 100644
index 0000000..daeec94
--- /dev/null
+++ b/mef-sca-api/src/main/java/org/onosproject/mefscaapi/translate/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+/**
+ * MEF SCA app utilities.
+ */
+package org.onosproject.mefscaapi.translate;