2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
 
   7  *      Modifications Copyright © 2018 IBM.
 
   8  * ================================================================================
 
   9  * Licensed under the Apache License, Version 2.0 (the "License");
 
  10  * you may not use this file except in compliance with the License.
 
  11  * You may obtain a copy of the License at
 
  13  *      http://www.apache.org/licenses/LICENSE-2.0
 
  15  * Unless required by applicable law or agreed to in writing, software
 
  16  * distributed under the License is distributed on an "AS IS" BASIS,
 
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  18  * See the License for the specific language governing permissions and
 
  19  * limitations under the License.
 
  20  * ============LICENSE_END=========================================================
 
  23 package org.onap.ccsdk.features.sdnr.northbound.ranSlice;
 
  25 import java.text.SimpleDateFormat;
 
  26 import java.util.Date;
 
  27 import java.util.Properties;
 
  28 import java.util.concurrent.ExecutorService;
 
  29 import java.util.concurrent.Executors;
 
  30 import java.util.concurrent.Future;
 
  31 import org.onap.ccsdk.sli.core.sli.provider.MdsalHelper;
 
  32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 
  33 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 
  34 import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
 
  35 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 
  36 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 
  37 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 
  38 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev200806.*;
 
  39 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev200806.common.header.CommonHeaderBuilder;
 
  40 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev200806.status.StatusBuilder;
 
  41 import org.opendaylight.yangtools.yang.common.RpcResult;
 
  42 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 
  43 import org.slf4j.Logger;
 
  44 import org.slf4j.LoggerFactory;
 
  46 import com.google.common.util.concurrent.Futures;
 
  47 import com.google.common.util.concurrent.ListenableFuture;
 
  49 import org.onap.ccsdk.features.sdnr.northbound.ranSlice.RANSliceResponseCode.*;
 
  52  * Defines a base implementation for your provider. This class extends from a
 
  53  * helper class which provides storage for the most commonly used components of
 
  54  * the MD-SAL. Additionally the base class provides some basic logging and
 
  55  * initialization / clean up methods.
 
  58 public class RANSliceProvider implements AutoCloseable, RanSliceApiService {
 
  60         private class CommonRANSliceFields {
 
  61                 private StatusBuilder statusBuilder;
 
  62                 private CommonHeaderBuilder commonHeaderBuilder;
 
  63                 private Payload payload;
 
  65                 public CommonRANSliceFields(StatusBuilder statusBuilder, CommonHeaderBuilder commonHeaderBuilder) {
 
  66                         this.statusBuilder = statusBuilder;
 
  67                         this.commonHeaderBuilder = commonHeaderBuilder;
 
  71                 public CommonRANSliceFields(StatusBuilder statusBuilder, CommonHeaderBuilder commonHeaderBuilder, Payload payload) {
 
  72                         this.statusBuilder = statusBuilder;
 
  73                         this.commonHeaderBuilder = commonHeaderBuilder;
 
  74                         this.payload = payload;
 
  77                 public StatusBuilder getStatusBuilder() {
 
  81                 public CommonHeaderBuilder getCommonHeaderBuilder() {
 
  82                         return commonHeaderBuilder;
 
  85                 public Payload getPayload() {
 
  90         private static final Logger LOG = LoggerFactory.getLogger(RANSliceProvider.class);
 
  92         private static final String exceptionMessage = "Caught exception";
 
  94         private static final String APPLICATION_NAME = "RANSlice";
 
  96         private final ExecutorService executor;
 
  97         protected DataBroker dataBroker;
 
  98         protected DOMDataBroker domDataBroker;
 
  99         protected NotificationPublishService notificationService;
 
 100         protected RpcProviderRegistry rpcRegistry;
 
 101         private final RANSliceClient RANSliceClient;
 
 103         protected BindingAwareBroker.RpcRegistration<RanSliceApiService> rpcRegistration;
 
 105         public RANSliceProvider(final DataBroker dataBroker, final NotificationPublishService notificationPublishService,
 
 106                         final RpcProviderRegistry rpcProviderRegistry, final RANSliceClient rANSliceClient) {
 
 108                 LOG.info("Creating provider for {}", APPLICATION_NAME);
 
 109                 executor = Executors.newFixedThreadPool(1);
 
 110                 this.dataBroker = dataBroker;
 
 111                 if (dataBroker instanceof AbstractForwardedDataBroker) {
 
 112                         domDataBroker = ((AbstractForwardedDataBroker) dataBroker).getDelegate();
 
 114                 notificationService = notificationPublishService;
 
 115                 rpcRegistry = rpcProviderRegistry;
 
 116                 this.RANSliceClient = rANSliceClient;
 
 120         public void initialize() {
 
 121                 LOG.info("Initializing {} for {}", this.getClass().getName(), APPLICATION_NAME);
 
 123                 if (rpcRegistration == null) {
 
 124                         if (rpcRegistry != null) {
 
 125                                 rpcRegistration = rpcRegistry.addRpcImplementation(RanSliceApiService.class, this);
 
 126                                 LOG.info("Initialization complete for {}", APPLICATION_NAME);
 
 128                                 LOG.warn("Error initializing {} : rpcRegistry unset", APPLICATION_NAME);
 
 133         protected void initializeChild() {
 
 134                 // Override if you have custom initialization intelligence
 
 138         public void close() throws Exception {
 
 139                 LOG.info("Closing provider for " + APPLICATION_NAME);
 
 141                 rpcRegistration.close();
 
 142                 LOG.info("Successfully closed provider for " + APPLICATION_NAME);
 
 146 //RPC configureNearRTRIC
 
 149         public ListenableFuture<RpcResult<ConfigureNearRTRICOutput>> configureNearRTRIC(ConfigureNearRTRICInput input) {
 
 150                 ConfigureNearRTRICInputBuilder iBuilder = new ConfigureNearRTRICInputBuilder(input);
 
 151                 ConfigureNearRTRICOutputBuilder oBuilder = new ConfigureNearRTRICOutputBuilder();
 
 154                         CommonRANSliceFields retval = callDG("configureNearRTRIC", iBuilder.build());
 
 155                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 156                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 157                 } catch (RANSliceRpcInvocationException e) {
 
 158                         LOG.debug(exceptionMessage, e);
 
 159                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 160                         oBuilder.setStatus(e.getStatus());
 
 163                 RpcResult<ConfigureNearRTRICOutput> rpcResult =
 
 164                                 RpcResultBuilder.<ConfigureNearRTRICOutput> status(true).withResult(oBuilder.build()).build();
 
 166                 return Futures.immediateFuture(rpcResult);
 
 170         //RPC instantiateRANSlice
 
 173         public ListenableFuture<RpcResult<InstantiateRANSliceOutput>> instantiateRANSlice(InstantiateRANSliceInput input) {
 
 174                 InstantiateRANSliceInputBuilder iBuilder = new InstantiateRANSliceInputBuilder(input);
 
 175                 InstantiateRANSliceOutputBuilder oBuilder = new InstantiateRANSliceOutputBuilder();
 
 178                         CommonRANSliceFields retval = callDG("instantiateRANSlice", iBuilder.build());
 
 179                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 180                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 181                 } catch (RANSliceRpcInvocationException e) {
 
 182                         LOG.debug(exceptionMessage, e);
 
 183                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 184                         oBuilder.setStatus(e.getStatus());
 
 187                 RpcResult<InstantiateRANSliceOutput> rpcResult =
 
 188                                 RpcResultBuilder.<InstantiateRANSliceOutput> status(true).withResult(oBuilder.build()).build();
 
 190                 return Futures.immediateFuture(rpcResult);
 
 196         //RPC configureRANSliceInstance
 
 199         public ListenableFuture<RpcResult<ConfigureRANSliceInstanceOutput>> configureRANSliceInstance(ConfigureRANSliceInstanceInput input) {
 
 200                 ConfigureRANSliceInstanceInputBuilder iBuilder = new ConfigureRANSliceInstanceInputBuilder(input);
 
 201                 ConfigureRANSliceInstanceOutputBuilder oBuilder = new ConfigureRANSliceInstanceOutputBuilder();
 
 204                         CommonRANSliceFields retval = callDG("configureRANSliceInstance", iBuilder.build());
 
 205                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 206                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 207                 } catch (RANSliceRpcInvocationException e) {
 
 208                         LOG.debug(exceptionMessage, e);
 
 209                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 210                         oBuilder.setStatus(e.getStatus());
 
 213                 RpcResult<ConfigureRANSliceInstanceOutput> rpcResult =
 
 214                                 RpcResultBuilder.<ConfigureRANSliceInstanceOutput> status(true).withResult(oBuilder.build()).build();
 
 216                 return Futures.immediateFuture(rpcResult);
 
 223         public ListenableFuture<RpcResult<ConfigureCUOutput>> configureCU(ConfigureCUInput input) {
 
 224                 ConfigureCUInputBuilder iBuilder = new ConfigureCUInputBuilder(input);
 
 225                 ConfigureCUOutputBuilder oBuilder = new ConfigureCUOutputBuilder();
 
 228                         CommonRANSliceFields retval = callDG("configureCU", iBuilder.build());
 
 229                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 230                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 231                 } catch (RANSliceRpcInvocationException e) {
 
 232                         LOG.debug(exceptionMessage, e);
 
 233                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 234                         oBuilder.setStatus(e.getStatus());
 
 237                 RpcResult<ConfigureCUOutput> rpcResult =
 
 238                                 RpcResultBuilder.<ConfigureCUOutput> status(true).withResult(oBuilder.build()).build();
 
 240                 return Futures.immediateFuture(rpcResult);
 
 247         public ListenableFuture<RpcResult<ConfigureDUOutput>> configureDU(ConfigureDUInput input) {
 
 248                 ConfigureDUInputBuilder iBuilder = new ConfigureDUInputBuilder(input);
 
 249                 ConfigureDUOutputBuilder oBuilder = new ConfigureDUOutputBuilder();
 
 252                         CommonRANSliceFields retval = callDG("configureDU", iBuilder.build());
 
 253                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 254                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 255                 } catch (RANSliceRpcInvocationException e) {
 
 256                         LOG.debug(exceptionMessage, e);
 
 257                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 258                         oBuilder.setStatus(e.getStatus());
 
 261                 RpcResult<ConfigureDUOutput> rpcResult =
 
 262                                 RpcResultBuilder.<ConfigureDUOutput> status(true).withResult(oBuilder.build()).build();
 
 264                 return Futures.immediateFuture(rpcResult);
 
 268         //RPC activateRANSliceInstance
 
 271         public ListenableFuture<RpcResult<ActivateRANSliceInstanceOutput>> activateRANSliceInstance(ActivateRANSliceInstanceInput input) {
 
 272                 ActivateRANSliceInstanceInputBuilder iBuilder = new ActivateRANSliceInstanceInputBuilder(input);
 
 273                 ActivateRANSliceInstanceOutputBuilder oBuilder = new ActivateRANSliceInstanceOutputBuilder();
 
 276                         CommonRANSliceFields retval = callDG("activateRANSliceInstance", iBuilder.build());
 
 277                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 278                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 279                 } catch (RANSliceRpcInvocationException e) {
 
 280                         LOG.debug(exceptionMessage, e);
 
 281                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 282                         oBuilder.setStatus(e.getStatus());
 
 285                 RpcResult<ActivateRANSliceInstanceOutput> rpcResult =
 
 286                                 RpcResultBuilder.<ActivateRANSliceInstanceOutput> status(true).withResult(oBuilder.build()).build();
 
 288                 return Futures.immediateFuture(rpcResult);
 
 293         //RPC deactivateRANSliceInstance
 
 296         public ListenableFuture<RpcResult<DeactivateRANSliceInstanceOutput>> deactivateRANSliceInstance(DeactivateRANSliceInstanceInput input) {
 
 297                 DeactivateRANSliceInstanceInputBuilder iBuilder = new DeactivateRANSliceInstanceInputBuilder(input);
 
 298                 DeactivateRANSliceInstanceOutputBuilder oBuilder = new DeactivateRANSliceInstanceOutputBuilder();
 
 301                         CommonRANSliceFields retval = callDG("deactivateRANSliceInstance", iBuilder.build());
 
 302                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 303                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 304                 } catch (RANSliceRpcInvocationException e) {
 
 305                         LOG.debug(exceptionMessage, e);
 
 306                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 307                         oBuilder.setStatus(e.getStatus());
 
 310                 RpcResult<DeactivateRANSliceInstanceOutput> rpcResult =
 
 311                                 RpcResultBuilder.<DeactivateRANSliceInstanceOutput> status(true).withResult(oBuilder.build()).build();
 
 313                 return Futures.immediateFuture(rpcResult);
 
 317         //RPC terminateRANSliceInstance
 
 320         public ListenableFuture<RpcResult<TerminateRANSliceInstanceOutput>> terminateRANSliceInstance(TerminateRANSliceInstanceInput input) {
 
 321                 TerminateRANSliceInstanceInputBuilder iBuilder = new TerminateRANSliceInstanceInputBuilder(input);
 
 322                 TerminateRANSliceInstanceOutputBuilder oBuilder = new TerminateRANSliceInstanceOutputBuilder();
 
 325                         CommonRANSliceFields retval = callDG("terminateRANSliceInstance", iBuilder.build());
 
 326                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 327                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 328                 } catch (RANSliceRpcInvocationException e) {
 
 329                         LOG.debug(exceptionMessage, e);
 
 330                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 331                         oBuilder.setStatus(e.getStatus());
 
 334                 RpcResult<TerminateRANSliceInstanceOutput> rpcResult =
 
 335                                 RpcResultBuilder.<TerminateRANSliceInstanceOutput> status(true).withResult(oBuilder.build()).build();
 
 337                 return Futures.immediateFuture(rpcResult);
 
 341         //RPC determineRANSliceResources
 
 344         public ListenableFuture<RpcResult<DetermineRANSliceResourcesOutput>> determineRANSliceResources(DetermineRANSliceResourcesInput input) {
 
 345                 DetermineRANSliceResourcesInputBuilder iBuilder = new DetermineRANSliceResourcesInputBuilder(input);
 
 346                 DetermineRANSliceResourcesOutputBuilder oBuilder = new DetermineRANSliceResourcesOutputBuilder();
 
 349                         CommonRANSliceFields retval = callDG("determineRANSliceResources", iBuilder.build());
 
 350                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 351                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 352                 } catch (RANSliceRpcInvocationException e) {
 
 353                         LOG.debug(exceptionMessage, e);
 
 354                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 355                         oBuilder.setStatus(e.getStatus());
 
 358                 RpcResult<DetermineRANSliceResourcesOutput> rpcResult =
 
 359                                 RpcResultBuilder.<DetermineRANSliceResourcesOutput> status(true).withResult(oBuilder.build()).build();
 
 361                 return Futures.immediateFuture(rpcResult);
 
 368         public ListenableFuture<RpcResult<ConfigNotificationOutput>> configNotification(ConfigNotificationInput input) {
 
 370                 ConfigNotificationInputBuilder iBuilder = new ConfigNotificationInputBuilder(input);
 
 371                 ConfigNotificationOutputBuilder oBuilder = new ConfigNotificationOutputBuilder();
 
 374                         CommonRANSliceFields retval = callDG("configNotification", iBuilder.build());
 
 375                         oBuilder.setStatus(retval.getStatusBuilder().build());
 
 376                         oBuilder.setCommonHeader(retval.getCommonHeaderBuilder().build());
 
 377                 } catch (RANSliceRpcInvocationException e) {
 
 378                         LOG.debug(exceptionMessage, e);
 
 379                         oBuilder.setCommonHeader(e.getCommonHeader());
 
 380                         oBuilder.setStatus(e.getStatus());
 
 383                 RpcResult<ConfigNotificationOutput> rpcResult =
 
 384                                 RpcResultBuilder.<ConfigNotificationOutput> status(true).withResult(oBuilder.build()).build();
 
 386                 return Futures.immediateFuture(rpcResult);
 
 391         private CommonRANSliceFields callDG(String rpcName, Object input) throws RANSliceRpcInvocationException {
 
 393                 StatusBuilder statusBuilder = new StatusBuilder();
 
 396                         LOG.debug("Rejecting " +rpcName+ " because of invalid input");
 
 397                         statusBuilder.setCode(RANSliceResponseCode.REJECT_INVALID_INPUT.getValue());
 
 398                         statusBuilder.setMessage("REJECT - INVALID INPUT.  Missing input");
 
 399                         CommonHeaderBuilder hBuilder = new CommonHeaderBuilder();
 
 400                         hBuilder.setApiVer("1");
 
 401                         hBuilder.setOriginatorId("unknown");
 
 402                         hBuilder.setRequestId("unset");
 
 403                         hBuilder.setTimestamp(new ZULU(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(new Date())));
 
 404                         throw new RANSliceRpcInvocationException(statusBuilder.build(), hBuilder.build());
 
 407                 CommonHeaderBuilder hBuilder = new CommonHeaderBuilder(((CommonHeader)input).getCommonHeader());
 
 409                 // add input to parms
 
 410                 LOG.info("Adding INPUT data for "+ rpcName +" input: " + input.toString());
 
 411                 Properties inputProps = new Properties();
 
 412                 MdsalHelper.toProperties(inputProps, input);
 
 414                 LOG.info("Printing SLI parameters to be passed");
 
 416         // iterate properties file to get key-value pairs
 
 417                 for (String key : inputProps.stringPropertyNames()) {
 
 418                         String value = inputProps.getProperty(key);
 
 419                         LOG.info("The SLI parameter in " + key + " is: " + value);
 
 422                 Properties respProps = new Properties();
 
 424                 // Call SLI sync method
 
 427                         if (RANSliceClient.hasGraph("ran-slice-api", rpcName , null, "sync"))
 
 431                                         respProps = RANSliceClient.execute("ran-slice-api", rpcName, null, "sync", inputProps, domDataBroker);
 
 435                                         LOG.error("Caught exception executing service logic for "+ rpcName, e);
 
 436                                         statusBuilder.setCode(RANSliceResponseCode.FAILURE_DG_FAILURE.getValue());
 
 437                                         statusBuilder.setMessage("FAILURE - DG FAILURE ("+e.getMessage()+")");
 
 438                                         throw new RANSliceRpcInvocationException(statusBuilder.build(), hBuilder.build());
 
 441                                 LOG.error("No service logic active for RANSlice: '" + rpcName + "'");
 
 443                                 statusBuilder.setCode(RANSliceResponseCode.REJECT_DG_NOT_FOUND.getValue());
 
 444                                 statusBuilder.setMessage("FAILURE - DG not found for action "+rpcName);
 
 445                                 throw new RANSliceRpcInvocationException(statusBuilder.build(), hBuilder.build());
 
 450                         LOG.error("Caught exception looking for service logic", e);
 
 452                         statusBuilder.setCode(RANSliceResponseCode.FAILURE_DG_FAILURE.getValue());
 
 453                         statusBuilder.setMessage("FAILURE - Unexpected error looking for DG ("+e.getMessage()+")");
 
 454                         throw new RANSliceRpcInvocationException(statusBuilder.build(), hBuilder.build());
 
 458                 StatusBuilder sBuilder = new StatusBuilder();
 
 459                 MdsalHelper.toBuilder(respProps, sBuilder);
 
 460                 MdsalHelper.toBuilder(respProps, hBuilder);
 
 462                 Payload payload = null;
 
 463                 String payloadValue = respProps.getProperty("payload");
 
 464                 if (payloadValue != null) {
 
 465                         payload = new Payload(payloadValue);
 
 468                 String statusCode = sBuilder.getCode().toString();
 
 470                 if (!"400".equals(statusCode)) {
 
 471                         LOG.error("Returned FAILED for "+rpcName+" error code: '" + statusCode + "'");
 
 473                         LOG.info("Returned SUCCESS for "+rpcName+" ");
 
 476                 return new CommonRANSliceFields(sBuilder, hBuilder, payload);