import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
import org.opendaylight.mdsal.binding.api.DataTreeModification;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.api.RpcService;
import org.opendaylight.transportpce.common.ResponseCodes;
import org.opendaylight.transportpce.servicehandler.ServiceInput;
-import org.opendaylight.transportpce.servicehandler.impl.ServicehandlerImpl;
import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.Restorable;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.RpcActions;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.sdnc.request.header.SdncRequestHeaderBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.Restorable;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.RpcActions;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.routing.metric.RoutingMetric;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.sdnc.request.header.SdncRequestHeaderBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliency;
import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateInputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateOutput;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteInputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteOutput;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.create.input.ServiceAEndBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.create.input.ServiceZEndBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfo;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfoBuilder;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.Services;
-import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmService;
-import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishNotificationAlarmServiceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreate;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDelete;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceReroute;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceAEndBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.create.input.ServiceZEndBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.delete.input.ServiceDeleteReqInfo;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.delete.input.ServiceDeleteReqInfoBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services;
+import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmService;
+import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmServiceBuilder;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Component
public class ServiceListener implements DataTreeChangeListener<Services> {
private static final Logger LOG = LoggerFactory.getLogger(ServiceListener.class);
private static final String PUBLISHER = "ServiceListener";
- private ServicehandlerImpl servicehandlerImpl;
+ private final RpcService rpcService;
private ServiceDataStoreOperations serviceDataStoreOperations;
private NotificationPublishService notificationPublishService;
private Map<String, ServiceInput> mapServiceInputReroute;
private final ScheduledExecutorService executor;
- public ServiceListener(ServicehandlerImpl servicehandlerImpl, ServiceDataStoreOperations serviceDataStoreOperations,
- NotificationPublishService notificationPublishService) {
- this.servicehandlerImpl = servicehandlerImpl;
- this.notificationPublishService = notificationPublishService;
+ @Activate
+ public ServiceListener(@Reference RpcService rpcService,
+ @Reference ServiceDataStoreOperations serviceDataStoreOperations,
+ @Reference NotificationPublishService notificationPublishService) {
+ this.rpcService = rpcService;
this.serviceDataStoreOperations = serviceDataStoreOperations;
+ this.notificationPublishService = notificationPublishService;
this.executor = MoreExecutors.getExitingScheduledExecutorService(new ScheduledThreadPoolExecutor(4));
mapServiceInputReroute = new HashMap<>();
}
@Override
- public void onDataTreeChanged(Collection<DataTreeModification<Services>> changes) {
+ public void onDataTreeChanged(List<DataTreeModification<Services>> changes) {
LOG.info("onDataTreeChanged - {}", this.getClass().getSimpleName());
for (DataTreeModification<Services> change : changes) {
DataObjectModification<Services> rootService = change.getRootNode();
- if (rootService.getDataBefore() == null) {
+ if (rootService.dataBefore() == null) {
continue;
}
- String serviceInputName = rootService.getDataBefore().key().getServiceName();
- switch (rootService.getModificationType()) {
+ String serviceInputName = rootService.dataBefore().key().getServiceName();
+ switch (rootService.modificationType()) {
case DELETE:
LOG.info("Service {} correctly deleted from controller", serviceInputName);
if (mapServiceInputReroute.get(serviceInputName) != null) {
}
break;
case WRITE:
- Services inputBefore = rootService.getDataBefore();
- Services inputAfter = rootService.getDataAfter();
+ Services inputBefore = rootService.dataBefore();
+ Services inputAfter = rootService.dataAfter();
if (inputBefore.getOperationalState() == State.InService
&& inputAfter.getOperationalState() == State.OutOfService) {
LOG.info("Service {} is becoming outOfService", serviceInputName);
if (inputAfter.getAdministrativeState() == AdminStates.InService
&& inputAfter.getServiceResiliency() != null
&& inputAfter.getServiceResiliency().getResiliency() != null
- && inputAfter.getServiceResiliency().getResiliency().equals(Restorable.class)) {
+ && inputAfter.getServiceResiliency().getResiliency().equals(Restorable.VALUE)) {
LOG.info("Attempting to reroute the service '{}'...", serviceInputName);
- // It is used for hold off time purposes
+ if (!serviceRerouteCheck(serviceInputName, inputAfter.getServiceResiliency(),
+ inputAfter.getRoutingMetric())) {
+ LOG.info("No other path available, cancelling reroute process of service '{}'...",
+ serviceInputName);
+ continue;
+ }
mapServiceInputReroute.put(serviceInputName, null);
if (inputAfter.getServiceResiliency().getHoldoffTime() != null) {
LOG.info("Waiting hold off time before rerouting...");
&& mapServiceInputReroute.get(serviceInputName) == null) {
serviceRerouteStep1(serviceInputName);
} else {
- LOG.info("Cancelling rerouting for service '{}'...", serviceInputName);
+ LOG.info("Cancelling reroute process of service '{}'...",
+ serviceInputName);
}
},
Long.parseLong(String.valueOf(inputAfter.getServiceResiliency()
}
break;
default:
- LOG.debug("Unknown modification type {}", rootService.getModificationType().name());
+ LOG.debug("Unknown modification type {}", rootService.modificationType().name());
break;
}
}
LOG.warn("Service '{}' does not exist in datastore", serviceNameToReroute);
return;
}
- Services service = serviceOpt.get();
- ListenableFuture<RpcResult<ServiceDeleteOutput>> res = this.servicehandlerImpl.serviceDelete(
+ Services service = serviceOpt.orElseThrow();
+ ListenableFuture<RpcResult<ServiceDeleteOutput>> res = rpcService.getRpc(ServiceDelete.class).invoke(
new ServiceDeleteInputBuilder()
.setSdncRequestHeader(new SdncRequestHeaderBuilder(service.getSdncRequestHeader())
.setRpcAction(RpcActions.ServiceDelete)
* @param serviceNameToReroute Name of the service
*/
private void serviceRerouteStep2(String serviceNameToReroute) {
- ListenableFuture<RpcResult<ServiceCreateOutput>> res = this.servicehandlerImpl.serviceCreate(
+ ListenableFuture<RpcResult<ServiceCreateOutput>> res = rpcService.getRpc(ServiceCreate.class).invoke(
mapServiceInputReroute.get(serviceNameToReroute).getServiceCreateInput());
try {
String httpResponseCode = res.get().getResult().getConfigurationResponseCommon().getResponseCode();
mapServiceInputReroute.remove(serviceNameToReroute);
}
+ /**
+ * Prior to the reroute steps: check that an alternative route of the service is possible.
+ *
+ * @param serviceNameToReroute Name of the service
+ * @param serviceResiliency Resiliency of the service
+ * @param routingMetric Metric of the routing
+ */
+ private boolean serviceRerouteCheck(String serviceNameToReroute, ServiceResiliency serviceResiliency,
+ RoutingMetric routingMetric) {
+ ServiceRerouteInput serviceRerouteInput = new ServiceRerouteInputBuilder()
+ .setServiceName(serviceNameToReroute)
+ .setServiceResiliency(serviceResiliency)
+ .setRoutingMetric(routingMetric)
+ .setSdncRequestHeader(new SdncRequestHeaderBuilder()
+ .setRpcAction(RpcActions.ServiceReroute)
+ .build())
+ .build();
+ ListenableFuture<RpcResult<ServiceRerouteOutput>> res = rpcService.getRpc(ServiceReroute.class).invoke(
+ serviceRerouteInput);
+ try {
+ return res.get().getResult().getConfigurationResponseCommon().getResponseCode()
+ .equals(ResponseCodes.RESPONSE_OK);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.warn("ServiceRerouteCheck FAILED ! ", e);
+ return false;
+ }
+ }
+
/**
* Send notification to NBI notification in order to publish message.
*
Thread.currentThread().interrupt();
}
}
+
}