Merge "disable creating docker images from cds-ui application"
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
index b0bfe8b..c51c7fa 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
@@ -1,4 +1,5 @@
 <!--Header-->
+<ngx-ui-loader></ngx-ui-loader>
 <header>
     <div class="row m-0">
         <div class="col pl-0">
@@ -92,7 +93,10 @@
                                 <a (click)="saveBluePrint()">Save</a>
                             </li>
                             <li>
-                                <a (click)="publishBluePrint()">Save &amp; Deploy</a>
+                                <a (click)="enrichBluePrint()">Enrich</a>
+                            </li>
+                            <li>
+                                <a (click)="publishBluePrint()">Deploy</a>
                             </li>
                         </ul>
                     </div>
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
index a2b57d6..1aa283c 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
@@ -52,6 +52,7 @@
 import { TopologyTemplate } from './model/designer.topologyTemplate.model';
 import { ToastrService } from 'ngx-toastr';
 import { DesignerDashboardState } from './model/designer.dashboard.state';
+import { NgxUiLoaderService } from 'ngx-ui-loader';
 
 @Component({
     selector: 'app-designer',
@@ -100,6 +101,7 @@
         private packageCreationService: PackageCreationService,
         private packageCreationExtractionService: PackageCreationExtractionService,
         private activatedRoute: ActivatedRoute,
+        private ngxService: NgxUiLoaderService,
         private toastService: ToastrService) {
         this.controllerSideBar = true;
         this.actionAttributesSideBar = false;
@@ -138,10 +140,6 @@
             });
     }
 
-    // private _toggleSidebar3() {
-    //   this.functionAttributeSidebar = !this.functionAttributeSidebar;
-    // }
-
 
     /**
      * - There is a board (main paper) that will the action and function selected from the palette
@@ -156,6 +154,7 @@
      */
 
     ngOnInit() {
+        // this.ngxService.start();
         this.customActionName = this.route.snapshot.paramMap.get('actionName');
         if (this.customActionName !== '') {
             this.showAction = true;
@@ -454,7 +453,7 @@
     }
 
     saveBluePrint() {
-
+        this.ngxService.start();
         FilesContent.clear();
         let packageCreationModes: PackageCreationModes;
         this.cbaPackage = PackageCreationModes.mapModeType(this.cbaPackage);
@@ -469,6 +468,46 @@
 
     }
 
+    enrichBluePrint() {
+        this.ngxService.start();
+        this.packageCreationStore.addTopologyTemplate(this.cbaPackage.templateTopology);
+        this.formTreeData();
+        this.enrichPackage();
+        this.designerStore.clear();
+        this.packageCreationStore.clear();
+    }
+
+    private formTreeData() {
+        FilesContent.clear();
+        let packageCreationModes: PackageCreationModes;
+        this.cbaPackage = PackageCreationModes.mapModeType(this.cbaPackage);
+        this.cbaPackage.metaData = PackageCreationModes.setEntryPoint(this.cbaPackage.metaData);
+        packageCreationModes = PackageCreationBuilder.getCreationMode(this.cbaPackage);
+        packageCreationModes.execute(this.cbaPackage, this.packageCreationUtils);
+        this.filesData.push(this.folder.TREE_DATA);
+    }
+    private enrichPackage() {
+        this.create();
+        this.zipFile.generateAsync({ type: 'blob' })
+            .then(blob => {
+                this.packageCreationService.enrichPackage(blob).subscribe(response => {
+                    console.log('success');
+                    const blobInfo = new Blob([response], { type: 'application/octet-stream' });
+                    this.packageCreationStore.clear();
+                    this.packageCreationExtractionService.extractBlobToStore(blobInfo);
+                    this.toastService.info('enriched successfully ');
+                }, err => {
+                }, () => {
+                    this.ngxService.stop();
+                });
+            }, error => {
+                this.toastService.error('error happened when enrich ' + error.message);
+                console.error('Error -' + error.message);
+            }, () => {
+                this.ngxService.stop();
+            });
+    }
+
     create() {
         this.zipFile = new JSZip();
         FilesContent.getMapOfFilesNamesAndContent().forEach((value, key) => {
@@ -491,8 +530,11 @@
                     }, error => {
                         this.toastService.error('error happened when editing ' + error.message);
                         console.log('Error -' + error.message);
+                    }, () => {
+                        this.ngxService.stop();
                     });
-            });
+            }, err => { },
+                () => { this.ngxService.stop(); });
     }
 
     openActionAttributes(customActionName: string) {
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts
index 3890a98..6ebf536 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions-attribute/functions-attribute.component.ts
@@ -195,12 +195,17 @@
         // instantiate the final node_template object to save
 
         this.nodeTemplates.type = type;
+        delete this.nodeTemplates.properties;
         node_templates[finalFunctionData['instance-name']] = this.nodeTemplates;
 
         delete finalFunctionData['instance-name'];
         // tslint:disable-next-line: no-string-literal
         delete finalFunctionData['type'];
 
+        if (finalFunctionData.outputs === {} || Object.keys(finalFunctionData.outputs).length <= 0) {
+            delete finalFunctionData.outputs;
+        }
+
         this.nodeTemplates.interfaces = {
             [this.interfaceChildName]: {
                 operations: {
@@ -210,11 +215,12 @@
                 }
             }
         };
-
         console.log(finalFunctionData);
         console.log(node_templates);
+        // save function to store
         // tslint:disable-next-line: no-unused-expression
         this.designerStore.addNodeTemplate(instanceName, type, node_templates[instanceName]);
+        // create a new package
         this.saveEvent.emit('save');
     }
     // Template logic
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.ts
index 4087dee..e49d7a4 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/package-creation/template-mapping/templ-mapp-creation/templ-mapp-creation.component.ts
@@ -282,15 +282,12 @@
     confirmDelete() {
         // Delete from templates
         this.sharedService.deleteFromList(this.fileName);
-        this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
+        console.log('Templates/' + this.fileName + '-template.' + this.templateInfo.ext);
+        this.packageCreationStore.state.templates.files.delete('Templates/' + this.fileName + '-template.' + this.templateInfo.ext);
         // Delete from Mapping
         this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
-        if (
-            this.packageCreationStore.state.templates.files.size > 0 ||
-            this.packageCreationStore.state.mapping.files.size > 0
-        ) {
-            this.openListView();
-        }
+        this.openListView();
+
 
     }
     uploadFile() {
diff --git a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfExecutorExtensions.kt b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfExecutorExtensions.kt
index 7aabb73..2d3eb3b 100644
--- a/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfExecutorExtensions.kt
+++ b/ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfExecutorExtensions.kt
@@ -21,6 +21,7 @@
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.restClientService
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintRetryException
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 
@@ -110,3 +111,72 @@
     log.info("sending unMount request, url: $unMountUrl")
     webClientService.exchangeResource("DELETE", unMountUrl, "")
 }
