Merge "Added resource assignemnt content"
diff --git a/cds-ui/client/src/app/common/core/services/api.service.ts b/cds-ui/client/src/app/common/core/services/api.service.ts
index 20d8a9b..463ef38 100644
--- a/cds-ui/client/src/app/common/core/services/api.service.ts
+++ b/cds-ui/client/src/app/common/core/services/api.service.ts
@@ -31,38 +31,14 @@
   
   constructor(private _http: HttpClient) {
   }
-  enrich(uri: string, body: FormData): Observable<any> {
-    
-    var HTTPOptions = {
-      headers: new HttpHeaders({ 'Accept': 'application/zip', }),
-      observe: "response" as 'body',// to display the full response & as 'body' for type cast
-      'responseType': 'blob' as 'json'
-    }
-    return this._http.post(LoopbackConfig.url + uri, body, HTTPOptions);
-
-  }
-  downloadCBA(uri: string, params?: any): Observable<Blob> {
-    // return this._http.get<Blob>(LoopbackConfig.url+uri);
-    var HTTPOptions = {
-      headers: new HttpHeaders({ 'Accept': 'application/zip; charset=UTF-8', }),
-      observe: "response" as 'body',// to display the full response & as 'body' for type cast
-      'responseType': 'blob' as 'json'
-    }
-    return this._http.get<Blob>(LoopbackConfig.url + uri, HTTPOptions);
-
+  get(url: string, params?: any): Observable<any> {
+    return this._http.get(url,params);
   }
 
-  post(uri: string, body: FormData): Observable<any> {
-    // to do
-    const httpOptions = {
-      headers: new HttpHeaders({
-        'Authorization': LoopbackConfig.authtoken,
+  post(url: string, body: any | null, options?:any): Observable<any> {
 
-      })
-    };
-    return this._http.post(LoopbackConfig.url + uri, body, httpOptions);
+    return this._http.post(url, body,options);
   }
-
   put() {
     // to do
   }
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
index 7cbf5b0..73cc72c 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.component.ts
@@ -36,7 +36,8 @@
 import { IBlueprintState } from 'src/app/common/core/store/models/blueprintState.model';
 import { LoadBlueprintSuccess, SetBlueprintState } from '../../../../common/core/store/actions/blueprint.action'
 import { ApiService } from 'src/app/common/core/services/api.service';
-
+import { IMetaData } from 'src/app/common/core/store/models/metadata.model';
+import { EditorService } from './editor.service';
 
 interface Node {
   name: string;
@@ -92,9 +93,9 @@
   currentFilePath: string = '';
   selectedFileObj = { name: '', type: '' };
   viewTemplateMode: boolean = false;
-  paramData : any = {
+  paramData: any = {
     'capability-data': [],
-    'resourceAccumulatorResolvedData' : []
+    'resourceAccumulatorResolvedData': []
   };
   validfile: boolean = false;
   @ViewChild('fileInput') fileInput;
@@ -103,6 +104,7 @@
   private tree;
   private fileObject: any;
   private tocsaMetadaData: any;
+  metadata: IMetaData;
 
   private transformer = (node: Node, level: number) => {
     return {
@@ -119,8 +121,10 @@
     this.transformer, node => node.level, node => node.expandable, node => node.children);
 
   dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
+  artifactName: any;
+  artifactVersion: any;
 
-  constructor(private store: Store<IAppState>, private apiservice: ApiService) {
+  constructor(private store: Store<IAppState>, private apiservice: EditorService) {
     this.dataSource.data = TREE_DATA;
     this.bpState = this.store.select('blueprint');
     // this.dataSource.data = TREE_DATA;
@@ -161,8 +165,15 @@
             blueprint.push(this.blueprintdata[key]);
           }
         }
-        // this.text = JSON.stringify(this.blueprintdata, null, '\t');
-        // this.editor.getEditor().getSession().setMode("ace/mode/json");
+        this.metadata=blueprintState.blueprint.metadata;
+        let metadatavalues = [];
+        for (let key in this.metadata) {
+          if (this.metadata.hasOwnProperty(key)) {
+            metadatavalues.push(this.metadata[key]);
+          }
+        }
+        this.artifactName = metadatavalues[3];
+        this.artifactVersion = metadatavalues[4];
         this.editor.getEditor().getSession().setTabSize(2);
         this.editor.getEditor().getSession().setUseWrapMode(true);
         this.setEditorMode();
@@ -197,7 +208,7 @@
   }
 
   selectFileToView(file) {
-    if(file.name.includes('.vtl')) { this.viewTemplateMode = true;} else { this.viewTemplateMode = false;}
+    if (file.name.includes('.vtl')) { this.viewTemplateMode = true; } else { this.viewTemplateMode = false; }
     this.currentFilePath = '';
     this.expandParents(file);
     this.selectedFileObj.name = file.name;
@@ -224,70 +235,21 @@
         this.apiservice.enrich("/enrich-blueprint/", formData)
           .subscribe(
             (response) => {
-              console.log("Inside blob");
-              var blob = new Blob([response.data], { type: 'application/zip' });
-              const fileName = 'CBA.zip';
-              saveAs(blob, fileName);
               this.zipFile.files = {};
-              this.zipFile.loadAsync(blob)
+              this.zipFile.loadAsync(response)
                 .then((zip) => {
                   if (zip) {
                     this.buildFileViewData(zip);
+                    console.log("processed");
                   }
                 });
-              
+                window.alert('Blueprint enriched successfully' );
             });
-
       });
-
   }
-  async buildFileViewData(zip) {
-    this.validfile = false;
-    this.paths = [];
-    for (var file in zip.files) {
-      this.fileObject = {
-        name: zip.files[file].name,
-        data: ''
-      };
-      const value = <any>await  zip.files[file].async('string');
-      this.fileObject.data = value;
-      this.paths.push(this.fileObject); 
-    }
-
-    if(this.paths) {
-      this.paths.forEach(path =>{
-        if(path.name.includes("TOSCA.meta")) {
-          this.validfile = true
-        }
-      });
-    } else {
-      alert('Please update proper file');
-    }
-
-    if(this.validfile) {      
-      this.fetchTOSACAMetadata();
-      this.tree = this.arrangeTreeData(this.paths);
-    } else {
-      alert('Please update proper file with TOSCA metadata');
-    }
-  }
-
-  fetchTOSACAMetadata() {
-    let toscaData = {};
-    this.paths.forEach(file =>{
-      if(file.name.includes('TOSCA.meta')) {
-        let keys = file.data.split("\n");
-        keys.forEach((key)=>{
-          let propertyData = key.split(':');
-          toscaData[propertyData[0]] = propertyData[1];
-        });
-      }
-    });
-    this.blueprintName = (((toscaData['Entry-Definitions']).split('/'))[1]).toString();;
-    console.log(toscaData);
-  }
-
   
+
+
   saveToBackend() {
     this.create();
     this.zipFile.generateAsync({ type: "blob" })
@@ -295,7 +257,11 @@
         const formData = new FormData();
         formData.append("file", blob);
         this.apiservice.post("/create-blueprint/", formData)
-          .subscribe(data => console.log(data));
+          .subscribe(
+            data => {
+              // console.log(data);
+              window.alert('Success:' + JSON.stringify(data));
+            });
 
       });
   }
