Adapt TransportPCE code to Sulfur
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / connectivity / TapiConnectivityImpl.java
1 /*
2  * Copyright © 2018 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.connectivity;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.nio.charset.StandardCharsets;
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.UUID;
15 import java.util.concurrent.ExecutionException;
16 import org.opendaylight.transportpce.common.OperationResult;
17 import org.opendaylight.transportpce.common.ResponseCodes;
18 import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
19 import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
20 import org.opendaylight.transportpce.tapi.utils.TapiContext;
21 import org.opendaylight.transportpce.tapi.validation.CreateConnectivityServiceValidation;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.RpcActions;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.sdnc.request.header.SdncRequestHeaderBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.OrgOpenroadmServiceService;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateInput;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceCreateOutput;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteInputBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.ServiceDeleteOutput;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfo;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.delete.input.ServiceDeleteReqInfoBuilder;
31 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.BandwidthProfileBuilder;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceOutput;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceOutputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInput;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceOutput;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsInput;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsOutput;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionDetailsOutputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsInput;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsOutput;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectionEndPointDetailsOutputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsInput;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsOutput;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceDetailsOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListInput;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListOutput;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.GetConnectivityServiceListOutputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ServiceType;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.TapiConnectivityService;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.UpdateConnectivityServiceInput;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.UpdateConnectivityServiceOutput;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint;
70 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointBuilder;
71 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey;
72 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.CapacityBuilder;
73 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.ServiceInterfacePointBuilder;
74 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.output.ServiceBuilder;
75 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connection.details.output.ConnectionBuilder;
76 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connection.end.point.details.output.ConnectionEndPointBuilder;
77 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.Service;
78 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.ServiceKey;
79 import org.opendaylight.yangtools.yang.common.ErrorType;
80 import org.opendaylight.yangtools.yang.common.RpcResult;
81 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
82 import org.slf4j.Logger;
83 import org.slf4j.LoggerFactory;
84
85 /**
86  * Top level service interface providing main TAPI Connectivity services.
87  */
88 public class TapiConnectivityImpl implements TapiConnectivityService {
89
90     private static final Logger LOG = LoggerFactory.getLogger(TapiConnectivityImpl.class);
91
92     private OrgOpenroadmServiceService serviceHandler;
93     private final TapiContext tapiContext;
94     private final ConnectivityUtils connectivityUtils;
95     private TapiPceListenerImpl pceListenerImpl;
96     private TapiRendererListenerImpl rendererListenerImpl;
97
98     public TapiConnectivityImpl(OrgOpenroadmServiceService serviceHandler, TapiContext tapiContext,
99                                 ConnectivityUtils connectivityUtils, TapiPceListenerImpl pceListenerImpl,
100                                 TapiRendererListenerImpl rendererListenerImpl) {
101         LOG.info("inside TapiImpl constructor");
102         this.serviceHandler = serviceHandler;
103         this.tapiContext = tapiContext;
104         this.connectivityUtils = connectivityUtils;
105         this.pceListenerImpl = pceListenerImpl;
106         this.rendererListenerImpl = rendererListenerImpl;
107     }
108
109     @Override
110     public ListenableFuture<RpcResult<CreateConnectivityServiceOutput>> createConnectivityService(
111             CreateConnectivityServiceInput input) {
112         // TODO: later version of TAPI models include Name as an input parameter in connectivity.yang
113         LOG.info("RPC create-connectivity received: {}", input.getEndPoint());
114         Uuid serviceUuid = new Uuid(UUID.randomUUID().toString());
115         this.pceListenerImpl.setInput(input);
116         this.pceListenerImpl.setServiceUuid(serviceUuid);
117         this.rendererListenerImpl.setServiceUuid(serviceUuid);
118         ListenableFuture<RpcResult<ServiceCreateOutput>> output = null;
119         OperationResult validationResult = CreateConnectivityServiceValidation.validateCreateConnectivityServiceRequest(
120                 input);
121         if (validationResult.isSuccess()) {
122             LOG.info("input parameter of RPC create-connectivity are being handled");
123             // check uuid of SIP in tapi context
124             Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap = this.tapiContext.getTapiContext()
125                     .getServiceInterfacePoint();
126             if (sipMap == null) {
127                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
128                     .withError(ErrorType.RPC, "SIP list is empty")
129                     .buildFuture();
130             }
131             if (sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().findFirst().get()
132                     .getServiceInterfacePoint().getServiceInterfacePointUuid()))
133                     && sipMap.containsKey(new ServiceInterfacePointKey(input.getEndPoint().values().stream().skip(1)
134                     .findFirst().get().getServiceInterfacePoint().getServiceInterfacePointUuid()))) {
135                 LOG.info("SIPs found in sipMap");
136                 // TODO: differentiate between OTN service and GbE service in TAPI
137                 ServiceCreateInput sci = this.connectivityUtils.createORServiceInput(input, serviceUuid);
138                 if (sci == null) {
139                     return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
140                         .withError(ErrorType.RPC, "Couldnt map Service create input")
141                         .buildFuture();
142                 }
143                 LOG.info("Service Create input = {}", sci);
144                 output = this.serviceHandler.serviceCreate(sci);
145                 if (!output.isDone()) {
146                     return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
147                         .withError(ErrorType.RPC, "Service create RPC failed")
148                         .buildFuture();
149                 }
150             } else {
151                 LOG.error("Unknown UUID");
152                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
153                     .withError(ErrorType.RPC, "SIPs do not exist in tapi context")
154                     .buildFuture();
155             }
156         }
157         try {
158             if (output == null) {
159                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
160                     .withError(ErrorType.RPC, "Failed to create service")
161                     .buildFuture();
162             }
163             LOG.info("Service create request was successful");
164             if (output.get().getResult().getConfigurationResponseCommon().getResponseCode()
165                     .equals(ResponseCodes.RESPONSE_FAILED)) {
166                 return RpcResultBuilder.<CreateConnectivityServiceOutput>failed()
167                     .withError(ErrorType.RPC, "Failed to create service")
168                     .buildFuture();
169             }
170             LOG.info("Output of service request = {}", output.get().getResult());
171         } catch (InterruptedException | ExecutionException e) {
172             LOG.error("Error checking response code of service create", e);
173         }
174         // Connections and states should be created/updated when the pce and renderer are done :)
175         Map<EndPointKey, EndPoint> endPointList = createEndPoints(input.getEndPoint());
176         Name name = new NameBuilder()
177             .setValueName("Connectivity Service Name")
178             .setValue(serviceUuid.getValue())
179             .build();
180         ConnectivityService service = new ConnectivityServiceBuilder()
181             .setUuid(serviceUuid)
182             .setAdministrativeState(AdministrativeState.LOCKED)
183             .setOperationalState(OperationalState.DISABLED)
184             .setLifecycleState(LifecycleState.PLANNED)
185             .setServiceLayer(input.getConnectivityConstraint().getServiceLayer())
186             .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY)
187             .setConnectivityDirection(ForwardingDirection.BIDIRECTIONAL)
188             .setName(Map.of(name.key(), name))
189             .setConnection(new HashMap<>())
190             .setEndPoint(endPointList)
191             .build();
192         // add to tapi context
193         this.tapiContext.updateConnectivityContext(Map.of(service.key(), service), new HashMap<>());
194         LOG.info("Created locked service in Datastore. Waiting for PCE and Renderer to complete tasks...");
195         // return ConnectivityServiceCreateOutput
196         return RpcResultBuilder.success(new CreateConnectivityServiceOutputBuilder()
197             .setService(new ServiceBuilder(service).build()).build()).buildFuture();
198     }
199
200     private Map<EndPointKey, EndPoint> createEndPoints(
201             Map<org.opendaylight.yang.gen.v1.urn
202                 .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPointKey,
203                 org.opendaylight.yang.gen.v1.urn
204                     .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint> endPoints) {
205         Map<EndPointKey, EndPoint> endPointMap = new HashMap<>();
206         for (org.opendaylight.yang.gen.v1.urn
207                 .onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint ep:
208                 endPoints.values()) {
209             EndPoint endpoint = new EndPointBuilder()
210                 .setServiceInterfacePoint(new ServiceInterfacePointBuilder()
211                     .setServiceInterfacePointUuid(ep.getServiceInterfacePoint().getServiceInterfacePointUuid())
212                     .build())
213                 .setName(ep.getName())
214                 .setAdministrativeState(ep.getAdministrativeState())
215                 .setDirection(ep.getDirection())
216                 .setLifecycleState(ep.getLifecycleState())
217                 .setOperationalState(ep.getOperationalState())
218                 .setLayerProtocolName(ep.getLayerProtocolName())
219                 .setCapacity(new CapacityBuilder()
220                     .setTotalSize(new TotalSizeBuilder().build())
221                     .setBandwidthProfile(new BandwidthProfileBuilder().build()) // TODO: implement bandwidth profile
222                     .build())
223                 .setProtectionRole(ep.getProtectionRole())
224                 .setRole(ep.getRole())
225                 .setLocalId(ep.getLocalId())
226                 .build();
227             endPointMap.put(endpoint.key(), endpoint);
228         }
229         return endPointMap;
230     }
231
232     @Override
233     public ListenableFuture<RpcResult<GetConnectivityServiceDetailsOutput>> getConnectivityServiceDetails(
234             GetConnectivityServiceDetailsInput input) {
235         // TODO Auto-generated method stub
236         Uuid serviceUuid = getUuidFromIput(input.getServiceIdOrName());
237         ConnectivityService service = this.tapiContext.getConnectivityService(serviceUuid);
238         if (service == null) {
239             LOG.error("Service {} doesnt exist in tapi context", input.getServiceIdOrName());
240             return RpcResultBuilder.<GetConnectivityServiceDetailsOutput>failed()
241                 .withError(ErrorType.RPC, "Service doesnt exist in datastore")
242                 .buildFuture();
243         }
244         return RpcResultBuilder.success(new GetConnectivityServiceDetailsOutputBuilder().setService(
245             new org.opendaylight.yang.gen.v1.urn
246                 .onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.details.output.ServiceBuilder(
247                     service).build()).build()).buildFuture();
248     }
249
250     @Override
251     public ListenableFuture<RpcResult<UpdateConnectivityServiceOutput>> updateConnectivityService(
252             UpdateConnectivityServiceInput input) {
253         // TODO Auto-generated method stub. More complicated as it depends on what needs to be updated... left aside
254         return null;
255     }
256
257     @Override
258     public ListenableFuture<RpcResult<GetConnectionDetailsOutput>> getConnectionDetails(
259             GetConnectionDetailsInput input) {
260         // TODO Auto-generated method stub
261         Uuid connectionUuid = getUuidFromIput(input.getConnectionIdOrName());
262         Connection connection = this.tapiContext.getConnection(connectionUuid);
263         if (connection == null) {
264             LOG.error("Connection {} doesnt exist in tapi context", input.getConnectionIdOrName());
265             return RpcResultBuilder.<GetConnectionDetailsOutput>failed()
266                 .withError(ErrorType.RPC, "Connection doesnt exist in datastore")
267                 .buildFuture();
268         }
269         return RpcResultBuilder.success(new GetConnectionDetailsOutputBuilder().setConnection(
270                 new ConnectionBuilder(connection).build()).build()).buildFuture();
271     }
272
273     @Override
274     public ListenableFuture<RpcResult<DeleteConnectivityServiceOutput>> deleteConnectivityService(
275             DeleteConnectivityServiceInput input) {
276         //TODO Auto-generated method stub
277         // TODO add try
278         if (input.getServiceIdOrName() != null) {
279             try {
280                 Uuid serviceUuid = getUuidFromIput(input.getServiceIdOrName());
281                 this.tapiContext.deleteConnectivityService(serviceUuid);
282                 ListenableFuture<RpcResult<ServiceDeleteOutput>> output =
283                     this.serviceHandler.serviceDelete(new ServiceDeleteInputBuilder()
284                         .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
285                             .setServiceName(input.getServiceIdOrName())
286                             .setTailRetention(ServiceDeleteReqInfo.TailRetention.No)
287                             .build())
288                         .setSdncRequestHeader(new SdncRequestHeaderBuilder()
289                             .setRequestId("request-1")
290                             .setNotificationUrl("notification url")
291                             .setRequestSystemId("appname")
292                             .setRpcAction(RpcActions.ServiceDelete)
293                             .build())
294                         .build());
295                 RpcResult<ServiceDeleteOutput> rpcResult = output.get();
296                 if (!rpcResult.getResult().getConfigurationResponseCommon().getResponseCode()
297                         .equals(ResponseCodes.RESPONSE_FAILED)) {
298                     LOG.info("Service is being deleted and devices are being rolled back");
299                     return RpcResultBuilder.success(new DeleteConnectivityServiceOutputBuilder().build()).buildFuture();
300                 }
301                 LOG.error("Failed to delete service. Deletion process failed");
302             } catch (InterruptedException | ExecutionException e) {
303                 LOG.error("Failed to delete service.", e);
304             }
305         }
306         return RpcResultBuilder.<DeleteConnectivityServiceOutput>failed()
307             .withError(ErrorType.RPC, "Failed to delete Service")
308             .buildFuture();
309     }
310
311     @Override
312     public ListenableFuture<RpcResult<GetConnectivityServiceListOutput>> getConnectivityServiceList(
313             GetConnectivityServiceListInput input) {
314         // TODO Auto-generated method stub
315         Map<ConnectivityServiceKey, ConnectivityService> connMap = this.tapiContext.getConnectivityServices();
316         if (connMap == null) {
317             LOG.error("No services in tapi context");
318             return RpcResultBuilder.<GetConnectivityServiceListOutput>failed()
319                 .withError(ErrorType.RPC, "No services exist in datastore")
320                 .buildFuture();
321         }
322
323         Map<ServiceKey, Service> serviceMap = new HashMap<>();
324         for (ConnectivityService connectivityService: connMap.values()) {
325             Service service = new org.opendaylight.yang.gen.v1.urn
326                 .onf.otcc.yang.tapi.connectivity.rev181210.get.connectivity.service.list.output.ServiceBuilder(
327                     connectivityService).build();
328             serviceMap.put(service.key(), service);
329         }
330         return RpcResultBuilder.success(new GetConnectivityServiceListOutputBuilder().setService(serviceMap)
331             .build()).buildFuture();
332     }
333
334     @Override
335     public ListenableFuture<RpcResult<GetConnectionEndPointDetailsOutput>> getConnectionEndPointDetails(
336             GetConnectionEndPointDetailsInput input) {
337         // TODO Auto-generated method stub
338         Uuid topoUuid = getUuidFromIput(input.getTopologyIdOrName());
339         Uuid nodeUuid = getUuidFromIput(input.getNodeIdOrName());
340         Uuid nepUuid = getUuidFromIput(input.getNepIdOrName());
341         Uuid cepUuid = getUuidFromIput(input.getCepIdOrName());
342         ConnectionEndPoint cep = this.tapiContext.getTapiCEP(topoUuid, nodeUuid, nepUuid, cepUuid);
343         if (cep == null) {
344             LOG.error("Cep doesnt exist in tapi context");
345             return RpcResultBuilder.<GetConnectionEndPointDetailsOutput>failed()
346                 .withError(ErrorType.RPC, "No cep with given Uuid exists in datastore")
347                 .buildFuture();
348         }
349         return RpcResultBuilder.success(new GetConnectionEndPointDetailsOutputBuilder().setConnectionEndPoint(
350             new ConnectionEndPointBuilder(cep).build()).build()).buildFuture();
351     }
352
353     private Uuid getUuidFromIput(String serviceIdOrName) {
354         try {
355             UUID.fromString(serviceIdOrName);
356             LOG.info("Given attribute {} is a UUID", serviceIdOrName);
357             return new Uuid(serviceIdOrName);
358         } catch (IllegalArgumentException e) {
359             LOG.info("Given attribute {} is not a UUID", serviceIdOrName);
360             return new Uuid(UUID.nameUUIDFromBytes(serviceIdOrName.getBytes(StandardCharsets.UTF_8)).toString());
361         }
362     }
363 }