2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.northbound.asdcapi;
24 import com.google.common.base.Optional;
25 import com.google.common.util.concurrent.FluentFuture;
26 import com.google.common.util.concurrent.Futures;
27 import com.google.common.util.concurrent.ListenableFuture;
28 import java.util.Properties;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.ExecutorService;
31 import java.util.concurrent.Executors;
32 import org.eclipse.jdt.annotation.NonNull;
33 import org.opendaylight.mdsal.binding.api.DataBroker;
34 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
35 import org.opendaylight.mdsal.binding.api.ReadTransaction;
36 import org.opendaylight.mdsal.binding.api.RpcProviderService;
37 import org.opendaylight.mdsal.binding.api.WriteTransaction;
38 import org.opendaylight.mdsal.common.api.CommitInfo;
39 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
40 import org.opendaylight.yang.gen.v1.http.xmlns.onap.org.asdc.license.model._1._0.rev160427.vf.license.model.grouping.VfLicenseModel;
41 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.ASDCAPIService;
42 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.Artifacts;
43 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.ArtifactsBuilder;
44 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelUpdateInput;
45 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelUpdateInputBuilder;
46 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelUpdateOutput;
47 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelUpdateOutputBuilder;
48 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelVersions;
49 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.VfLicenseModelVersionsBuilder;
50 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.artifacts.Artifact;
51 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.artifacts.ArtifactBuilder;
52 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.artifacts.ArtifactKey;
53 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.vf.license.model.versions.VfLicenseModelVersion;
54 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev170201.vf.license.model.versions.VfLicenseModelVersionBuilder;
55 import org.opendaylight.yangtools.concepts.ObjectRegistration;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.common.RpcResult;
58 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
63 * Defines a base implementation for your provider. This class extends from a helper class
64 * which provides storage for the most commonly used components of the MD-SAL. Additionally the
65 * base class provides some basic logging and initialization / clean up methods.
67 * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule
68 * class which is auto generated under src/main/java in this project
69 * (created only once during first compilation):
74 public java.lang.AutoCloseable createInstance() {
76 final asdcApiProvider provider = new asdcApiProvider();
77 provider.setDataBroker( getDataBrokerDependency() );
78 provider.setNotificationService( getNotificationServiceDependency() );
79 provider.setRpcRegistry( getRpcRegistryDependency() );
80 provider.initialize();
81 return new AutoCloseable() {
84 public void close() throws Exception {
85 //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
95 public class AsdcApiProvider implements AutoCloseable, ASDCAPIService {
97 private static final Logger LOG = LoggerFactory.getLogger(AsdcApiProvider.class);
99 private static final String ACTIVE_VERSION = "active";
101 private static final String APPLICATION_NAME = "asdcApi";
103 private final ExecutorService executor;
104 protected DataBroker dataBroker;
105 protected NotificationPublishService notificationService;
106 protected RpcProviderService rpcRegistry;
107 private final AsdcApiSliClient asdcApiSliClient;
109 protected ObjectRegistration<ASDCAPIService> rpcRegistration;
111 public AsdcApiProvider(final DataBroker dataBroker,
112 final NotificationPublishService notificationPublishService,
113 final RpcProviderService rpcProviderRegistry,
114 final AsdcApiSliClient asdcApiSliClient) {
116 LOG.info("Creating provider for {}", APPLICATION_NAME);
117 executor = Executors.newFixedThreadPool(1);
118 this.dataBroker = dataBroker;
119 notificationService = notificationPublishService;
120 rpcRegistry = rpcProviderRegistry;
121 this.asdcApiSliClient= asdcApiSliClient;
125 public void initialize(){
126 LOG.info("Initializing {} for {}", this.getClass().getName(), APPLICATION_NAME);
130 if (rpcRegistration == null) {
131 if (rpcRegistry != null) {
132 rpcRegistration = rpcRegistry.registerRpcImplementation(
133 ASDCAPIService.class, this);
134 LOG.info("Initialization complete for {}", APPLICATION_NAME);
136 LOG.warn("Error initializing {} : rpcRegistry unset", APPLICATION_NAME);
141 private void createContainers() {
143 if (dataBroker != null) {
144 final WriteTransaction t = dataBroker.newReadWriteTransaction();
146 // Create the vf-model-license-versions and artifacts containers
147 t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(VfLicenseModelVersions.class),
148 new VfLicenseModelVersionsBuilder().build());
150 t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Artifacts.class), new ArtifactsBuilder().build());
154 FluentFuture<? extends @NonNull CommitInfo> checkedFuture = t.commit();
156 LOG.info("Create Containers succeeded!: ");
158 } catch (InterruptedException | ExecutionException e) {
159 LOG.error("Create Containers Failed: ", e);
162 LOG.warn("createContainers : cannot find dataBroker to create containers");
165 protected void initializeChild() {
166 //Override if you have custom initialization intelligence
170 public void close() throws Exception {
171 LOG.info( "Closing provider for " + APPLICATION_NAME);
173 rpcRegistration.close();
174 LOG.info( "Successfully closed provider for " + APPLICATION_NAME);
177 protected boolean artifactVersionExists(String aName, String aVersion) {
178 InstanceIdentifier artifactInstanceId =
179 InstanceIdentifier.<Artifacts>builder(Artifacts.class)
180 .child(Artifact.class, new ArtifactKey(aName, aVersion)).build();
181 Optional<Artifact> data = null;
182 try(ReadTransaction readTx = dataBroker.newReadOnlyTransaction()) {
183 data = (Optional<Artifact>) readTx.read(LogicalDatastoreType.CONFIGURATION, artifactInstanceId).get();
184 } catch (InterruptedException | ExecutionException e) {
185 LOG.error("Caught Exception reading MD-SAL for ["+aName+","+ aVersion+"] " ,e);
189 return data.isPresent();
192 protected void addArtifactVersion(String aName, String aVersion) {
196 ArtifactBuilder aBuilder = new ArtifactBuilder();
198 aBuilder.setArtifactName(aName);
199 aBuilder.setArtifactVersion(aVersion);
201 Artifact artifact = aBuilder.build();
203 InstanceIdentifier.InstanceIdentifierBuilder<Artifact> aIdBuilder = InstanceIdentifier
204 .<Artifacts> builder(Artifacts.class)
205 .child(Artifact.class, artifact.key());
207 InstanceIdentifier<Artifact> path = aIdBuilder.build();
209 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
211 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
214 } catch (Exception e) {
215 LOG.error("Caught exception trying to add artifact entry", e);
221 private void applyVfLicenseModelUpdate(VfLicenseModelUpdateInput input) {
223 String aName = input.getArtifactName();
224 String aVersion = input.getArtifactVersion();
225 VfLicenseModel vfLicenseModel = input.getVfLicenseModel();
228 // Add new version (version = artifact-version)
231 VfLicenseModelVersionBuilder vBuilder = new VfLicenseModelVersionBuilder();
232 vBuilder.setArtifactName(aName);
233 vBuilder.setArtifactVersion(aVersion);
234 vBuilder.setVfLicenseModel(vfLicenseModel);
236 VfLicenseModelVersion version = vBuilder.build();
238 InstanceIdentifier.InstanceIdentifierBuilder<VfLicenseModelVersion> versionIdBuilder = InstanceIdentifier
239 .<VfLicenseModelVersions> builder(VfLicenseModelVersions.class)
240 .child(VfLicenseModelVersion.class, version.key());
242 InstanceIdentifier<VfLicenseModelVersion> path = versionIdBuilder.build();
244 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
245 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
248 } catch (Exception e) {
250 "Caught exception trying to save entry to MD-SAL",
255 // Add "active" version (version = "active")
258 VfLicenseModelVersionBuilder vBuilder = new VfLicenseModelVersionBuilder();
259 vBuilder.setArtifactName(aName);
260 vBuilder.setArtifactVersion(ACTIVE_VERSION);
261 vBuilder.setVfLicenseModel(vfLicenseModel);
263 VfLicenseModelVersion version = vBuilder.build();
264 InstanceIdentifier.InstanceIdentifierBuilder<VfLicenseModelVersion> versionIdBuilder = InstanceIdentifier
265 .<VfLicenseModelVersions> builder(VfLicenseModelVersions.class)
266 .child(VfLicenseModelVersion.class, version.key());
268 InstanceIdentifier<VfLicenseModelVersion> path = versionIdBuilder.build();
270 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
272 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
275 } catch (Exception e) {
277 "Caught exception trying to save entry to MD-SAL",
284 public ListenableFuture<RpcResult<VfLicenseModelUpdateOutput>> vfLicenseModelUpdate(VfLicenseModelUpdateInput input) {
285 final String svcOperation = "vf-license-model-update";
287 Properties parms = new Properties();
289 LOG.info( svcOperation +" called." );
292 LOG.debug("exiting " +svcOperation+ " because of invalid input");
296 VfLicenseModelUpdateInputBuilder inputBuilder = new VfLicenseModelUpdateInputBuilder(input);
298 VfLicenseModelUpdateInput inputVfLic = inputBuilder.build();
300 String errorMessage = "Success";
301 String errorCode = "200";
303 // If this artifact already exists, reject this update
304 if (artifactVersionExists(inputVfLic.getArtifactName(), inputVfLic.getArtifactVersion())) {
306 errorMessage = "Artifact version already exists";
308 // Translate input object into SLI-consumable properties
309 LOG.info("Adding INPUT data for "+svcOperation+" input: " + inputVfLic);
310 AsdcApiUtil.toProperties(parms, inputVfLic);
313 // Call directed graph
314 Properties respProps = null;
317 if (asdcApiSliClient.hasGraph("ASDC-API", svcOperation , null, "sync"))
322 respProps = asdcApiSliClient.execute("ASDC-API", svcOperation, null, "sync", parms);
326 LOG.error("Caught exception executing service logic for "+ svcOperation, e);
329 errorMessage = "No service logic active for ASDC-API: '" + svcOperation + "'";
336 errorMessage = e.getMessage();
337 LOG.error("Caught exception looking for service logic", e);
341 if (respProps != null)
343 errorCode = respProps.getProperty("error-code");
344 errorMessage = respProps.getProperty("error-message", "");
349 if ("200".equals(errorCode)) {
350 LOG.info("ASDC update succeeded");
352 // Update config tree
353 applyVfLicenseModelUpdate(inputVfLic);
354 addArtifactVersion(inputVfLic.getArtifactName(), inputVfLic.getArtifactVersion());
357 LOG.info("ASDC update failed ("+errorCode+" : "+errorMessage);
361 VfLicenseModelUpdateOutputBuilder respBuilder = new VfLicenseModelUpdateOutputBuilder();
362 respBuilder.setAsdcApiResponseCode(errorCode);
363 if (errorMessage != null && errorMessage.length() > 0) {
364 respBuilder.setAsdcApiResponseText(errorMessage);
367 RpcResult<VfLicenseModelUpdateOutput> rpcResult;
370 rpcResult = RpcResultBuilder.<VfLicenseModelUpdateOutput> status(true).withResult(respBuilder.build()).build();
374 return Futures.immediateFuture(rpcResult);