@@ -307,8 +273,11 @@
       .then(blob => {
         const formData = new FormData();
         formData.append("file", blob);
-        this.apiservice.post("/deploy-blueprint/", formData)
-          .subscribe(data => console.log(data));
+        this.apiservice.deployPost("/deploy-blueprint/", formData)
+          .subscribe(data => {
+            // console.log(data);
+            window.alert('Saved Successfully:' + JSON.stringify(data));
+          });
 
       });
   }
@@ -320,7 +289,10 @@
         const formData = new FormData();
         formData.append("file", blob);
         this.apiservice.post("/publish/", formData)
-          .subscribe(data => console.log(data));
+          .subscribe(data => {
+            // console.log(data);
+            window.alert('Published:' + JSON.stringify(data));
+          });
 
       });
 
@@ -333,17 +305,19 @@
   }
 
   download() {
-    this.apiservice.downloadCBA("/download-blueprint/baseconfiguration/1.0.0")
-      .subscribe(response => {
-        console.log(response);
-        var blob = new Blob([response], { type: 'application/zip' });
-        const fileName = 'CBA';
-        saveAs(blob, fileName);
-      },
-        error => {
-          console.log(error);
-        }
-      );
+    console.log(this.artifactName);
+    status = this.apiservice.downloadCBA("/download-blueprint/" + this.artifactName + "/" + this.artifactVersion);
+    window.alert(status);
+    // .subscribe(response => {
+    //   console.log(response);
+    //   var blob = new Blob([response], { type: 'application/zip' });
+    //   const fileName = 'CBA';
+    //   saveAs(blob, fileName);
+    // },
+    //   error => {
+    //     console.log(error);
+    //   }
+    // );
   }
   setEditorMode() {
     switch (this.fileExtension) {
@@ -417,6 +391,52 @@
     return indexForNewNode;
   }
 
+  async buildFileViewData(zip) {
+    this.validfile = false;
+    this.paths = [];
+    for (var file in zip.files) {
+      this.fileObject = {
+        name: zip.files[file].name,
+        data: ''
+      };
+      const value = <any>await zip.files[file].async('string');
+      this.fileObject.data = value;
+      this.paths.push(this.fileObject);
+    }
+
+    if (this.paths) {
+      this.paths.forEach(path => {
+        if (path.name.includes("TOSCA.meta")) {
+          this.validfile = true
+        }
+      });
+    } else {
+      alert('Please update proper file');
+    }
+
+    if (this.validfile) {
+      this.fetchTOSACAMetadata();
+      this.tree = this.arrangeTreeData(this.paths);
+    } else {
+      alert('Please update proper file with TOSCA metadata');
+    }
+  }
+
+  fetchTOSACAMetadata() {
+    let toscaData = {};
+    this.paths.forEach(file => {
+      if (file.name.includes('TOSCA.meta')) {
+        let keys = file.data.split("\n");
+        keys.forEach((key) => {
+          let propertyData = key.split(':');
+          toscaData[propertyData[0]] = propertyData[1];
+        });
+      }
+    });
+    this.blueprintName = (((toscaData['Entry-Definitions']).split('/'))[1]).toString();;
+    console.log(toscaData);
+  }
+  
   arrangeTreeData(paths) {
     const tree = [];
 
@@ -505,34 +525,34 @@
   }
   loadConfigParams() {
     console.log(this.currentFilePath);
-   console.log(this.selectedFile);
-   console.log(this.selectedFileObj);
-   console.log(this.selectedFolder);
-   console.log(this.text);
+    console.log(this.selectedFile);
+    console.log(this.selectedFileObj);
+    console.log(this.selectedFolder);
+    console.log(this.text);
 
-   let parsedData = JSON.parse(this.text);
-   this.paramData.resourceAccumulatorResolvedData = parsedData['resource-accumulator-resolved-data'];
-  let i=0;
+    let parsedData = JSON.parse(this.text);
+    this.paramData.resourceAccumulatorResolvedData = parsedData['resource-accumulator-resolved-data'];
+    let i = 0;
 
-   this.paramData.resourceAccumulatorResolvedData.forEach(element => {
-        element.id = i;
-        let tempElement = element['param-value'];
-        let indexLength = tempElement.length;
-        tempElement = tempElement.slice(2,indexLength);
-        let index = tempElement.indexOf('}');
-        tempElement = this.removeItemByIndex(tempElement, index);
-        element['param-value'] = tempElement;
-        i++;
-   });
+    this.paramData.resourceAccumulatorResolvedData.forEach(element => {
+      element.id = i;
+      let tempElement = element['param-value'];
+      let indexLength = tempElement.length;
+      tempElement = tempElement.slice(2, indexLength);
+      let index = tempElement.indexOf('}');
+      tempElement = this.removeItemByIndex(tempElement, index);
+      element['param-value'] = tempElement;
+      i++;
+    });
 
   }
 
   removeItemByIndex(paramValue, index) {
-    if(index == 0) {
-      return  paramValue.slice(1)
-    } else if(index > 0) {
+    if (index == 0) {
+      return paramValue.slice(1)
+    } else if (index > 0) {
       let indexLength = paramValue.length;
-      return paramValue.slice(0,index) + paramValue.slice(index+1, indexLength);
+      return paramValue.slice(0, index) + paramValue.slice(index + 1, indexLength);
     } else {
       return paramValue;
     }
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
new file mode 100644
index 0000000..98e43b6
--- /dev/null
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/editor/editor.service.ts
@@ -0,0 +1,58 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 IBM Intellectual Property. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+============LICENSE_END============================================
+*/
+
+
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable, observable } from 'rxjs';
+import { ApiService } from '../../../../common/core/services/api.service';
+import { LoopbackConfig } from '../../../../common/constants/app-constants';
+import { saveAs } from 'file-saver';
+
+@Injectable()
+export class EditorService {
+    // blueprintUrl = '../../constants/blueprint.json';
+
+    constructor(private _http: HttpClient, private api: ApiService) {
+    }
+
+    enrich(uri: string, body: FormData): Observable<any> {
+        return this.api.post(LoopbackConfig.url + uri, body, { responseType: 'blob' });
+    }
+    downloadCBA(uri: string): string {
+        this.api.get(LoopbackConfig.url + uri, { responseType: 'blob' })
+            .subscribe(response => {
+                let blob = new Blob([response], { 'type': "application/octet-stream" });
+                saveAs(blob, "CBA.zip");
+            });
+        return "Download Success";
+
+    }
+    post(uri: string, body: any | null, options?: any): Observable<any> {
+
+        return this.api.post(LoopbackConfig.url + uri, body, options);
+    }
+
+    deployPost(uri: string, body: any | null, options?: any): Observable<any> {
+
+        return this.api.post(LoopbackConfig.url + uri, body, { responseType: 'text' });
+    }
+}
\ No newline at end of file
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
index 1d9b526..b3eeeed 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.component.html
@@ -38,7 +38,7 @@
                 <button mat-menu-item (click)="saveToBlueprintProcessor()">Deploy</button>
                 <button mat-menu-item (click)="processBlueprint()">Test</button>
             </mat-menu>
-            <button [disabled]="!isEnriched" class="btn-active" (click)="publishToControllerBlueprint()">Publish</button>
+            <button class="btn-active" (click)="publishToControllerBlueprint()">Publish</button>
             <button class="btn-active" (click)="saveToControllerBlueprint()">Save</button>
             <button class="btn-active" (click)="getEnriched()">Enrich</button>
 
diff --git a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.module.ts b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.module.ts
index 7d22c56..64ba4cd 100644
--- a/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.module.ts
+++ b/cds-ui/client/src/app/feature-modules/blueprint/modify-template/modify-template.module.ts
@@ -31,6 +31,7 @@
 import { AceEditorModule } from 'ng2-ace-editor';
 import { ResourceMappingComponent } from './resource-mapping/resource-mapping.component';
 import { ResourceMappingService } from './resource-mapping/resource-mapping.service';
+import { EditorService } from './editor/editor.service';
 
 @NgModule({
   declarations: [
@@ -52,6 +53,6 @@
     AceEditorModule,
     FormsModule
   ],
-  providers: [ ResourceMappingService ]
+  providers: [ ResourceMappingService , EditorService ]
 })
 export class ModifyTemplateModule { }
diff --git a/cds-ui/server/src/controllers/blueprint-rest.controller.ts b/cds-ui/server/src/controllers/blueprint-rest.controller.ts
index c1f7f96..38abad8 100644
--- a/cds-ui/server/src/controllers/blueprint-rest.controller.ts
+++ b/cds-ui/server/src/controllers/blueprint-rest.controller.ts
@@ -51,12 +51,11 @@
 
 const REST_BLUEPRINT_CONTROLLER_BASE_URL = process.env.REST_BLUEPRINT_CONTROLLER_BASE_URL || "http://localhost:8080/api/v1";
 const REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER = process.env.REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==";
-const REST_BLUEPRINT_PROCESSOR_BASE_URL= "http://localhost:8081/api/v1";
+const REST_BLUEPRINT_PROCESSOR_BASE_URL= process.env.REST_BLUEPRINT_PROCESSOR_BASE_URL ||"http://localhost:8081/api/v1";
+const MULTIPART_FORM_UPLOAD_DIR = process.env.MULTIPART_FORM_UPLOAD_DIR || "/tmp";
 
 export class BlueprintRestController {
   constructor(
-  //  @repository(BlueprintRepository)
-  //   public blueprintRepository : BlueprintRepository,
     @inject('services.BlueprintService') 
     public bpservice: BlueprintService,
   ) {}
@@ -71,7 +70,6 @@
   })
   async getall() {
     return await this.bpservice.getAllblueprints(REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER);
-
   }
 
   @post('/create-blueprint')
@@ -89,12 +87,11 @@
     })
     request: Request,
     @inject(RestBindings.Http.RESPONSE) response: Response,