+
+/**
+ * Generic PUT/PATCH/POST request function
+ */
+suspend fun AbstractScriptComponentFunction.genericPutPatchPostRequest(
+    webClientService: BlueprintWebClientService,
+    requestUrl: String,
+    requestType: String,
+    payload: Any,
+    headers: Map<String, String> = mutableMapOf("Content-Type" to "application/xml")
+): BlueprintWebClientService.WebClientResponse<String> {
+    when (requestType.toUpperCase()) {
+        "PUT" -> log.info("sending PUT request, url: $requestUrl")
+        "PATCH" -> log.info("sending PATCH request, url: $requestUrl")
+        "POST" -> log.info("sending POST request, url: $requestUrl")
+        else -> throw BluePrintProcessorException("Illegal request type, only POST, PUT or PATCH allowed.")
+    }
+    return webClientService.exchangeResource(requestType, requestUrl, payload as String, headers)
+}
+
+/**
+ * Generic GET/DELETE request function
+ */
+
+suspend fun AbstractScriptComponentFunction.genericGetOrDeleteRequest(
+    webClientService: BlueprintWebClientService,
+    requestUrl: String,
+    requestType: String
+): BlueprintWebClientService.WebClientResponse<String> {
+    when (requestType.toUpperCase()) {
+        "GET" -> log.info("sending GET request, url: $requestUrl")
+        "DELETE" -> log.info("sending DELETE request, url: $requestUrl")
+        else -> throw BluePrintProcessorException("Illegal request type, only GET and DELETE allowed.")
+    }
+    return webClientService.exchangeResource(requestType, requestUrl, "")
+}
+
+/**
+ * Generic Mount function
+ * This function mount the given deviceId and verify if device mounted successfully.
+ * This function take mount url and mount verify url as parameters.
+ */
+
+suspend fun AbstractScriptComponentFunction.restconfMountDevice(
+    webClientService: BlueprintWebClientService,
+    payload: Any,
+    mountUrl: String,
+    mountVerifyUrl: String,
+    headers: Map<String, String> = mutableMapOf("Content-Type" to "application/xml"),
+    expectedMountResult: String = """"netconf-node-topology:connection-status":"connected""""
+) {
+
+    log.info("sending mount request, url: $mountUrl")
+    webClientService.exchangeResource("PUT", mountUrl, payload as String, headers)
+
+    /** Check device has mounted */
+    val mountCheckExecutionBlock: suspend (Int) -> String = { tryCount: Int ->
+        val result = webClientService.exchangeResource("GET", mountVerifyUrl, "")
+        if (result.body.contains(expectedMountResult)) {
+            log.info("NF was mounted successfully on ODL")
+            result.body
+        } else {
+            throw BluePrintRetryException("Wait for device with url($mountUrl) to mount")
+        }
+    }
+
+    log.info("url for ODL status check: $mountVerifyUrl")
+    webClientService.retry<String>(10, 0, 1000, mountCheckExecutionBlock)
+}