Bump upstream dependencies to Ca
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / impl / rpc / CreateConnectivityServiceImpl.java
1 /*
2  * Copyright © 2024 Orange, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.transportpce.tapi.impl.rpc;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.HashMap;
12 import java.util.Map;
13 import java.util.UUID;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.mdsal.binding.api.RpcService;
16 import org.opendaylight.transportpce.common.OperationResult;
17 import org.opendaylight.transportpce.common.ResponseCodes;
18 import org.opendaylight.transportpce.tapi.connectivity.ConnectivityUtils;
19 import org.opendaylight.transportpce.tapi.listeners.TapiPceNotificationHandler;
20 import org.opendaylight.transportpce.tapi.listeners.TapiRendererNotificationHandler;
21 import org.opendaylight.transportpce.tapi.utils.TapiContext;
22 import org.opendaylight.transportpce.tapi.validation.CreateConnectivityServiceValidation;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreate;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateInput;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateOutput;
26 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.AdministrativeState;
27 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.ForwardingDirection;
28 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.LifecycleState;
29 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.OperationalState;
30 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.Uuid;
31 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.capacity.TotalSizeBuilder;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.Name;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.global._class.NameBuilder;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePoint;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev221121.tapi.context.ServiceInterfacePointKey;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityService;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityServiceInput;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityServiceOutput;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.CreateConnectivityServiceOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.ServiceType;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityService;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.context.ConnectivityServiceBuilder;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectivityConstraint;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.ConnectivityConstraintBuilder;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPoint;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPointBuilder;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.EndPointKey;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.end.point.CapacityBuilder;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.connectivity.service.end.point.ServiceInterfacePointBuilder;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.output.ServiceBuilder;
51 import org.opendaylight.yangtools.yang.common.ErrorType;
52 import org.opendaylight.yangtools.yang.common.RpcResult;
53 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58 public class CreateConnectivityServiceImpl implements CreateConnectivityService {
59     private static final Logger LOG = LoggerFactory.getLogger(CreateConnectivityServiceImpl.class);
60
61     private final RpcService rpcService;
62     private final TapiContext tapiContext;
63     private final ConnectivityUtils connectivityUtils;
64     private TapiPceNotificationHandler pceListenerImpl;
65     private TapiRendererNotificationHandler rendererListenerImpl;
66
67     public CreateConnectivityServiceImpl(RpcService rpcService, TapiContext tapiContext,
68             ConnectivityUtils connectivityUtils, TapiPceNotificationHandler pceListenerImpl,
69             TapiRendererNotificationHandler rendererListenerImpl) {
70         this.rpcService = rpcService;
71         this.tapiContext = tapiContext;
72         this.connectivityUtils = connectivityUtils;
73         this.pceListenerImpl = pceListenerImpl;
74         this.rendererListenerImpl = rendererListenerImpl;
75     }
76
77     @Override
78     public ListenableFuture<RpcResult<CreateConnectivityServiceOutput>> invoke(CreateConnectivityServiceInput input) {
79         // TODO: later version of TAPI models include Name as an input parameter in connectivity.yang
80         LOG.info("RPC create-connectivity received: {}", input.getEndPoint());
81         Uuid serviceUuid = new Uuid(UUID.randomUUID().toString());
82         this.pceListenerImpl.setInput(input);
83         this.pceListenerImpl.setServiceUuid(serviceUuid);
84         this.rendererListenerImpl.setServiceUuid(serviceUuid);
85         ListenableFuture<RpcResult<ServiceCreateOutput>> output = null;
86         OperationResult validationResult = CreateConnectivityServiceValidation.validateCreateConnectivityServiceRequest(
87                 input);
88         if (validationResult.isSuccess()) {
89             LOG.info("input parameter of RPC create-connectivity are being handled");
90             // check uuid of SIP in tapi context
91             Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap = this.tapiContext.getTapiContext()
92                     .getServiceInterfacePoint();
93             if (sipMap == null) {
94                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
95                     .withError(ErrorType.RPC, "SIP list is empty")
96                     .buildFuture();
97             }
98             if (sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().findFirst()
99                         .orElseThrow().getServiceInterfacePoint().getServiceInterfacePointUuid()))
100                     && sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().skip(1)
101                         .findFirst().orElseThrow().getServiceInterfacePoint().getServiceInterfacePointUuid()))) {
102                 LOG.info("SIPs found in sipMap");
103                 // TODO: differentiate between OTN service and GbE service in TAPI
104                 ServiceCreateInput sci = this.connectivityUtils.createORServiceInput(input, serviceUuid);
105                 if (sci == null) {
106                     return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
107                         .withError(ErrorType.RPC, "Couldnt map Service create input")
108                         .buildFuture();
109                 }
110                 LOG.info("Service Create input = {}", sci);
111                 output = rpcService.getRpc(ServiceCreate.class).invoke(sci);
112                 if (!output.isDone()) {
113                     return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
114                         .withError(ErrorType.RPC, "Service create RPC failed")
115                         .buildFuture();
116                 }
117             } else {
118                 LOG.error("Unknown UUID");
119                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
120                     .withError(ErrorType.RPC, "SIPs do not exist in tapi context")
121                     .buildFuture();
122             }
123         }
124         try {
125             if (output == null) {
126                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
127                     .withError(ErrorType.RPC, "Failed to create service")
128                     .buildFuture();
129             }
130             LOG.info("Service create request was successful");
131             if (output.get().getResult().getConfigurationResponseCommon().getResponseCode()
132                     .equals(ResponseCodes.RESPONSE_FAILED)) {
133                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
134                     .withError(ErrorType.RPC, "Failed to create service")
135                     .buildFuture();
136             }
137             LOG.info("Output of service request = {}", output.get().getResult());
138         } catch (InterruptedException | ExecutionException e) {
139             LOG.error("Error checking response code of service create", e);
140         }
141         // Connections and states should be created/updated when the pce and renderer are done :)
142         Map<EndPointKey, EndPoint> endPointList = createEndPoints(input.getEndPoint());
143         Name name = new NameBuilder()
144             .setValueName("Connectivity Service Name")
145             .setValue(serviceUuid.getValue())
146             .build();
147         ConnectivityConstraint conConstr = new ConnectivityConstraintBuilder()
148             .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY)
149             .setServiceLevel(input.getConnectivityConstraint().getServiceLevel()).build();
150
151         ConnectivityService service = new ConnectivityServiceBuilder()
152             .setUuid(serviceUuid)
153             .setAdministrativeState(AdministrativeState.LOCKED)
154             .setOperationalState(OperationalState.DISABLED)
155             .setLifecycleState(LifecycleState.PLANNED)
156             .setLayerProtocolName(input.getLayerProtocolName())
157             .setConnectivityConstraint(conConstr)
158             .setDirection(ForwardingDirection.BIDIRECTIONAL)
159             .setName(Map.of(name.key(), name))
160             .setConnection(new HashMap<>())
161             .setEndPoint(endPointList)
162             .build();
163         // add to tapi context
164         this.tapiContext.updateConnectivityContext(Map.of(service.key(), service), new HashMap<>());
165         LOG.info("Created locked service in Datastore. Waiting for PCE and Renderer to complete tasks...");
166         // return ConnectivityServiceCreateOutput
167         return RpcResultBuilder.success(new CreateConnectivityServiceOutputBuilder()
168             .setService(new ServiceBuilder(service).build()).build()).buildFuture();
169     }
170
171     private Map<EndPointKey, EndPoint> createEndPoints(
172             Map<org.opendaylight.yang.gen.v1.urn
173                 .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPointKey,
174                 org.opendaylight.yang.gen.v1.urn
175                     .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint> endPoints) {
176         Map<EndPointKey, EndPoint> endPointMap = new HashMap<>();
177         for (org.opendaylight.yang.gen.v1.urn
178                 .onf.otcc.yang.tapi.connectivity.rev221121.create.connectivity.service.input.EndPoint ep:
179                 endPoints.values()) {
180             EndPoint endpoint = new EndPointBuilder()
181                 .setServiceInterfacePoint(new ServiceInterfacePointBuilder()
182                     .setServiceInterfacePointUuid(ep.getServiceInterfacePoint().getServiceInterfacePointUuid())
183                     .build())
184                 .setName(ep.getName())
185                 .setAdministrativeState(ep.getAdministrativeState())
186                 .setDirection(ep.getDirection())
187                 .setLifecycleState(ep.getLifecycleState())
188                 .setOperationalState(ep.getOperationalState())
189                 .setLayerProtocolName(ep.getLayerProtocolName())
190                 // TODO: implement bandwidth profile
191                 .setCapacity(new CapacityBuilder()
192                     .setTotalSize(new TotalSizeBuilder().build())
193 //                    .setBandwidthProfile(new BandwidthProfileBuilder().build()) // TODO: implement bandwidth profile
194                     .build())
195                 .setProtectionRole(ep.getProtectionRole())
196                 .setRole(ep.getRole())
197                 .setLocalId(ep.getLocalId())
198                 .build();
199             endPointMap.put(endpoint.key(), endpoint);
200         }
201         return endPointMap;
202     }
203
204 }