-  ): Promise<object> {
+  ): Promise<Response> {
     return new Promise((resolve, reject) => { 
        this.getFileFromMultiPartForm(request).then(file=>{
-         this.uploadFileToBlueprintController(file, "/blueprint-model/").then(resp=>{
-          response.setHeader("X-ONAP-RequestID", resp.headers['x-onap-requestid']);
-          resolve(JSON.parse(resp.body));
+         this.uploadFileToBlueprintController(file, REST_BLUEPRINT_CONTROLLER_BASE_URL+"/blueprint-model/", response).then(resp=>{
+          resolve(resp);
          }, err=>{
            reject(err);
          });
@@ -103,7 +100,34 @@
       });
     });
   }
-
+  @post('/publish')
+  async publish(
+    @requestBody({
+      description: 'multipart/form-data value.',
+      required: true,
+      content: {
+        'multipart/form-data': {
+          // Skip body parsing
+          'x-parser': 'stream',
+          schema: {type: 'object'},
+        },
+      },
+    })
+    request: Request,
+    @inject(RestBindings.Http.RESPONSE) response: Response,
+  ): Promise<Response> {
+    return new Promise((resolve, reject) => { 
+       this.getFileFromMultiPartForm(request).then(file=>{
+         this.uploadFileToBlueprintController(file, REST_BLUEPRINT_CONTROLLER_BASE_URL+"/blueprint-model/publish/", response).then(resp=>{
+          resolve(resp);
+         }, err=>{
+           reject(err);
+         });
+      }, err=>{
+        reject(err);
+      });
+    });
+  }
   @post('/enrich-blueprint')
   async enrich(
     @requestBody({
@@ -119,13 +143,11 @@
     })
     request: Request,
     @inject(RestBindings.Http.RESPONSE) response: Response,
-  ): Promise<any> {
+  ): Promise<Response> {
     return new Promise((resolve, reject) => { 
        this.getFileFromMultiPartForm(request).then(file=>{
-         this.uploadFileToBlueprintController(file, "/blueprint-model/enrich/").then(resp=>{
-           response.setHeader("X-ONAP-RequestID", resp.headers['x-onap-requestid']);
-           response.setHeader("Content-Disposition", resp.headers['content-disposition']);
-           resolve(resp.body);
+         this.uploadFileToBlueprintController(file, REST_BLUEPRINT_CONTROLLER_BASE_URL+"/blueprint-model/enrich/", response).then(resp=>{
+           resolve(resp);
          }, err=>{
            reject(err);
          });
@@ -139,25 +161,13 @@
   async download(
     @param.path.string('name') name: string,
     @param.path.string('version') version:string,
-    // @inject(RestBindings.Http.REQUEST) request: Request,
     @inject(RestBindings.Http.RESPONSE) response: Response,
-  ): Promise<any> {
-    return new Promise((resolve, reject) => { 
-      this.downloadFileFromBlueprintController("/blueprint-model/download/by-name/"+name+"/version/"+version).then(resp=>{
-        response.setHeader("X-ONAP-RequestID", resp.headers['x-onap-requestid']);
-        response.setHeader("Content-Disposition", resp.headers['content-disposition']);
-        resolve(resp.body);
-      }, err=>{
-        reject(err);
-      });
-    });
+  ): Promise<Response> {
+    return this.downloadFileFromBlueprintController(REST_BLUEPRINT_CONTROLLER_BASE_URL+"/blueprint-model/download/by-name/"+name+"/version/"+version, response);
   }
 
-  async getFileFromMultiPartForm(request: Request): Promise<any>{
+  async getFileFromMultiPartForm(request: Request): Promise<multiparty.File>{
     return new Promise((resolve, reject) => {
-      // let options = {
-      //   uploadDir: MULTIPART_FORM_UPLOAD_DIR
-      // }
       let form = new multiparty.Form();
       form.parse(request, (err: any, fields: any, files: { [x: string]: any[]; }) => {
         if (err) reject(err);
@@ -171,9 +181,38 @@
     })
   }
 
-  async uploadFileToBlueprintController(file: any, uri: string): Promise<any>{
+  @post('/deploy-blueprint')
+  async deploy(
+    @requestBody({
+      description: 'multipart/form-data value.',
+      required: true,
+      content: {
+        'multipart/form-data': {
+          // Skip body parsing
+          'x-parser': 'stream',
+          schema: {type: 'object'},
+        },
+      },
+    })
+    request: Request,
+    @inject(RestBindings.Http.RESPONSE) response: Response,
+  ): Promise<Response> {
+    return new Promise((resolve, reject) => { 
+       this.getFileFromMultiPartForm(request).then(file=>{
+         this.uploadFileToBlueprintController(file, REST_BLUEPRINT_PROCESSOR_BASE_URL+"/execution-service/upload/", response).then(resp=>{
+          resolve(resp);
+         }, err=>{
+           reject(err);
+         });
+      }, err=>{
+        reject(err);
+      });
+    });
+  }
+  async uploadFileToBlueprintController(file: multiparty.File, uri: string, response: Response): Promise<Response>{
     let options = {
-      url: REST_BLUEPRINT_CONTROLLER_BASE_URL + uri,
+      // url: REST_BLUEPRINT_CONTROLLER_BASE_URL + uri,
+      url:uri,
       headers: {
         Authorization: REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER,
         'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
@@ -189,40 +228,43 @@
       }
     };
 
-    return new Promise((resolve, reject) => {
-      request_lib.post(options, (err: any, resp: any, body: any) => {
+    var removeTempFile = () => {
+      fs.unlink(file.path, (err: any) => {
         if (err) {
-          //delete tmp file
-          fs.unlink(file.path, (err: any) => {
-            if (err) {
-              console.error(err);
-              return
-            }
-          })
+          console.error(err);
+        } 
+      });
+    }
+
+    return new Promise((resolve, reject) => {
+      request_lib.post(options)
+        .on("error", err => {
           reject(err);
-        }else{
-          resolve(resp);
-        }
-      })
+        })
+        .pipe(response)
+        .once("finish", () => {
+          removeTempFile();
+          resolve(response);
+        });
     })
   }
-
-  async downloadFileFromBlueprintController(uri: string): Promise<any> {
+  async downloadFileFromBlueprintController(uri: string, response: Response): Promise<Response> {
     let options = {
-      url: REST_BLUEPRINT_CONTROLLER_BASE_URL + uri,
+      url: uri,
+      // REST_BLUEPRINT_CONTROLLER_BASE_URL + uri,
       headers: {
         Authorization: REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER,
       }
     };
-
     return new Promise((resolve, reject) => {
-      request_lib.get(options, (err: any, resp: any, body: any) => {
-        if (err) {
+      request_lib.get(options)
+        .on("error", err => {
           reject(err);
-        }else{
-          resolve(resp);
-        }
-      })
+        })
+        .pipe(response)
+        .once("finish", () => {
+          resolve(response);
+        });
     })
-}
+  }
 }
\ No newline at end of file
diff --git a/cds-ui/server/src/controllers/data-dictionary.controller.ts b/cds-ui/server/src/controllers/data-dictionary.controller.ts
new file mode 100644
index 0000000..36efe6e
--- /dev/null
+++ b/cds-ui/server/src/controllers/data-dictionary.controller.ts
@@ -0,0 +1,85 @@
+// Uncomment these imports to begin using these cool features!
+
+// import {inject} from '@loopback/context';
+import {
+  post,
+  param,
+  get,
+  getFilterSchemaFor,
+  getWhereSchemaFor,
+  patch,
+  put,
+  del,
+  requestBody,
+  Request,
+  Response,
+  RestBindings,
+} from '@loopback/rest';
+import { inject } from '@loopback/core';
+import { ResourceDictionaryService } from '../services';
+
+const REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER = process.env.REST_BLUEPRINT_CONTROLLER_BASIC_AUTH_HEADER || "Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==";
+export class DataDictionaryController {
+  constructor(
+    @inject('services.ResourceDictionaryService')
+    public rdservice: ResourceDictionaryService,
+  ) { }
+
+  @get('/resourcedictionary/{name}', {
+    responses: {
+      '200': {
+        content: { 'application/json': {} },
+      },
+    },
+  })
+  async getByName(@param.path.string('name') name: string) {
+    return await this.rdservice.getByName(name, REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER);
+  }
+  @get('/resourcedictionary/{tags}', {
+    responses: {
+      '200': {
+        content: { 'application/json': {} },
+      },
+    },
+  })
+  async getByTags(@param.path.string('tags') tags: string) {
+    return await this.rdservice.getByTags(tags, REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER);
+  }
+
+  @get('/resourcedictionary/source-mapping', {
+    responses: {
+      '200': {
+        content: { 'application/json': {} },
+      },
+    },
+  })
+  async getSourceMapping() {
+    return await this.rdservice.getSourceMapping(REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER);
+  }
+  @post('/resourcedictionary/save', {
+    responses: {
+      '200': {
+        content: { 'application/json': {} }
+      }
+    },
+  })
+  async save(@requestBody({
+    content: { 'application/json': { schema: { 'x-ts-type': JSON } } },
+    accepts: { 'application/json': { schema: { 'x-ts-type': JSON } } }
+  }) resourceDictionary: JSON): Promise<any> {
+    return await this.rdservice.save(REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER, resourceDictionary);
+  }
+  @post('/resourcedictionary/search/by-names', {
+    responses: {
+      '200': {
+        content: { 'application/json': {} }
+      }
+    },
+  })
+  async searchByNames(@requestBody({
+    content: { 'application/json': { schema: { 'x-ts-type': JSON } } },
+    accepts: { 'application/json': { schema: { 'x-ts-type': JSON } } }
+  }) resourceDictionaryList: JSON): Promise<any> {
+    return await this.rdservice.searchbyNames(REST_RESOURCE_DICTIONARY_BASIC_AUTH_HEADER, resourceDictionaryList);
+  }
+}
diff --git a/cds-ui/server/src/controllers/index.ts b/cds-ui/server/src/controllers/index.ts
index bf2bd6f..59f6351 100644
--- a/cds-ui/server/src/controllers/index.ts
+++ b/cds-ui/server/src/controllers/index.ts
@@ -20,3 +20,4 @@
 */
 
 export * from './ping.controller';
+export * from './data-dictionary.controller';
diff --git a/cds-ui/server/src/datasources/index.ts b/cds-ui/server/src/datasources/index.ts
index f7a934c..7ed2c91 100644
--- a/cds-ui/server/src/datasources/index.ts
+++ b/cds-ui/server/src/datasources/index.ts
@@ -22,3 +22,4 @@
 
 export * from './db.datasource';
 export * from './blueprint.datasource';
+export * from './resource-dictionary.datasource';
diff --git a/cds-ui/server/src/datasources/resource-dictionary.datasource.json b/cds-ui/server/src/datasources/resource-dictionary.datasource.json
new file mode 100644
index 0000000..9bf5f30
--- /dev/null
+++ b/cds-ui/server/src/datasources/resource-dictionary.datasource.json
@@ -0,0 +1,89 @@
+{
+    "name": "resourceDictionary",
+    "connector": "rest",
+    "baseURL": "http://localhost:8080/api/v1/dictionary",
+    "crud": false,
+    "operations": [{
+            "template": {
+                "method": "GET",
+                "url": "http://localhost:8080/api/v1/dictionary/{name}",
+                "headers": {
+                    "accepts": "application/json",
+                    "content-type": "application/json",
+                    "authorization": "{authtoken}"
+                },
+                "responsePath": "$.*"
+            },
+            "functions": {
+                "getByName": ["name", "authtoken"]
+
+            }
+        },
+        {
+            "template": {
+                "method": "GET",
+                "url": "http://localhost:8080/api/v1/dictionary/source-mapping",
+                "headers": {
+                    "accepts": "application/json",
+                    "content-type": "application/json",
+                    "authorization": "{authtoken}"
+                },
+                "responsePath": "$.*"
+            },
+            "functions": {
+                "getSourceMapping": ["authtoken"]
+
+            }
+        },
+        {
+            "template": {
+                "method": "GET",
+                "url": "http://localhost:8080/api/v1/dictionary/search/{tags}",
+                "headers": {
+                    "accepts": "application/json",
+                    "content-type": "application/json",
+                    "authorization": "{authtoken}"
+                },
+                "responsePath": "$.*"
+            },
+            "functions": {
+                "getByTags": ["tags", "authtoken"]
+
+            }
+        },
+        {
+            "template": {
+                "method": "POST",
+                "url": "http://localhost:8080/api/v1/dictionary",
+                "headers": {
+                    "accepts": "application/json",
+                    "content-type": "application/json",
+                    "authorization": "{authtoken}"
+                },
+                "body": "{resourceDictionary}",
+                "responsePath": "$.*"
+            },
+            "functions": {
+                "save": ["authtoken", "resourceDictionary"]
+
+            }
+        },
+        {
+            "template": {
+                "method": "POST",
+                "url": "http://localhost:8080/api/v1/dictionary/by-names",
+                "headers": {
+                    "accepts": "application/json",
+                    "content-type": "application/json",
+                    "authorization": "{authtoken}"
+                },
+                "body": "{resourceDictionaryList}",
+                "responsePath": "$.*"
+            },
+            "functions": {
+                "searchbyNames": ["authtoken", "resourceDictionaryList"]
+
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/cds-ui/server/src/datasources/resource-dictionary.datasource.ts b/cds-ui/server/src/datasources/resource-dictionary.datasource.ts
new file mode 100644
index 0000000..381ab9a
--- /dev/null
+++ b/cds-ui/server/src/datasources/resource-dictionary.datasource.ts
@@ -0,0 +1,14 @@
+import {inject} from '@loopback/core';
+import {juggler} from '@loopback/repository';
+import * as config from './resource-dictionary.datasource.json';
+
+export class ResourceDictionaryDataSource extends juggler.DataSource {
+  static dataSourceName = 'resourceDictionary';
+
+  constructor(
+    @inject('datasources.config.resourceDictionary', {optional: true})
+    dsConfig: object = config,
+  ) {
+    super(dsConfig);
+  }
+}
diff --git a/cds-ui/server/src/services/index.ts b/cds-ui/server/src/services/index.ts
index 26b01ed..8a82e32 100644
--- a/cds-ui/server/src/services/index.ts
+++ b/cds-ui/server/src/services/index.ts
@@ -1 +1,2 @@
 export * from './blueprint.service';
+export * from './resource-dictionary.service';
diff --git a/cds-ui/server/src/services/resource-dictionary.service.ts b/cds-ui/server/src/services/resource-dictionary.service.ts
new file mode 100644
index 0000000..44ba1a3
--- /dev/null
+++ b/cds-ui/server/src/services/resource-dictionary.service.ts
@@ -0,0 +1,23 @@
+import {getService} from '@loopback/service-proxy';
+import {inject, Provider} from '@loopback/core';
+import {ResourceDictionaryDataSource} from '../datasources';
+
+export interface ResourceDictionaryService {
+  getByName(name: string, authtoken: string): Promise<JSON>;
+  getSourceMapping(authtoken: string): Promise<JSON>;
+  getByTags(tags: string, authtoken: string): Promise<JSON>;
+  save(authtoken: string, resourceDictionary: JSON): Promise<JSON>;
+  searchbyNames(authtoken: string, resourceDictionaryList: JSON): Promise<JSON>;
+}
+
+export class ResourceDictionaryServiceProvider implements Provider<ResourceDictionaryService> {
+  constructor(
+    // resourceDictionary must match the name property in the datasource json file
+    @inject('datasources.resourceDictionary')
+    protected dataSource: ResourceDictionaryDataSource = new ResourceDictionaryDataSource(),
+  ) {}
+
+  value(): Promise<ResourceDictionaryService> {
+    return getService(this.dataSource);
+  }
+}
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
index 13c1bfa..b1121b3 100644
--- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
+++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt
@@ -257,19 +257,11 @@
         }
 
         val capabilityMatcher = NetconfMessageUtils.CAPABILITY_REGEX_PATTERN.matcher(serverHelloResponse)
-        while (capabilityMatcher.find()) {
+        while (capabilityMatcher.find()) { //TODO: refactor to add unit test easily for device capability accumulation.
             deviceCapabilities.add(capabilityMatcher.group(1))
         }
     }
 
-    fun sessionstatus(state:String): Boolean{
-        return when (state){
-            "Close" -> channel.isClosed
-            "Open" -> channel.isOpen
-            else -> false
-        }
-    }
-
     internal fun setStreamHandler(streamHandler: NetconfDeviceCommunicator) {
         this.streamHandler = streamHandler
     }
@@ -279,7 +271,6 @@
      * Used by {@link NetconfSessionListenerImpl}
      */
     internal fun addDeviceErrorReply(errReply: String) {
-        println("addDeviceErrorReply (errReply: $errReply") //TODO : get rid of this.
         errorReplies.add(errReply)
     }
 
@@ -288,7 +279,6 @@
      * Used by {@link NetconfSessionListenerImpl}
      */
     internal fun addDeviceReply(messageId: String, replyMsg: String) {
-        println("addDeviceReply (messageId: $messageId replyMsg: $replyMsg") //TODO : get rid of this.
         replies[messageId]?.complete(replyMsg)
     }
 
@@ -312,7 +302,6 @@
      * internal function for accessing errorReplies for testing.
      */
     internal fun getErrorReplies() = errorReplies
-
     internal fun clearErrorReplies() = errorReplies.clear()
     internal fun clearReplies() = replies.clear()
     internal fun setClient(client: SshClient) { this.client = client }