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.openecomp.sdnc.asdcapi;
24 import com.google.common.base.Optional;
25 import com.google.common.util.concurrent.CheckedFuture;
26 import com.google.common.util.concurrent.Futures;
27 import java.util.Properties;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.ExecutorService;
30 import java.util.concurrent.Executors;
31 import java.util.concurrent.Future;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
34 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
35 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
36 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
37 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
38 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
39 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
40 import org.opendaylight.yang.gen.v1.http.xmlns.openecomp.org.asdc.license.model._1._0.rev160427.vf.license.model.grouping.VfLicenseModel;
41 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.ASDCAPIService;
42 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.Artifacts;
43 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.ArtifactsBuilder;
44 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelUpdateInput;
45 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelUpdateInputBuilder;
46 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelUpdateOutput;
47 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelUpdateOutputBuilder;
48 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelVersions;
49 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.VfLicenseModelVersionsBuilder;
50 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.artifacts.Artifact;
51 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.artifacts.ArtifactBuilder;
52 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.artifacts.ArtifactKey;
53 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.vf.license.model.versions.VfLicenseModelVersion;
54 import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.rev170201.vf.license.model.versions.VfLicenseModelVersionBuilder;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.opendaylight.yangtools.yang.common.RpcResult;
57 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
62 * Defines a base implementation for your provider. This class extends from a helper class
63 * which provides storage for the most commonly used components of the MD-SAL. Additionally the
64 * base class provides some basic logging and initialization / clean up methods.
66 * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule
67 * class which is auto generated under src/main/java in this project
68 * (created only once during first compilation):
73 public java.lang.AutoCloseable createInstance() {
75 final asdcApiProvider provider = new asdcApiProvider();
76 provider.setDataBroker( getDataBrokerDependency() );
77 provider.setNotificationService( getNotificationServiceDependency() );
78 provider.setRpcRegistry( getRpcRegistryDependency() );
79 provider.initialize();
80 return new AutoCloseable() {
83 public void close() throws Exception {
84 //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
94 public class AsdcApiProvider implements AutoCloseable, ASDCAPIService {
96 private static final String ACTIVE_VERSION = "active";
98 private final Logger log = LoggerFactory.getLogger( AsdcApiProvider.class );
99 private final String appName = "asdcApi";
101 private final ExecutorService executor;
102 protected DataBroker dataBroker;
103 protected NotificationProviderService notificationService;
104 protected RpcProviderRegistry rpcRegistry;
106 protected BindingAwareBroker.RpcRegistration<ASDCAPIService> rpcRegistration;
108 public AsdcApiProvider(DataBroker dataBroker2,
109 NotificationProviderService notificationProviderService,
110 RpcProviderRegistry rpcProviderRegistry) {
111 this.log.info( "Creating provider for " + appName );
112 executor = Executors.newFixedThreadPool(1);
113 dataBroker = dataBroker2;
114 notificationService = notificationProviderService;
115 rpcRegistry = rpcProviderRegistry;
119 public void initialize(){
120 log.info( "Initializing provider for " + appName );
125 if (rpcRegistration == null) {
126 if (rpcRegistry != null) {
127 rpcRegistration = rpcRegistry.addRpcImplementation(
128 ASDCAPIService.class, this);
129 log.info("Initialization complete for " + appName);
131 log.warn("Error initializing " + appName
132 + " : rpcRegistry unset");
137 private void createContainers() {
139 if (dataBroker != null) {
140 final WriteTransaction t = dataBroker.newReadWriteTransaction();
142 // Create the vf-model-license-versions and artifacts containers
143 t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(VfLicenseModelVersions.class),
144 new VfLicenseModelVersionsBuilder().build());
146 t.merge(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Artifacts.class), new ArtifactsBuilder().build());
150 CheckedFuture<Void, TransactionCommitFailedException> checkedFuture = t.submit();
152 log.info("Create Containers succeeded!: ");
154 } catch (InterruptedException | ExecutionException e) {
155 log.error("Create Containers Failed: " + e);
159 log.warn("createContainers : cannot find dataBroker to create containers");
162 protected void initializeChild() {
163 //Override if you have custom initialization intelligence
167 public void close() throws Exception {
168 log.info( "Closing provider for " + appName );
170 rpcRegistration.close();
171 log.info( "Successfully closed provider for " + appName );
174 public void setDataBroker(DataBroker dataBroker) {
175 this.dataBroker = dataBroker;
176 if( log.isDebugEnabled() ){
177 log.debug( "DataBroker set to " + (dataBroker==null?"null":"non-null") + "." );
181 public void setNotificationService(
182 NotificationProviderService notificationService) {
183 this.notificationService = notificationService;
184 if( log.isDebugEnabled() ){
185 log.debug( "Notification Service set to " + (notificationService==null?"null":"non-null") + "." );
189 public void setRpcRegistry(RpcProviderRegistry rpcRegistry) {
190 this.rpcRegistry = rpcRegistry;
192 rpcRegistration = rpcRegistry.addRpcImplementation(ASDCAPIService.class, this);
194 if( log.isDebugEnabled() ){
195 log.debug( "RpcRegistry set to " + (rpcRegistry==null?"null":"non-null") + "." );
200 protected boolean artifactVersionExists(String aName, String aVersion) {
201 InstanceIdentifier artifactInstanceId =
202 InstanceIdentifier.<Artifacts>builder(Artifacts.class)
203 .child(Artifact.class, new ArtifactKey(aName, aVersion)).toInstance();
204 ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
205 Optional<Artifact> data = null;
207 data = (Optional<Artifact>) readTx.read(LogicalDatastoreType.CONFIGURATION, artifactInstanceId).get();
208 } catch (InterruptedException | ExecutionException e) {
209 log.error("Caught Exception reading MD-SAL for ["+aName+","+ aVersion+"] " ,e);
214 if (data.isPresent()) {
221 protected void addArtifactVersion(String aName, String aVersion) {
225 ArtifactBuilder aBuilder = new ArtifactBuilder();
227 aBuilder.setArtifactName(aName);
228 aBuilder.setArtifactVersion(aVersion);
230 Artifact artifact = aBuilder.build();
232 InstanceIdentifier.InstanceIdentifierBuilder<Artifact> aIdBuilder = InstanceIdentifier
233 .<Artifacts> builder(Artifacts.class)
234 .child(Artifact.class, artifact.getKey());
236 InstanceIdentifier<Artifact> path = aIdBuilder
239 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
241 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
243 tx.submit().checkedGet();
244 } catch (Exception e) {
245 log.error("Caught exception trying to add artifact entry", e);
251 private void applyVfLicenseModelUpdate(VfLicenseModelUpdateInput input) {
253 String aName = input.getArtifactName();
254 String aVersion = input.getArtifactVersion();
255 VfLicenseModel vfLicenseModel = input.getVfLicenseModel();
258 // Add new version (version = artifact-version)
261 VfLicenseModelVersionBuilder vBuilder = new VfLicenseModelVersionBuilder();
262 vBuilder.setArtifactName(aName);
263 vBuilder.setArtifactVersion(aVersion);
264 vBuilder.setVfLicenseModel(vfLicenseModel);
266 VfLicenseModelVersion version = vBuilder.build();
268 InstanceIdentifier.InstanceIdentifierBuilder<VfLicenseModelVersion> versionIdBuilder = InstanceIdentifier
269 .<VfLicenseModelVersions> builder(VfLicenseModelVersions.class)
270 .child(VfLicenseModelVersion.class, version.getKey());
272 InstanceIdentifier<VfLicenseModelVersion> path = versionIdBuilder
275 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
276 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
278 tx.submit().checkedGet();
279 } catch (Exception e) {
281 "Caught exception trying to save entry to MD-SAL",
286 // Add "active" version (version = "active")
289 VfLicenseModelVersionBuilder vBuilder = new VfLicenseModelVersionBuilder();
290 vBuilder.setArtifactName(aName);
291 vBuilder.setArtifactVersion(ACTIVE_VERSION);
292 vBuilder.setVfLicenseModel(vfLicenseModel);
294 VfLicenseModelVersion version = vBuilder.build();
295 InstanceIdentifier.InstanceIdentifierBuilder<VfLicenseModelVersion> versionIdBuilder = InstanceIdentifier
296 .<VfLicenseModelVersions> builder(VfLicenseModelVersions.class)
297 .child(VfLicenseModelVersion.class, version.getKey());
299 InstanceIdentifier<VfLicenseModelVersion> path = versionIdBuilder
302 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
304 tx.merge(LogicalDatastoreType.CONFIGURATION, path,
306 tx.submit().checkedGet();
307 } catch (Exception e) {
309 "Caught exception trying to save entry to MD-SAL",
316 public Future<RpcResult<VfLicenseModelUpdateOutput>> vfLicenseModelUpdate(VfLicenseModelUpdateInput input) {
317 final String SVC_OPERATION = "vf-license-model-update";
319 Properties parms = new Properties();
321 log.info( SVC_OPERATION +" called." );
324 log.debug("exiting " +SVC_OPERATION+ " because of invalid input");
328 VfLicenseModelUpdateInputBuilder inputBuilder = new VfLicenseModelUpdateInputBuilder(input);
329 input = inputBuilder.build();
331 String errorMessage = "Success";
332 String errorCode = "200";
334 // If this artifact already exists, reject this update
335 if (artifactVersionExists(input.getArtifactName(), input.getArtifactVersion())) {
337 errorMessage = "Artifact version already exists";
339 // Translate input object into SLI-consumable properties
340 log.info("Adding INPUT data for "+SVC_OPERATION+" input: " + input);
341 AsdcApiUtil.toProperties(parms, input);
344 // Call directed graph
346 Properties respProps = null;
349 AsdcApiSliClient sliClient = new AsdcApiSliClient();
352 if (sliClient.hasGraph("ASDC-API", SVC_OPERATION , null, "sync"))
357 respProps = sliClient.execute("ASDC-API", SVC_OPERATION, null, "sync", parms);
361 log.error("Caught exception executing service logic for "+ SVC_OPERATION, e);
364 errorMessage = "No service logic active for ASDC-API: '" + SVC_OPERATION + "'";
371 errorMessage = e.getMessage();
372 log.error("Caught exception looking for service logic", e);
376 if (respProps != null)
378 errorCode = respProps.getProperty("error-code");
379 errorMessage = respProps.getProperty("error-message", "");
384 if ("200".equals(errorCode)) {
385 log.info("ASDC update succeeded");
387 // Update config tree
388 applyVfLicenseModelUpdate(input);
389 addArtifactVersion(input.getArtifactName(), input.getArtifactVersion());
392 log.info("ASDC update failed ("+errorCode+" : "+errorMessage);
396 VfLicenseModelUpdateOutputBuilder respBuilder = new VfLicenseModelUpdateOutputBuilder();
397 respBuilder.setAsdcApiResponseCode(errorCode);
398 if (errorMessage != null && errorMessage.length() > 0) {
399 respBuilder.setAsdcApiResponseText(errorMessage);
402 RpcResult<VfLicenseModelUpdateOutput> rpcResult;
405 rpcResult = RpcResultBuilder.<VfLicenseModelUpdateOutput> status(true).withResult(respBuilder.build()).build();
409 return Futures.immediateFuture(rpcResult);