summaryrefslogtreecommitdiffstats
path: root/src/app/vnfs/build-artifacts
diff options
context:
space:
mode:
authorSkip Wonnell <skip@att.com>2018-03-01 08:30:15 -0600
committerSkip Wonnell <skip@att.com>2018-03-01 08:33:56 -0600
commit2c977e2b66ced314a4f51121801f62fe5c3c05e4 (patch)
treed93b360d7a6502a6aff1f30ba7f96c3e14f8911c /src/app/vnfs/build-artifacts
parent912f105d12fe6f8dc3a2d409938c87016204debe (diff)
Initial seed code contribution for CDT
Issue-ID: APPC-682 Change-Id: I0331ffce2a430195c29d0d1b2295966f9eb28699 Signed-off-by: Skip Wonnell <skip@att.com>
Diffstat (limited to 'src/app/vnfs/build-artifacts')
-rw-r--r--src/app/vnfs/build-artifacts/build-artifacts.component.css40
-rw-r--r--src/app/vnfs/build-artifacts/build-artifacts.component.html36
-rw-r--r--src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts49
-rw-r--r--src/app/vnfs/build-artifacts/build-artifacts.component.ts82
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts114
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts509
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css22
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html219
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts197
-rw-r--r--src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts430
-rw-r--r--src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css22
-rw-r--r--src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html24
-rw-r--r--src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts49
-rw-r--r--src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts39
-rw-r--r--src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css21
-rw-r--r--src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html22
-rw-r--r--src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts48
-rw-r--r--src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts37
-rw-r--r--src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css137
-rw-r--r--src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html354
-rw-r--r--src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts67
-rw-r--r--src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts1242
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css35
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html119
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts711
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts43
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts63
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css35
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html100
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts199
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts977
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-holder.component.css22
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-holder.component.html24
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts49
-rw-r--r--src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts39
35 files changed, 6176 insertions, 0 deletions
diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.css b/src/app/vnfs/build-artifacts/build-artifacts.component.css
new file mode 100644
index 0000000..e7095bd
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/build-artifacts.component.css
@@ -0,0 +1,40 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+.active-tab > a {
+ border-bottom: 5px solid #6ab344;
+}
+
+.custom-heade-nav {
+ border-bottom: none !important;
+}
+
+.nav-link {
+ font-size: 15PX;
+ color: black
+}
+
+a.disabled {
+ color: darkolivegreen;
+ pointer-events: none;
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.html b/src/app/vnfs/build-artifacts/build-artifacts.component.html
new file mode 100644
index 0000000..e0b2e05
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/build-artifacts.component.html
@@ -0,0 +1,36 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+
+<div class="container">
+ <div class="row">
+ <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+ <ul class="nav nav-tabs custom-heade-nav" style=" margin-bottom: 12px;">
+ <li [ngClass]="{'active-tab':((router.url.indexOf('/'+item.url))>-1 || router.url.indexOf(item.url)>-1 )}"
+ *ngFor="let item of tabs">
+ <a [routerLink]="[item.url]" [type]="item.type" class="nav-link">{{item.name}}</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+<router-outlet></router-outlet> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts b/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts
new file mode 100644
index 0000000..8545838
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/build-artifacts.component.spec.ts
@@ -0,0 +1,49 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {BuildDesignComponent} from './build-artifacts.component';
+
+describe('BuildDesignComponent', () => {
+ let component: BuildDesignComponent;
+ let fixture: ComponentFixture<BuildDesignComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [BuildDesignComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BuildDesignComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/vnfs/build-artifacts/build-artifacts.component.ts b/src/app/vnfs/build-artifacts/build-artifacts.component.ts
new file mode 100644
index 0000000..7641aa5
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/build-artifacts.component.ts
@@ -0,0 +1,82 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import * as _ from 'underscore';
+
+@Component({ selector: 'app-build-design', templateUrl: './build-artifacts.component.html', styleUrls: ['./build-artifacts.component.css'] })
+export class BuildDesignComponent implements OnInit {
+ tabs: Array<Object> = [];
+ private allowOtherUpdates: boolean = true;
+
+ constructor (private router: Router) {
+ }
+
+ ngOnInit() {
+ this.tabs = [
+ {
+ type: 'dropdown',
+ name: 'Reference Data',
+ url: 'references',
+ }, {
+ name: 'Template',
+ type: 'dropdown',
+ url: 'templates/myTemplates',
+ }, {
+ name: 'Parameter Definition',
+ type: 'dropdown',
+ url: 'parameterDefinitions/create'
+ } /*, {
+ name: "Test",
+ url: 'test',
+ }*/
+ ];
+ }
+
+ public setAllowOtherUpdates(allowOtherUpdates: boolean) {
+ this.allowOtherUpdates = allowOtherUpdates;
+ }
+
+ // Allow / block access to the update pages of GT and PD if no reference data present
+ public updateAccessUpdatePages(selectedAction, referenceList) {
+ // Disable/enable the menu items for update pages of GT and PD.
+ if (this.isReferenceFound(selectedAction, referenceList)) {
+ this.setAllowOtherUpdates(true);
+ } else {
+ //alert("false")
+ this.setAllowOtherUpdates(false);
+ }
+ }
+
+ public isReferenceFound(selectedAction, referenceList) {
+ let selectedActioneObject = _.find(referenceList, function (obj) {
+ return obj['action'] == selectedAction;
+ });
+ if (selectedActioneObject) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts
new file mode 100644
index 0000000..8a9c112
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.spec.ts
@@ -0,0 +1,114 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+
+/* tslint:disable:no-unused-variable */
+
+import {inject, TestBed} from '@angular/core/testing';
+import {ParameterDefinitionService} from './parameter-definition.service';
+import {NotificationsService} from 'angular2-notifications';
+import {MappingEditorService} from '../../../shared/services/mapping-editor.service';
+import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service';
+import {UtilityService} from '../../../shared/services/utilityService/utility.service';
+import {ParamShareService} from '../../../shared/services/paramShare.service';
+
+
+class MockService {
+ doStuff() {
+ return this;
+ }
+}
+
+describe('ParameterDefinitionService', () => {
+ beforeEach(() => {
+ let httpUtilService = new MockService();
+ TestBed.configureTestingModule({
+ providers: [ParameterDefinitionService, NotificationsService, MappingEditorService, ParamShareService, HttpUtilService, UtilityService,
+ {provide: HttpUtilService, useValue: httpUtilService}]
+ });
+ });
+
+ it('should create a service...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ expect(service).toBeTruthy();
+ }));
+
+ it('should remove unwanted values from PD object...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ let obj = {
+ 'vnf-parameter-list': [{
+ 'ruleTypeValues': 'ruleTypeValues',
+ 'showFilterFields': 'showFilterFields',
+ 'enableFilterByValue': 'enableFilterByValue'
+ }]
+ };
+
+ expect(service.removeUnwantedvalues(obj)).toEqual({'vnf-parameter-list': [{}]});
+ }));
+
+
+ it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ let obj = [{'source': 'A&AI', 'ruleType': 'vm-name-list'}];
+
+ expect(service.populateDataUponSource(obj));
+ }));
+
+ it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ let obj = [{'source': 'Manual', 'ruleType': 'vm-name-list'}];
+
+ expect(service.populateDataUponSource(obj));
+ }));
+
+ it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ let obj = [{'source': 'Something', 'ruleType': 'vm-name-list'}];
+
+ expect(service.populateDataUponSource(obj));
+ }));
+
+
+ it('populateDataUponSource...', inject([ParameterDefinitionService], (service: ParameterDefinitionService) => {
+ let obj = [{'source': 'Something', 'ruleType': 'vm-name-list'}];
+
+ expect(service.populatePD(obj));
+ }));
+
+ it('processPDfile...', inject([ParameterDefinitionService], (service: ParameterDefinitionService)=> {
+ let yaml = "---\nkind: Property Definition\nversion: V1\nvnf-parameter-list:\n- name: LICENSE_KEY\n type: null\n description: null\n required: null\n default: null\n source: Manual\n rule-type: null\n request-keys: null\n response-keys: null";
+ let expectedPD = [{"name":"LICENSE_KEY","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null,
+ "request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null
+ ,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}];
+
+ expect(service.processPDfile("testfile.yaml", yaml)).toEqual(expectedPD);
+
+ }));
+
+ // it('processKeyFile...', inject([ParameterDefinitionService, ParamShareService], (service: ParameterDefinitionService, paramShareService: ParamShareService)=> {
+ // let keyFile = "PARAMVALUE|SOURCE|RULETYPE|KEY1|VALUE1|KEY2|VALUE2|KEY3|VALUE3\nvalue1|INSTAR|interface_ip_address|UniqueKeyName1|addressfqdn123|UniqueKeyValue|m001ssc001p1n001v001|FieldKeyName|ipaddress_v4\nvalue2|INSTAR|interface_ip_address|UniqueKeyName2|addressfqdnAsgar1|UniqueKeyValue|m001ssc001p1n001v002|FieldKeyName|ipaddress_v4";
+ // let expectedPD = [{"name":"name1","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null,
+ // "request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null
+ // ,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}];
+ // localStorage['paramsContent'] = "{ \"name1\":\"value1\",\"name2\":\"value2\"}";
+ // paramShareService.setSessionParamData(expectedPD)
+ // expect(service.processKeyFile("testfile.txt", keyFile)).toEqual(expectedPD);
+
+ // }));
+
+});
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts
new file mode 100644
index 0000000..89eeec2
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter-definition.service.ts
@@ -0,0 +1,509 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+
+import {Injectable, ViewChild} from '@angular/core';
+import {saveAs} from 'file-saver';
+import {ParamShareService} from '../../../shared/services/paramShare.service';
+import {MappingEditorService} from '../../../shared/services/mapping-editor.service';
+import {ModalComponent} from '../../../shared/modal/modal.component';
+import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service';
+import {UtilityService} from '../../../shared/services/utilityService/utility.service';
+import {NotificationsService} from 'angular2-notifications';
+import 'rxjs/add/operator/map';
+
+let YAML = require('yamljs');
+
+declare var $: any;
+
+@Injectable()
+export class ParameterDefinitionService {
+
+ public vnfcTypeData: string = '';
+ public selectedUploadType: string;
+ @ViewChild(ModalComponent) modalComponent: ModalComponent;
+ public title: string;
+ public parameterDefinitionMap: { [index: string]: string; } = {};
+ public parameterNameValues = {};
+ public displayParamObjects;
+ public modelParamDefinitionObjects;
+ public vnfType: any;
+ vnfcType: any;
+ protocol: any;
+ public refNameObj = {};
+ public action;
+ public artifactName;
+ public type;
+ public appDataObject: any;
+ public downloadDataObject: any;
+ public artifact_fileName;
+ identifier: any;
+ public myKeyFileName = null;
+ public myPdFileName = null;
+ private selectedActionReference: any;
+ private apiToken = localStorage['apiToken'];
+ private userId = localStorage['userId'];
+
+ constructor(private mappingEditorService: MappingEditorService,
+ private paramShareService: ParamShareService,
+ private nService: NotificationsService,
+ private httpService: HttpUtilService,
+ private utilService: UtilityService) {
+
+ }
+
+ public initialize() {
+
+ }
+
+ public setValues(vnfType, vnfcType, protocol, action, artifactName) {
+ this.vnfType = vnfType;
+ this.vnfcType = vnfcType;
+ this.protocol = protocol;
+ this.action = action;
+ this.artifact_fileName = artifactName;
+ }
+
+ public afterInit(artifactName, displayParamObjects) {
+
+ }
+
+ //========================== End of saveChanges() Method============================================
+ /* Saves pd to appc */
+ public sendPD(yamlString: String) {
+ let result: any;
+ let payload = '{"userID": "' + this.userId + '","vnf-type" : "' + this.vnfType + '","action" : "' + this.action + '","artifact-name" : "' + this.artifact_fileName + '","artifact-type" : "APPC-CONFIG","artifact-version" : "0.0.1","artifact-contents" : ' + yamlString + '}';
+ let input = {
+ 'input': {
+ 'design-request': {
+ 'request-id': this.apiToken,
+ 'action': 'uploadArtifact',
+ 'payload': payload
+ }
+ }
+ };
+ this.appDataObject.pd = input;
+ }
+
+
+ //========================== End of filetrByFieldChanged() Method============================================
+ removeUnwantedvalues(obj) {
+ let result = Object.assign({}, obj);
+ result['vnf-parameter-list'].forEach(obj => {
+ delete obj['ruleTypeValues'];
+ delete obj['showFilterFields'];
+ delete obj['enableFilterByValue'];
+ });
+ return result;
+ }
+
+ //========================== End of removeUnwantedvalues() Method============================================
+ populateDataUponSource(displayParamObjects) {
+ displayParamObjects.forEach(parameter => {
+ if (parameter.source == 'A&AI') {
+ parameter.ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list'];
+ if (parameter['rule-type'] == 'vm-name-list' || parameter['rule-type'] == 'vnfc-name-list' || parameter['rule-type'] == 'vnfc-oam-ipv4-address-list') {
+ parameter.showFilterFields = true;
+ parameter.enableFilterByValue = false;
+ } else {
+ parameter.showFilterFields = false;
+ }
+
+ } else if (parameter.source == 'Manual') {
+ parameter.ruleTypeValues = [null];
+ }
+ else {
+ parameter.ruleTypeValues = [parameter['rule-type']];
+ }
+ });
+
+ }
+
+ //========================== End of getPD() Method============================================
+ populatePD(result: any) {
+ let fileContent = JSON.stringify(result);
+ //Added code to deserialize, serialize and format the response keys for display purposes ??May be unneessary?? To Do: - Check
+ let fileObj = JSON.parse(fileContent);
+ this.displayParamObjects = this.formatFileContentForDisplay(fileObj);
+ this.populateDataUponSource(this.displayParamObjects);
+ this.formatResponseForKey(this.displayParamObjects);
+ if (undefined !== this.displayParamObjects)
+ this.modelParamDefinitionObjects = this.displayParamObjects;
+ if (this.displayParamObjects !== undefined && this.displayParamObjects.length > 0) {
+ this.paramShareService.setSessionParamData(this.displayParamObjects);
+ }
+ return this.displayParamObjects;
+ }
+
+ //========================== End of populatePD() Method============================================
+ /* Formats each object read from YAML file as per page expectations */
+ formatResponseForKey(param: any[]) {
+ for (var i = 0; i < param.length; i++) {
+ this.formatKeys(param[i]);
+ }
+ }
+
+ //========================== End of formatResponseForKey() Method============================================
+ /* Formats for responsekeys of each object */
+ formatKeys(parameterDefinitionObject: any) {
+ if (null == parameterDefinitionObject || undefined === parameterDefinitionObject)
+ return;
+ if (null == parameterDefinitionObject['response-keys'])
+ parameterDefinitionObject['response-keys'] = [{}];
+ for (var j = 0; j < 5; j++) {
+ var keysObj = {
+ 'key-name': null,
+ 'key-value': null
+ };
+ if (undefined == parameterDefinitionObject['response-keys'][j] || null == parameterDefinitionObject['response-keys'][j]) {
+ parameterDefinitionObject['response-keys'].push(keysObj);
+ }
+ if (undefined == parameterDefinitionObject['response-keys'][j]['key-name']) {
+ parameterDefinitionObject['response-keys'][j]['key-name'] = null;
+ }
+ if (undefined == parameterDefinitionObject['response-keys'][j]['key-value']) {
+ parameterDefinitionObject['response-keys'][j]['key-value'] = null;
+ }
+ }
+ if (null == parameterDefinitionObject['request-keys'])
+ parameterDefinitionObject['request-keys'] = [{}];
+ for (var k = 0; k < 3; k++) {
+ var keysObj = {
+ 'key-name': null,
+ 'key-value': null
+ };
+ if (undefined == parameterDefinitionObject['request-keys'][k] || null == parameterDefinitionObject['request-keys'][k]) {
+ parameterDefinitionObject['request-keys'].push(keysObj);
+ }
+ if (undefined == parameterDefinitionObject['request-keys'][k]['key-name']) {
+ parameterDefinitionObject['request-keys'][k]['key-name'] = null;
+ }
+ if (undefined == parameterDefinitionObject['request-keys'][k]['key-value']) {
+ parameterDefinitionObject['request-keys'][k]['key-value'] = null;
+ }
+ }
+ }
+
+ //========================== End of formatKeys() Method============================================
+ //Send null if there are no keys present - Check with key names being absent
+ formatKeysForFileGeneration() {
+ for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
+ if (this.modelParamDefinitionObjects[i]['response-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['response-keys'][2]['key-name'] == null)
+ this.modelParamDefinitionObjects[i]['response-keys'] = null;
+ if (this.modelParamDefinitionObjects[i]['request-keys'][0]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][1]['key-name'] == null && this.modelParamDefinitionObjects[i]['request-keys'][2]['key-name'] == null)
+ this.modelParamDefinitionObjects[i]['request-keys'] = null;
+ }
+ }
+
+ //========================== End of formatKeysForFileGeneration() Method============================================
+ /* Fn to restore response keys in desired format per backend consumption*/
+ processResponseKeys(saveModel: any[]) {
+ for (var i = 0; i < saveModel.length; i++) {
+ if (saveModel[i]['response-keys'] != null) {
+ saveModel[i]['response-keys-new'] = [{}];
+ saveModel[i]['response-keys-new'][0] = {};//An array of objects ?? so accessing first element
+ if (undefined != saveModel[i]['response-keys'][0]['key-name'] && undefined != saveModel[i]['response-keys'][0]['key-value']) {
+ let keyName1 = saveModel[i]['response-keys'][0]['key-name'];
+ saveModel[i]['response-keys-new'][0][keyName1] = saveModel[i]['response-keys'][0]['key-value'];
+ }
+ if (undefined != saveModel[i]['response-keys'][1]['key-name'] && undefined != saveModel[i]['response-keys'][1]['key-value']) {
+ let keyName2 = saveModel[i]['response-keys'][1]['key-name'];
+ saveModel[i]['response-keys-new'][0][keyName2] = saveModel[i]['response-keys'][1]['key-value'];
+ }
+ if (undefined != saveModel[i]['response-keys'][2]['key-name'] && undefined != saveModel[i]['response-keys'][2]['key-value']) {
+ let keyName3 = saveModel[i]['response-keys'][2]['key-name'];
+ saveModel[i]['response-keys-new'][0][keyName3] = saveModel[i]['response-keys'][2]['key-value'];
+ }
+ if (saveModel[i]['response-keys'][3]['key-value'] != undefined && saveModel[i]['response-keys'][3]['key-value'] != null) {
+ let keyName4 = saveModel[i]['response-keys'][3]['key-name'];
+ saveModel[i]['response-keys-new'][0]['filter-by-key'] = saveModel[i]['response-keys'][3]['key-value'];
+ }
+ if (saveModel[i]['response-keys'][4]['key-value'] != undefined && saveModel[i]['response-keys'][4]['key-value'] != null) {
+ let keyName4 = saveModel[i]['response-keys'][4]['key-name'];
+ saveModel[i]['response-keys-new'][0]['filter-by-value'] = saveModel[i]['response-keys'][4]['key-value'];
+ }
+ }
+ else {
+ saveModel[i]['response-keys-new'] = null;
+ }
+ delete saveModel[i]['response-keys'];
+ saveModel[i]['response-keys'] = saveModel[i]['response-keys-new'];
+ delete saveModel[i]['response-keys-new'];
+ }
+ return saveModel;
+ }
+
+ //========================== End of processResponseKeys() Method============================================
+ /*Fn to format response keys for front end display */
+ formatFileContentForDisplay(fileModel: any[]) {
+ for (var i = 0; i < fileModel.length; i++) {
+ if (undefined != fileModel[i]['response-keys']) {
+ let testObj = fileModel[i]['response-keys'];
+ let keyNum = 0;
+ fileModel[i]['response-keys-new'] = [{}];
+ for (var prop in testObj[0]) {
+ if (testObj[0].hasOwnProperty(prop)) {
+ let key = prop;
+ fileModel[i]['response-keys-new'][keyNum] = {};
+ fileModel[i]['response-keys-new'][keyNum]['key-name'] = key;
+ fileModel[i]['response-keys-new'][keyNum]['key-value'] = testObj[0][key];
+ }
+ keyNum++;
+ }
+ delete fileModel[i]['response-keys'];
+ fileModel[i]['response-keys'] = fileModel[i]['response-keys-new'];
+ delete fileModel[i]['response-keys=new'];
+ }
+ }
+ return fileModel;
+ }
+
+ //========================== End of openModal() Method============================================
+ getCorrectParameterDefinitionObject(paramName: string) {
+ var result = {
+ 'obj': {},
+ 'present': false
+ };
+ for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
+ var paramObj = this.modelParamDefinitionObjects[i];
+ if (paramObj.name === paramName) {
+ result.obj = this.modelParamDefinitionObjects[i];
+ result.present = true;
+ return result;
+ }
+ }
+ var parameterDefinitionObject = {
+ 'name': paramName,
+ 'type': null,
+ 'description': null,
+ 'required': null,
+ 'default': null,
+ 'source': null,
+ 'rule-type': null,
+ 'response-keys': [{}],
+ 'request-keys': [{}]
+ };
+ result.obj = parameterDefinitionObject;
+ result.present = false;
+ return result;
+ }
+
+ //========================== End of clearSessionStorageForParam() Method============================================
+ isValidateSourceAndResponseKeys(objs: any[]) {
+ let isValid = true;
+ if (undefined != objs || null != objs) {
+ for (var i = 0; i < objs.length; i++) {
+ if (objs[i].source == 'INSTAR' && (null == objs[i]['response-keys'] || undefined == objs[i]['response-keys'])) {
+ isValid = false;
+ return isValid;
+ }
+ }
+ }
+ return isValid;
+ }
+
+
+ public prepareFileName(): any {
+ let fileNameObject: any = this.mappingEditorService.latestAction;
+ this.appDataObject = this.mappingEditorService.appDataObject;
+ this.downloadDataObject = this.mappingEditorService.downloadDataObject;
+ return fileNameObject;
+ }
+
+ public destroy(displayParamObjects) {
+ this.displayParamObjects = displayParamObjects;
+ if (this.mappingEditorService.referenceNameObjects) {
+ this.saveChanges('send');
+ this.saveChanges('download');
+ this.mappingEditorService.changeNavAppData(this.appDataObject);
+ this.mappingEditorService.changeNavDownloadData(this.downloadDataObject);
+ }
+ }
+
+ //========================== End of fileChangeEvent() Method============================================
+ /* Saves pd file in YAML format */
+ public saveChanges(downLoadOrSend: String) {
+ if (undefined != this.displayParamObjects && null != this.displayParamObjects && this.displayParamObjects.length > 0) {
+ this.paramShareService.setSessionParamData(this.displayParamObjects);
+
+ //Generate File Name per given rules - if not, return without saving
+ this.modelParamDefinitionObjects = this.displayParamObjects.slice(0);
+ this.paramShareService.setDisplayData(this.displayParamObjects);
+ this.formatKeysForFileGeneration();
+ //Added code to serialize, deserialize and then make changes needed to save response keys as needed in pd file
+ let jsonString = JSON.stringify(this.modelParamDefinitionObjects, null, '\t');
+ jsonString = jsonString.replace(/"null"/g, 'null');
+ let saveModel = JSON.parse(jsonString);
+ let pdFileObject = this.processResponseKeys(saveModel);
+ //Validate for Source =INSTAR and responsekeys present
+ if (this.isValidateSourceAndResponseKeys(pdFileObject)) {
+ let yamlObject = {
+ 'kind': 'Property Definition',
+ 'version': 'V1',
+ 'vnf-parameter-list': []
+ };
+ yamlObject['vnf-parameter-list'] = pdFileObject;
+ yamlObject = this.removeUnwantedvalues(yamlObject);
+ let yamlStringTemp = YAML.stringify(yamlObject, 6, 1);
+ var re = /\'/gi;
+ var newYamlStringTemp = yamlStringTemp.replace(re, '"');
+ var re2 = / -\n +/gi;
+ var newYamlStringTemp2 = newYamlStringTemp.replace(re2, '- ');
+ let yamlString = '---\n' + newYamlStringTemp2;
+ if (downLoadOrSend === 'download') {
+ var blob = new Blob([yamlString], {
+ type: 'text/plain'
+ });
+ //let fileName = "pd_" + this.action + "_" + this.type + "_0.0.1V.yaml"
+ this.downloadDataObject.pd.pdData = yamlString;
+ this.downloadDataObject.pd.pdFileName = this.artifact_fileName;
+ }
+ else {
+ this.sendPD(JSON.stringify(yamlString));
+ }
+ }
+ else {
+ for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
+ this.formatKeys(this.modelParamDefinitionObjects[i]);
+ }
+ this.nService.error('Error', 'Response Keys cannot be empty if source is INSTAR');
+ return;
+ }
+ //Restore Keys for display
+ for (var i = 0; i < this.modelParamDefinitionObjects.length; i++) {
+ this.formatKeys(this.modelParamDefinitionObjects[i]);
+ }
+ }
+
+ }
+
+
+ //This method will create parameter definitions as an array of objects from template name-value pairs and associative array for value from external key file if present
+ createOrUpdateParameterDefinitionData(usecase) {
+ this.parameterNameValues = JSON.parse(localStorage['paramsContent']);
+ this.parameterDefinitionMap = this.paramShareService.getData();
+ //Return if there are no name-value pairs or send some alert notification
+ if (undefined != this.modelParamDefinitionObjects && this.modelParamDefinitionObjects.length > 0 && usecase == 'create') {
+ //Do not recreate if object is already created
+ return;
+ }
+ else {
+ }
+ this.parameterDefinitionMap = this.paramShareService.getData();
+ //To Do:: Add Check for empty parameterDefinitionmap
+ var nameValueObj = {}, pName, pValue;
+ for (var key in this.parameterNameValues) {
+ if (this.parameterNameValues.hasOwnProperty(key)) {
+ pName = key;
+ pValue = this.parameterNameValues[key];
+ }
+
+ if (this.parameterDefinitionMap !== undefined)
+ //Check if parameter exists - if so, just update the keys, else create new object
+ var result = this.getCorrectParameterDefinitionObject(pName);
+ var parameterDefinitionObject = result.obj;
+ if (parameterDefinitionObject['source'] != 'A&AI' && (undefined !== this.parameterDefinitionMap) && (undefined !== this.parameterDefinitionMap[pValue.toUpperCase()])) {
+ var fields = this.parameterDefinitionMap[pValue.toUpperCase()].split('|');
+ //Starts with 2, first vallue is source, second is rule-type
+ let respInd = 0;
+ for (var i = 2; i < fields.length; i += 2) {
+ parameterDefinitionObject['response-keys'][respInd] = {};
+ parameterDefinitionObject['response-keys'][respInd]['key-name'] = fields[i];
+ if ((i + 1) < fields.length) {
+ parameterDefinitionObject['response-keys'][respInd]['key-value'] = fields[i + 1];
+ }
+ respInd++;
+ }
+ parameterDefinitionObject['source'] = fields[0];
+ parameterDefinitionObject['rule-type'] = fields[1];
+ } else {
+ if (parameterDefinitionObject['source'] === 'INSTAR') {
+ parameterDefinitionObject['source'] = 'Manual';
+ parameterDefinitionObject['ruleTypeValues'] = [null];
+ parameterDefinitionObject['rule-type'] = null;
+ parameterDefinitionObject['showFilterFields'] = false;
+ for (let x = 0; x < 5; x++) {
+ parameterDefinitionObject['response-keys'][x]['key-name'] = null;
+ parameterDefinitionObject['response-keys'][x]['key-value'] = null;
+ }
+ }
+ }
+ this.formatKeys(parameterDefinitionObject); //Ensure there are 3 elements for response-keys, request-keys for display purposes
+ if (!result.present) { //only push if not present
+ this.modelParamDefinitionObjects.push(parameterDefinitionObject);
+ }
+ }
+ for (var indx in this.modelParamDefinitionObjects) {
+ if (this.modelParamDefinitionObjects[indx] != undefined && (this.modelParamDefinitionObjects[indx].source == undefined || this.modelParamDefinitionObjects[indx].source == null || this.modelParamDefinitionObjects[indx].source == '')) {
+ this.modelParamDefinitionObjects[indx].source = 'Manual';
+ }
+ }
+ this.displayParamObjects = this.modelParamDefinitionObjects.slice(0);
+ this.paramShareService.setDisplayData(this.displayParamObjects);
+ }
+
+ public processKeyFile(fileName, result) {
+ this.myKeyFileName = fileName;
+ if (!this.myKeyFileName.endsWith('.txt')) {
+ this.nService.error('Error', 'Uploaded file is not a TXT file');
+ }
+ this.parameterDefinitionMap = {};
+ var rows = result.split(/\r\n|\r|\n/g);
+ for (var i = 1; i < rows.length; i++) { //Omit headings, so start from 1
+ let ind = rows[i].indexOf('|');
+ let key = rows[i].slice(0, ind);
+ let value = rows[i].slice(ind + 1);
+ this.parameterDefinitionMap[key.toUpperCase()] = value;
+ }
+ this.paramShareService.setData(this.parameterDefinitionMap);
+ //this.notificationService.notifySuccessMessage('External Key file successfully uploaded..');
+ let sessionVar = [{}];
+ sessionVar = this.paramShareService.getSessionParamData();
+ if (sessionVar !== undefined && sessionVar != null && sessionVar.length > 0) {
+ if (undefined == this.displayParamObjects)
+ this.displayParamObjects = this.modelParamDefinitionObjects = [];
+ this.displayParamObjects = sessionVar;
+ this.modelParamDefinitionObjects = this.displayParamObjects;
+ if (localStorage['paramsContent'] && (undefined !== this.displayParamObjects) && (this.displayParamObjects.length > 0)) {
+ this.createOrUpdateParameterDefinitionData('update');
+ //update the session variable with the updated data
+ this.paramShareService.setSessionParamData(this.displayParamObjects);
+ }
+ } else {
+ this.displayParamObjects = this.modelParamDefinitionObjects = [];
+ }
+ this.populateDataUponSource(this.displayParamObjects);
+ return this.displayParamObjects;
+ }
+
+ public processPDfile(fileName, result) {
+ this.myPdFileName = fileName;
+ if (!this.myPdFileName.endsWith('.yaml')) {
+ this.nService.error('Error', 'Uploaded file is not a YAML file');
+ }
+ var pdObject = YAML.parse(result);
+ let fileModel = pdObject['vnf-parameter-list'];
+ this.populatePD(fileModel);
+ return this.displayParamObjects;
+ }
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css
new file mode 100644
index 0000000..be35e44
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.css
@@ -0,0 +1,22 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html
new file mode 100644
index 0000000..ed0fbd3
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.html
@@ -0,0 +1,219 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+-->
+
+<simple-notifications [options]="options"></simple-notifications>
+<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'"
+ [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress>
+<div class="card" style=" margin-bottom: 23px;">
+ <img class="card-img-top" data-src="holder.js/100%x180/" alt="">
+ <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;">
+ <div class="row" style="padding: 15px 25px">
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Action</label>
+ <input class="form-control" type="text" disabled value="{{action}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" />
+ </div>
+ <div *ngIf="(action === 'ConfigScaleOut')" class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>templateIdentifier</label><input class="form-control" type="text" disabled value="{{identifier}}" />
+ </div>
+ </div>
+ </div>
+</div>
+<div class="row create-wrapper">
+ <div class="col-md-12">
+ <div class="row" style="padding: 5px 5px">
+ <div class="col-12 mb-3">
+ <div class="input-group">
+ <input id="inputFile1" class="file" hidden #myInput1 type='file' (change)="fileChange(myInput1, 'pdfile')">
+ <input [(ngModel)]="myPdFileName" type="text" class="input-lg" disabled placeholder="Upload parameters from PC" style="width:85%;">
+ <button [disabled]="(undefined == mappingEditorService.latestAction)" (click)="browsePdFile($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg"
+ type="button"> UPLOAD PD FILE
+ </button>
+ </div>
+ </div>
+ <div class="col-12">
+ <div class="input-group">
+ <input id="inputFile2" class="file" hidden #myInput2 type='file' (change)="fileChange(myInput2, 'keyfile')">
+ <input [(ngModel)]="myKeyFileName" type="text" class="input-lg" disabled placeholder="Upload key file from PC. You can upload a key file only if you have some parameters."
+ style="width:85%;">
+ <button [disabled]="(!(undefined !== displayParamObjects && displayParamObjects.length>0))" (click)="browseKeyFile($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg"
+ type="button">UPLOAD KEY FILE
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <br>
+ <hr>
+ <!--h4>testing{{initialData}}</h4-->
+ <div *ngIf="((undefined !== displayParamObjects && displayParamObjects.length>0) ) " class="col-md-12 ">
+ <form *ngIf="undefined !== displayParamObjects" class="form-inline" novalidate #paramForm="ngForm" (ngSubmit)="saveChanges('download', paramForm.valid)">
+
+ <div style="height: 210px; overflow: auto;">
+ <table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
+ <thead>
+ <tr>
+ <th class="mdl-data-table__cell--non-numeric">NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">DESCRIPTION</th>
+ <th class="mdl-data-table__cell--non-numeric">TYPE</th>
+ <th class="mdl-data-table__cell--non-numeric">REQUIRED</th>
+ <th class="mdl-data-table__cell--non-numeric">DEFAULT</th>
+ <th class="mdl-data-table__cell--non-numeric">SOURCE</th>
+ <th class="mdl-data-table__cell--non-numeric">RULETYPE</th>
+ <th class="mdl-data-table__cell--non-numeric">FILTER BY FIELD</th>
+ <th class="mdl-data-table__cell--non-numeric">FILTER BY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">RESPKEY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY NAME</th>
+ <th class="mdl-data-table__cell--non-numeric">REQKEY VALUE</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let obj of displayParamObjects; let i = index">
+ <td class="mdl-data-table__cell--non-numeric">
+ <input required id="id1" [(ngModel)]="obj.name" #objName="ngModel" name="objName{{i}}" style="width:300px">
+ <span class="error-message" [hidden]="objName.valid || (objName.pristine && !paramForm.submitted)">Required Field</span>
+ </td>
+ <td class="mdl-data-table__cell--non-numeric"><input [(ngModel)]="obj.description" #objDesc="ngModel" name="objDesc{{i}}">
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">
+ <select id="id3" [(ngModel)]="obj.type" name="{{'objType'+i}}">
+ <option *ngFor="let typ of typeValues"
+ [value]="typ"
+ [selected]="obj.type === typ"
+ >
+ {{typ}}
+ </option>
+ </select>
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">
+ <select [(ngModel)]="obj.required" #objRequired="ngModel" name="{{'objRequired'+i}}">
+ <option *ngFor="let req of requiredValues"
+ [value]="req"
+ [selected]="req === obj.required"
+ >
+ {{req}}
+ </option>
+ </select>
+ </td>
+ <td class="mdl-data-table__cell--non-numeric"><input id="id1" [(ngModel)]="obj.default" #objDefault="ngModel" name="objDefault{{i}}"></td>
+ <td class="mdl-data-table__cell--non-numeric">
+ <select class="form-control" required id="id3" [(ngModel)]="obj.source" #objSource="ngModel" (ngModelChange)="sourceChanged($event,obj)" name="{{'objSource'+i}}">
+ <option *ngFor="let src of sourceValues"
+ [value]="src"
+ [selected]="src === obj.source"
+ [disabled]="src === 'INSTAR'">
+ {{src}}
+ </option>
+
+ </select>
+ <span class="error-message" [hidden]="objSource.valid || (objSource.pristine && !paramForm.submitted)">Required Field</span>
+ </td>
+
+ <td class="mdl-data-table__cell--non-numeric">
+ <select (ngModelChange)="ruleTypeChanged($event,obj)" class="form-control" id="id4" [(ngModel)]="obj['rule-type']" #objRuleType="ngModel" name="objRuleType{{i}}"
+ list="ruleTypes">
+ <option *ngFor="let rTyp of obj.ruleTypeValues;" [value]="rTyp"
+ [selected]="rTyp === obj.rule-type">
+ {{rTyp}}
+ </option>
+ </select>
+ </td>
+
+ <td>
+ <select *ngIf="obj.showFilterFields" (ngModelChange)="filetrByFieldChanged($event,obj)" class="form-control" id="id4" [(ngModel)]="obj['response-keys'][3]['key-value']"
+ #objfilterByField="ngModel" name="filterByField{{i}}" list="ruleTypes">
+ <option *ngFor="let fTyp of filterByFieldvalues;" [value]="fTyp"
+ [selected]="fTyp === obj['response-keys'][3]['key-value']">
+ {{fTyp}}
+ </option>
+ </select>
+ </td>
+ <td>
+ <input *ngIf="obj.showFilterFields" [disabled]="!(obj.enableFilterByValue)" type="text" [value]="obj['response-keys'][4]['key-value']" class="form-control"
+ id="id4" [(ngModel)]="obj['response-keys'][4]['key-value']" #objfilterByValue="ngModel" name="objfilterByValue{{i}}" list="ruleTypes">
+ </td>
+
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][0]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][0]['key-value']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][1]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][1]['key-value']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][2]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['response-keys'][2]['key-value']}}
+
+ </td>
+
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][0]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][0]['key-value']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][1]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][1]['key-value']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][2]['key-name']}}
+
+ </td>
+ <td class="mdl-data-table__cell--non-numeric">{{obj['request-keys'][2]['key-value']}}
+
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ `
+ </div>
+
+ </form>
+ </div>
+</div> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts
new file mode 100644
index 0000000..2668f2b
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.spec.ts
@@ -0,0 +1,197 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed, inject} from '@angular/core/testing';
+import {NO_ERRORS_SCHEMA} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {NotificationService} from '../../../shared/services/notification.service';
+import {ParamShareService} from '../../../shared/services/paramShare.service';
+import {MappingEditorService} from '../../../shared/services/mapping-editor.service';
+import {ModalComponent} from '../../../shared/modal/modal.component';
+import {DialogService} from 'ng2-bootstrap-modal';
+import {ConfirmComponent} from '../../../shared/confirmModal/confirm.component';
+import {RouterTestingModule} from '@angular/router/testing';
+import {HttpUtilService} from '../../../shared/services/httpUtil/http-util.service';
+import {UtilityService} from '../../../shared/services/utilityService/utility.service';
+
+import {BuildDesignComponent} from '../build-artifacts.component';
+import {NotificationsService} from 'angular2-notifications';
+import {HomeComponent} from '../../../home/home/home.component';
+import {LogoutComponent} from '../../../shared/components/logout/logout.component';
+import {HelpComponent} from '../../../shared/components/help/help/help.component';
+import {AboutUsComponent} from '../../../about-us/aboutus.component';
+import {TestComponent} from '../../../test/test.component';
+import {ParameterComponent} from './parameter.component';
+import {HttpModule} from '@angular/http';
+import { NgProgress } from 'ngx-progressbar';
+
+
+
+describe('ParameterComponent', () => {
+ let component: ParameterComponent;
+ let fixture: ComponentFixture<ParameterComponent>;
+ const routes = [
+ {
+ path: 'home',
+ component: HomeComponent
+ }, {
+ path: 'vnfs',
+ loadChildren: './vnfs/vnfs.module#VnfsModule'
+ }, {
+ path: 'test',
+ component: TestComponent
+ },
+ {
+ path: 'help',
+ component: HelpComponent
+ }, {
+ path: 'aboutUs',
+ component: AboutUsComponent
+ }, {
+ path: 'logout',
+ component: LogoutComponent
+ }, {
+ path: '',
+ redirectTo: '/home',
+ pathMatch: 'full'
+ }
+ ];
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ParameterComponent, HomeComponent, TestComponent, HelpComponent, AboutUsComponent, LogoutComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ imports: [HttpModule, FormsModule, RouterTestingModule.withRoutes(routes)],
+ providers: [UtilityService, NgProgress, BuildDesignComponent, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService, NotificationsService]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ParameterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+
+ it('should retrieve PD from APPC...', () => {
+ expect(component.getPD());
+ });
+
+ it('should infer some information from reference object...', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => {
+ mappingEditorService.latestAction = {"action":"Configure","action-level":"vnf","scope":{"vnf-type":"ticktack","vnfc-type":""},"template":"Y","vm":[],"device-protocol":"CHEF","user-name":"","port-number":"","artifact-list":[{"artifact-name":"template_Configure_ticktack_0.0.1V.json","artifact-type":"config_template"},{"artifact-name":"pd_Configure_ticktack_0.0.1V.yaml","artifact-type":"parameter_definitions"}],"scopeType":"vnf-type"};
+ expect(component.ngOnInit());
+ expect(component.vnfType).toEqual('ticktack');
+ expect(component.vnfcType).toEqual('');
+ expect(component.protocol).toEqual('CHEF');
+ expect(component.action).toEqual('Configure');
+ expect(component.artifact_fileName).toEqual('pd_Configure_ticktack_0.0.1V.yaml');
+ }));
+
+
+ it('should retrieve the PD from cache...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ mappingEditorService.latestAction = {"action":"Configure","action-level":"vnf","scope":{"vnf-type":"ticktack","vnfc-type":""},"template":"Y","vm":[],"device-protocol":"CHEF","user-name":"","port-number":"","artifact-list":[{"artifact-name":"template_Configure_ticktack_0.0.1V.json","artifact-type":"config_template"},{"artifact-name":"pd_Configure_ticktack_0.0.1V.yaml","artifact-type":"parameter_definitions"}],"scopeType":"vnf-type"};
+ paramShareService.setSessionParamData("TEST PD INFORMATION")
+ expect(component.ngAfterViewInit()).toEqual("TEST PD INFORMATION");
+ }));
+
+/*
+ it('should read file key file content...', () => {
+ let input = {"__zone_symbol__changefalse":[{"type":"eventTask","state":"running","source":"HTMLInputElement.addEventListener:change","zone":"angular","runCount":2}]};
+ expect(component.fileChange(input, 'keyfile'));
+ });
+
+let content = new Blob(["PARAMVALUE|SOURCE|RULETYPE|KEY1|VALUE1|KEY2|VALUE2|KEY3|VALUE3\nvalue1|INSTAR|interface_ip_address|UniqueKeyName1|addressfqdn123|UniqueKeyValue|m001ssc001p1n001v001|FieldKeyName|ipaddress_v4\nvalue2|INSTAR|interface_ip_address|UniqueKeyName2|addressfqdnAsgar1|UniqueKeyValue|m001ssc001p1n001v002|FieldKeyName|ipaddress_v4"]
+{includes:()});
+let file = new File(content, "test.txt");
+ it('should read file PD file content...', () => {
+ let input = {"__zone_symbol__changefalse":[{"type":"eventTask","state":"running","source":"HTMLInputElement.addEventListener:change","zone":"angular","runCount":2}]};
+
+ expect(component.fileChange(input, 'pdfile'));
+ });
+ */
+
+ it('should set the ruletypes for source A&AI...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = "A&AI";
+ expect(component.sourceChanged(data, obj));
+ expect(obj.ruleTypeValues).toEqual([null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list']);
+ }));
+
+ it('should set the ruletypes for source Manual...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = "Manual";
+ expect(component.sourceChanged(data, obj));
+ expect(obj.ruleTypeValues).toEqual([null]);
+ expect(obj['rule-type']).toBeNull();
+ }));
+
+ it('should set the ruletypes for source INSTAR...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = "INSTAR";
+ expect(component.sourceChanged(data, obj));
+ expect(obj.ruleTypeValues).toEqual([null]);
+ }));
+
+ it('should set the ruletypes for ruletype null...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = null
+ expect(component.ruleTypeChanged(data, obj));
+ expect(obj['showFilterFields']).toBeFalsy();
+ expect(obj['rule-type']).toBeNull();
+ }));
+
+ it('should set the ruletypes for ruletype vm-name-list...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = 'vm-name-list';
+ let sourceObject = component.ruleTypeConfiguaration[data];
+
+ expect(component.ruleTypeChanged(data, obj));
+ expect(obj['showFilterFields']).toBeTruthy();
+ expect(obj['rule-type']).toBeNull();
+
+ for (let x = 0; x < sourceObject.length; x++) {
+ expect(obj['response-keys'][x]['key-name']).toEqual(sourceObject[x]['key-name']);
+ expect(obj['response-keys'][x]['key-value']).toEqual(sourceObject[x]['key-value']);
+ }
+ }));
+
+
+ it('should set the ruletypes for ruletype vnf-name...', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ let obj = {"name":"name1","type":"ipv4-address","description":"xxx","required":"true","default":null,"source":"A&AI","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}
+ let data = "vnf-name";
+ expect(component.ruleTypeChanged(data, obj));
+ expect(obj['showFilterFields']).toBeFalsy();
+ expect(obj['response-keys'][3]['key-name']).toBeNull;
+ expect(obj['response-keys'][3]['key-value']).toBeNull;
+ expect(obj['response-keys'][4]['key-name']).toBeNull;
+ expect(obj['response-keys'][4]['key-value']).toBeNull;
+ }));
+
+
+
+});
diff --git a/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts
new file mode 100644
index 0000000..2732473
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-definitions/parameter.component.ts
@@ -0,0 +1,430 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { saveAs } from 'file-saver';
+import { ParamShareService } from '../../../shared/services/paramShare.service';
+import { MappingEditorService } from '../../../shared/services/mapping-editor.service';
+import { ModalComponent } from '../../../shared/modal/modal.component';
+import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service';
+import { UtilityService } from '../../../shared/services/utilityService/utility.service';
+import { environment } from '../../../../environments/environment';
+import { NotificationsService } from 'angular2-notifications';
+import { ParameterDefinitionService } from './parameter-definition.service';
+import 'rxjs/add/operator/map';
+import { NgProgress } from 'ngx-progressbar';
+
+
+let YAML = require('yamljs');
+
+declare var $: any;
+
+@Component({
+ selector: 'parameter-form',
+ templateUrl: './parameter.component.html',
+ styleUrls: ['../reference-dataform/reference-dataform.component.css'],
+ providers: [ParameterDefinitionService]
+})
+export class ParameterComponent implements OnInit {
+ public paramForm: any;
+ public actionType: any;
+ public showFilterFields: boolean;
+ public filterByFieldvalues = [null, 'vm-number', 'vnfc-function-code'];
+ public ruleTypeConfiguaration = {
+ 'vnf-name': [
+ {
+ 'key-name': 'unique-key-name',
+ 'key-value': 'parent-name'
+ },
+ {
+ 'key-name': 'unique-key-value',
+ 'key-value': 'vnf'
+ },
+ {
+ 'key-name': 'field-key-name',
+ 'key-value': 'vnf-name'
+ }
+ ],
+ 'vm-name-list': [
+ {
+ 'key-name': 'unique-key-name',
+ 'key-value': 'parent-name'
+ },
+ {
+ 'key-name': 'unique-key-value',
+ 'key-value': 'vserver'
+ },
+ {
+ 'key-name': 'field-key-name',
+ 'key-value': 'vserver-name'
+ }
+ ],
+ 'vnfc-name-list': [
+ {
+ 'key-name': 'unique-key-name',
+ 'key-value': 'parent-name'
+ },
+ {
+ 'key-name': 'unique-key-value',
+ 'key-value': 'vnfc'
+ },
+ {
+ 'key-name': 'field-key-name',
+ 'key-value': 'vnfc-name'
+ }
+ ],
+ 'vnf-oam-ipv4-address': [
+ {
+ 'key-name': 'unique-key-name',
+ 'key-value': 'parent-name'
+ },
+ {
+ 'key-name': 'unique-key-value',
+ 'key-value': 'vnf'
+ },
+ {
+ 'key-name': 'field-key-name',
+ 'key-value': 'ipv4-oam-ipaddress'
+ }
+ ],
+ 'vnfc-oam-ipv4-address-list': [
+ {
+ 'key-name': 'unique-key-name',
+ 'key-value': 'parent-name'
+ },
+ {
+ 'key-name': 'unique-key-value',
+ 'key-value': 'vnfc'
+ },
+ {
+ 'key-name': 'field-key-name',
+ 'key-value': 'ipaddress-v4-oam-vip'
+ }
+ ]
+ };
+ public requiredValues: boolean[] = [null, true, false];
+ public sourceValues = ['Manual', 'INSTAR', 'A&AI'];
+ public ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list'];
+ public typeValues = [null, 'ipv4-address', 'ipv6-address', 'ipv4-prefix', 'ipv6-prefix'];
+ public responseKeyNameValues = ['', 'unique-key-name', 'unique-key-value', 'field-key-name'];
+ public responseKeyValues = ['(none)', 'addressfqdn', 'ipaddress-v4', 'ipaddress-v6'];
+ public requestKeyNameValues = [''];
+ public requestKeyValues = ['', '(none)'];
+ public myKeyFileName = null;
+ public myPdFileName = null;
+ public disposable: any;
+ public confirmation: boolean;
+ public showConfirmation: boolean;
+ public test: boolean;
+ apiToken = localStorage['apiToken'];
+ userId = localStorage['userId'];
+ public initialData: any;
+ public intialData: any;
+ public initialAction: any;
+ public item: any = {};
+ public subscription: any;
+ public Actions = [
+ { action: 'ConfigBackup', value: 'ConfigBackup' },
+ { action: 'ConfigModify', value: 'ConfigModify' },
+ { action: 'ConfigRestore', value: 'ConfigRestore' },
+ { action: 'Configure', value: 'Configure' },
+ { action: 'GetRunningConfig', value: 'GetRunningConfig' },
+ { action: 'HealthCheck', value: 'HealthCheck' },
+ { action: 'StartApplication', value: 'StartApplication' },
+ { action: 'StopApplication', value: 'StopApplication' }
+ ];
+ public uploadTypes = [{
+ value: 'External Key File',
+ display: 'KeyFile'
+ },
+ {
+ value: 'Pd File',
+ display: 'Pd File'
+ }
+ ];
+
+ options = {
+ timeOut: 1000,
+ showProgressBar: true,
+ pauseOnHover: true,
+ clickToClose: true,
+ maxLength: 200
+ };
+ public vnfcTypeData: string = '';
+ public selectedUploadType: string;
+ @ViewChild(ModalComponent) modalComponent: ModalComponent;
+ public title: string;
+ public parameterDefinitionMap: { [index: string]: string; } = {};
+ public parameterNameValues = {};
+ public displayParamObjects;
+ public modelParamDefinitionObjects;
+ public vnfType: any;
+ vnfcType: any;
+ protocol: any;
+ public refNameObj = {};
+ public action;
+ public artifactName;
+ public appDataObject: any;
+ public downloadDataObject: any;
+ public artifact_fileName;
+ identifier: any;
+ private selectedActionReference: any;
+
+ //this.mappingeditorservice.referenceNameObjects = object;PLEASE USE THIS OBJECT TO GET TEMPALLDATA
+
+ constructor (private httpService: HttpUtilService,
+ private parameterDefinitionService: ParameterDefinitionService,
+ private paramShareService: ParamShareService,
+ private mappingEditorService: MappingEditorService,
+ private httpUtil: HttpUtilService,
+ private utilService: UtilityService,
+ private nService: NotificationsService,
+ private ngProgress: NgProgress) {
+ }
+
+ ngOnInit() {
+ this.selectedActionReference = this.parameterDefinitionService.prepareFileName();
+ if (this.selectedActionReference && this.selectedActionReference != undefined) {
+
+ this.vnfType = this.selectedActionReference.scope['vnf-type'];
+ this.vnfcType = this.selectedActionReference.scope['vnfc-type'];
+ this.protocol = this.selectedActionReference['device-protocol'];
+ this.action = this.selectedActionReference.action;
+
+ for (let i = 0; i < this.selectedActionReference['artifact-list'].length; i++) {
+ let artifactList = this.selectedActionReference['artifact-list'];
+ if (artifactList[i]['artifact-type'] === 'parameter_definitions') {
+ this.artifact_fileName = artifactList[i]['artifact-name'];
+ }
+ }
+ this.parameterDefinitionService.setValues(this.vnfType, this.vnfcType, this.protocol, this.action, this.artifact_fileName);
+ }
+ else {
+ this.selectedActionReference = {
+ 'action': '',
+ 'scope': { 'vnf-type': '', 'vnfc-type': '' },
+ 'vm': [],
+ 'protocol': '',
+ 'download-dg-reference': '',
+ 'user-name': '',
+ 'port-number': '',
+ 'artifact-list': [],
+ 'deviceTemplate': '',
+ 'scopeType': ''
+ };
+ }
+
+ //let path = this.location.path
+ /* this.activeRoutes.url.subscribe(UrlSegment => {
+ this.actionType = UrlSegment[0].path
+ })
+ */
+ this.identifier = this.mappingEditorService.identifier;
+ }
+
+ ngAfterViewInit() {
+ if (this.mappingEditorService.latestAction) {
+ this.displayParamObjects = [];
+ this.modelParamDefinitionObjects = [];
+ if (this.paramShareService.getSessionParamData() != undefined && this.paramShareService.getSessionParamData().length > 0) {
+ this.displayParamObjects = this.paramShareService.getSessionParamData();
+ } else {
+ this.getPD();
+ }
+ } else {
+ this.nService.error('Error', 'Please enter Action and VNF type in Reference Data screen');
+ }
+ return this.displayParamObjects;
+ }
+
+
+ public getPD() {
+ let result: any;
+ let input = {
+ 'input': {
+ 'design-request': {
+ 'request-id': this.apiToken,
+ 'action': 'getArtifact',
+ 'payload': '{"userID": "' + this.userId + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + this.artifact_fileName + '"}'
+ }
+ }
+ };
+ let artifactContent: any;
+ this.ngProgress.start();
+ return this.httpService.post({
+ url: environment.getDesigns,
+ data: input
+ }).subscribe(data => {
+ if (this.utilService.checkResult(data)) {
+ let result: any = JSON.parse(data.output.data.block).artifactInfo[0];
+ var pdObject = YAML.parse(result['artifact-content']);
+ let fileModel = pdObject['vnf-parameter-list'];
+ this.displayParamObjects = this.parameterDefinitionService.populatePD(fileModel);
+ }
+ else {
+
+ }
+ this.ngProgress.done();
+ },
+
+ error => this.nService.error('Error', 'Error in connecting APPC Server'));
+
+ }
+
+ //========================== End of NGInit() Method============================================
+ selectedNavItem(item: any) {
+ this.item = item;
+ }
+
+ //========================== End of selectedNavItem() Method============================================
+ browsePdFile() {
+ $('#inputFile1').trigger('click');
+ }
+
+ //========================== End of browsePdFile() Method============================================
+ browseKeyFile() {
+ $('#inputFile2').trigger('click');
+
+ }
+
+ //========================== End of browseKeyFile() Method============================================
+
+
+ //========================== End of appendSlashes() Method============================================
+
+
+ //========================== End of prepareFileName() Method============================================
+ ngOnDestroy() {
+ this.parameterDefinitionService.destroy(this.displayParamObjects);
+ }
+
+ //========================== End of ngOnDestroy() Method============================================
+
+ //========================== End of createOrUpdateParameterDefinitionData() Method============================================
+ public showUpload() {
+ this.selectedUploadType = this.uploadTypes[0].value;
+ };
+
+ //========================== End of showUpload() Method============================================
+ //This is called when the user selects new files from the upload button
+ public fileChange(input, uploadType) {
+ if (input.files && input.files[0]) {
+ // Create the file reader
+ let reader = new FileReader();
+ this.readFile(input.files[0], reader, (result) => {
+ if ('keyfile' === uploadType) {
+ this.myKeyFileName = input.files[0].name;
+ this.displayParamObjects = this.parameterDefinitionService.processKeyFile(this.myKeyFileName, result);
+ }
+ if ('pdfile' === uploadType) {
+ this.myPdFileName = input.files[0].name;
+ this.displayParamObjects = this.parameterDefinitionService.processPDfile(this.myPdFileName, result);
+ }
+ });
+ } else {
+ //this.notificationService.notifyErrorMessage('Failed to read file!Please try again.');
+ }
+ }
+
+ //========================== End of fileChange() Method============================================
+ public readFile(file, reader, callback) {
+ // Set a callback funtion to fire after the file is fully loaded
+ reader.onload = () => {
+ // callback with the results
+ callback(reader.result);
+ };
+ //this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size);
+ // Read the file
+ reader.readAsText(file, 'UTF-8');
+ }
+
+ //========================== End of readFile() Method============================================
+ fileChangeEvent(fileInput: any) {
+ let obj: any = fileInput.target.files;
+ }
+
+
+ sourceChanged(data, obj) {
+ if (data == 'A&AI') {
+ obj.ruleTypeValues = [null, 'vnf-name', 'vm-name-list', 'vnfc-name-list', 'vnf-oam-ipv4-address', 'vnfc-oam-ipv4-address-list'];
+ for (let x = 0; x < 5; x++) {
+ obj['response-keys'][x]['key-name'] = null;
+ obj['response-keys'][x]['key-value'] = null;
+ }
+ } else if (data == 'Manual') {
+ obj.ruleTypeValues = [null];
+ obj['rule-type'] = null;
+ obj.showFilterFields = false;
+ for (let x = 0; x < 5; x++) {
+ obj['response-keys'][x]['key-name'] = null;
+ obj['response-keys'][x]['key-value'] = null;
+ }
+ }
+ else {
+ obj.ruleTypeValues = [null];
+ }
+ }
+
+ //========================== End of sourceChanged() Method============================================
+ ruleTypeChanged(data, obj) {
+ if (data == null || data == undefined || data == 'null') {
+ obj.showFilterFields = false;
+ obj['rule-type'] = null;
+ for (let x = 0; x < 5; x++) {
+ obj['response-keys'][x]['key-name'] = null;
+ obj['response-keys'][x]['key-value'] = null;
+ }
+ } else {
+ let sourceObject = this.ruleTypeConfiguaration[data];
+ if (data == 'vm-name-list' || data == 'vnfc-name-list' || data == 'vnfc-oam-ipv4-address-list') {
+ this.showFilterFields = false;
+ obj.showFilterFields = true;
+ this.filetrByFieldChanged(obj['response-keys'][3]['key-value'], obj);
+ } else {
+ obj.showFilterFields = false;
+ obj['response-keys'][3]['key-name'] = null;
+ obj['response-keys'][3]['key-value'] = null;
+ obj['response-keys'][4]['key-name'] = null;
+ obj['response-keys'][4]['key-value'] = null;
+ }
+ for (let x = 0; x < sourceObject.length; x++) {
+ obj['response-keys'][x]['key-name'] = sourceObject[x]['key-name'];
+ obj['response-keys'][x]['key-value'] = sourceObject[x]['key-value'];
+ }
+ }
+
+ }
+
+ //========================== End of ruleTypeChanged() Method============================================
+ filetrByFieldChanged(data, obj) {
+ if (data == null || data == undefined || data == 'null') {
+ obj.enableFilterByValue = false;
+ obj['response-keys'][4]['key-value'] = null;
+ } else {
+ obj.enableFilterByValue = true;
+ }
+
+ }
+
+
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css
new file mode 100644
index 0000000..7c075eb
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.css
@@ -0,0 +1,22 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/ \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html
new file mode 100644
index 0000000..6668ed1
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.html
@@ -0,0 +1,24 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+
+<router-outlet></router-outlet> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts
new file mode 100644
index 0000000..2ab9fd8
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.spec.ts
@@ -0,0 +1,49 @@
+/**
+ ============LICENSE_START==========================================
+ ===================================================================
+ Copyright (C) 2018 AT&T 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.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END============================================
+ */
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {ParameterHolderComponent} from './parameter-holder.component';
+
+describe('ParameterHolderComponent', () => {
+ let component: ParameterHolderComponent;
+ let fixture: ComponentFixture<ParameterHolderComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ParameterHolderComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ParameterHolderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts
new file mode 100644
index 0000000..73c9aa1
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/parameter-holder/parameter-holder.component.ts
@@ -0,0 +1,39 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import {Component, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-parameter-holder',
+ templateUrl: './parameter-holder.component.html',
+ styleUrls: ['./parameter-holder.component.css']
+})
+export class ParameterHolderComponent implements OnInit {
+
+ constructor() {
+ }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css
new file mode 100644
index 0000000..9d63aa1
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.css
@@ -0,0 +1,21 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================ */ \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html
new file mode 100644
index 0000000..2dc338f
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.html
@@ -0,0 +1,22 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================ -->
+<router-outlet></router-outlet> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts
new file mode 100644
index 0000000..ffada5d
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.spec.ts
@@ -0,0 +1,48 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================ */
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {ReferenceDataHolderComponent} from './reference-data-holder.component';
+
+describe('ReferenceDataHolderComponent', () => {
+ let component: ReferenceDataHolderComponent;
+ let fixture: ComponentFixture<ReferenceDataHolderComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ReferenceDataHolderComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ReferenceDataHolderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts
new file mode 100644
index 0000000..878b4dd
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-data-holder/reference-data-holder.component.ts
@@ -0,0 +1,37 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================ */
+import {Component, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-reference-data-holder',
+ templateUrl: './reference-data-holder.component.html',
+ styleUrls: ['./reference-data-holder.component.css']
+})
+export class ReferenceDataHolderComponent implements OnInit {
+
+ constructor() {
+ }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css
new file mode 100644
index 0000000..1b4c470
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.css
@@ -0,0 +1,137 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+.form-group {
+ padding: 5px
+}
+
+.panel {
+ margin-top: 20px;
+}
+
+.form-control {
+ width: 100%;
+}
+
+.panel-header {
+ padding: 20px 0px;
+}
+
+.container {
+ border-radius: 0.375rem;
+ transition: all 0.3s ease;
+ padding: 40px;
+}
+
+.container2 {
+ box-shadow: -4px 14px 20px 0px rgba(46, 61, 73, 0.15);
+ border-radius: 0.375rem;
+ transition: all 0.3s ease;
+ padding: 10px;
+ margin-top: 57px;
+}
+
+.error-message {
+ color: red;
+}
+
+.create-wrapper {
+ text-align: left;
+}
+
+.removevnfcClass {
+ text-align: right;
+}
+
+.form-custom-group {
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+.side-by-side {
+ position: relative;
+}
+
+.sidebtn {
+ position: absolute;
+ left: 26.5em;
+ top: 0em;
+}
+
+.clear-control {
+ margin: 40px 20px;
+ display: inherit;
+}
+
+.short-column {
+ width: 100px;
+}
+
+.long-column {
+ width: 200px;
+}
+
+th,
+td {
+ min-width: 150px;
+}
+
+.headlinesInBold {
+ font-weight: bold;
+}
+
+.titleCustom {
+ padding-left: 25px;
+ overflow: visible;
+}
+
+.anchorHover {
+ cursor: pointer;
+}
+
+.custom-btn {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+
+.clear-btn {
+ margin-top: 23px;
+}
+
+.col-md-button {
+ margin: auto;
+ margin-right: 20px;
+ text-align: center;
+ margin-bottom: 15px;
+}
+
+.selectedAction {
+ /* change here */
+ font-weight: bold;
+ color: #1A86E4
+}
+
+.file {
+ visibility: hidden;
+ position: absolute;
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html
new file mode 100644
index 0000000..d38620a
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.html
@@ -0,0 +1,354 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+
+<simple-notifications [options]="options"></simple-notifications>
+<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'"
+ [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress>
+<form class="" novalidate #userForm="ngForm" (ngSubmit)="save(userForm.value,userForm.valid)">
+ <div class="card">
+
+ <div class="card-block" style=" border-top: 5px solid #6ab344; border-top-right-radius: 7px;border-top-left-radius: 7px;">
+ <div class="row" style="padding: 15px 25px">
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Action*</label>
+ <select class="form-control" required id="cmbAction" [(ngModel)]="referenceDataObject.action" (ngModelChange)="updateSessionValues($event,'action');actionChange($event,content,userForm);"
+ #action="ngModel" name="action">
+ <option [value]="actionType"
+ [ngClass]="{'selectedAction':selectedActions.indexOf(actionType)>-1}"
+ [selected]="referenceDataObject.action===actionType"
+ *ngFor="let actionType of actions ">{{actionType}}
+ </option>
+ </select>
+
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>VNF Type* </label>
+ <input type="text" [readonly]="updateParams !='undefined' || vnfParams?.vnfType " class="form-control" id="txtVnfType" required [(ngModel)]="referenceDataObject['scope']['vnf-type']"
+ (ngModelChange)="updateSessionValues($event,'vnfType')" #vnftype="ngModel" name="vnftype">
+ <span class="error-message" [hidden]="vnfParams?.vnfType || vnftype.valid || (vnftype.pristine && !userForm.submitted)">Required Field</span>
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>VNFC Type</label>
+ <input type="text" class="form-control" [disabled]="nonConfigureAction || updateParams !='undefined' || vnfParams?.vnfType" id="txtVnfcType" [(ngModel)]="referenceDataObject.scope['vnfc-type']"
+ (blur)="setVnfcType($event.target.value)" (ngModelChange)="updateSessionValues($event,'vnfcType')" #vnfcType="ngModel" name="vnfcType"
+ disabled="disabled">
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Device Protocol*</label>
+ <select class="form-control" required id="txtDeviceProtocol" [(ngModel)]="referenceDataObject['device-protocol']" #deviceProtocol="ngModel" name="deviceProtocol">
+ <option [value]="device" [selected]="referenceDataObject.deviceProtocol===device"
+ *ngFor="let device of deviceProtocols">{{device}}
+ </option>
+ </select>
+
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12" *ngIf="referenceDataObject['action']== 'ConfigScaleOut'">
+ <label>Template Identifier</label>
+ <select class="form-control" required id="tempIdentifier" (ngModelChange)="dataModified()" [(ngModel)]="templateIdentifier" #deviceProtocol="ngModel" name="templateIdentifier">
+ <option [value]="val" *ngFor="let val of referenceDataObject['template-id-list']">{{val}}
+ </option>
+ </select>
+ <span class="error-message" [hidden]="deviceProtocol.valid || (deviceProtocol.pristine && !userForm.submitted)">Required Field</span>
+ </div>
+
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12" *ngIf="referenceDataObject['action']== 'ConfigScaleOut'" style="margin-top: 30px">
+ <span *ngIf="referenceDataObject.action === 'ConfigScaleOut'"> <a style=" color: blue;"
+ href="javascript:void(0)"
+ (click)="showIdentifier()">Assign New Template Identifier</a></span>
+
+ </div>
+ </div>
+ <div class="col-12" *ngIf="!(referenceDataObject.action === 'OpenStack Actions')">
+ <div class="input-group">
+ <input id="inputFile" class="file" #myInput type='file' (change)="fileChange($event)">
+ <input [(ngModel)]="fileName" type="text" class="input-lg" disabled placeholder="Upload Reference File from PC" name="browse" style="width:80%">
+ <button (click)="browseOption($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg" type="button">Upload Reference File
+ </button>
+ </div>
+ </div>
+ <div class="col-12" *ngIf="referenceDataObject.action === 'OpenStack Actions'">
+ <div class="input-group">
+ <input id="excelInputFile" #myInput1 class="file" type="file" (change)="upload($event)">
+ <input [(ngModel)]="uploadFileName" type="text" class="input-lg" disabled placeholder="Upload VM Capabilities File" name="uploadFileName" style="width:80%">
+ <button (click)="excelBrowseOption($event)" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg"
+ type="button">Upload VM Capabilities File
+ </button>
+ </div>
+ </div>
+ </div>
+ <div class="card-block" style="padding: 10px">
+ <div>
+ <div class="create-wrapper" style="padding: 0px 25px">
+ <div class="row" style="margin-bottom: 30px">
+ <div class=" col-6">
+
+ </div>
+ <div class="text-right col-6">
+ <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="submit">Download All To PC
+ </button>&emsp;&emsp;
+ <button id="saveToAppc" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="button" (click)="saveToAppc(userForm.valid, userForm)">Save All to APPC
+ </button>&emsp;&emsp;
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-12">
+ <div class="row" *ngIf="!(referenceDataObject.action === 'OpenStack Actions')">
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label>Template</label>
+ <select class="form-control" id="txtDeviceProtocol" [(ngModel)]="referenceDataObject['template']" #template="ngModel" name="template">
+ <option [value]="template" *ngFor="let template of deviceTemplates">
+ {{template}}
+ </option>
+ </select>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label>User Name</label>
+ <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['user-name']" name="loginUserName">
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label>Port Number</label>
+ <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['port-number']" name="portNumber">
+ </div>
+ <div *ngIf="actionHealthCheck && referenceDataObject['device-protocol'] =='REST' " class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Context Url</label>
+ <input type="text" class="form-control" id="txtIpaddress" [(ngModel)]="referenceDataObject['context-url']" name="portNumber">
+ </div>
+ </div>
+ <div class="card-block" *ngIf="(referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined)"
+ style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;">
+ <div class="col-12">
+ <h5 style="margin-top: 0.5rem;font-family: Roboto"> VNFC Information
+ <span class="pull-right">
+ <i (click)="isCollapsedContent = !isCollapsedContent"
+ [ngClass]="{'fa-minus-circle':isCollapsedContent,'fa-plus-circle':!isCollapsedContent}"
+ class="fa" aria-hidden="true"></i>
+ </span>
+ </h5>
+ </div>
+ </div>
+ <div class="row" *ngIf="(( referenceDataObject.action =='ConfigScaleOut' ||referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined ) && isCollapsedContent) ">
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">VNFC Type*</label>
+ <input type="text" class="form-control" id="txtVnfcTypeInColl" [(ngModel)]="Sample['vnfc-type']" #vnfcType="ngModel" name="samplevnfcType">
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px">VNFC Function Code*</label>
+ <input type="text" class="form-control" id="txtVnfcFunctionCode" [(ngModel)]="Sample['vnfc-function-code']" #vnfcFunctionCode="ngModel" name="samplevnfcFunctionCode">
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">IPAddress V4 OAM VIP</label>
+ <select class="form-control" id="cmbIpAddedBoo" [(ngModel)]="Sample['ipaddress-v4-oam-vip']" name="sampleIpaddress">
+ <option [value]="hasIp" *ngFor="let hasIp of ipAddressBoolean">{{hasIp}}
+ </option>
+ </select>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">Group Notation Type</label>
+ <select class="form-control" id="cmbGroupType" [(ngModel)]="Sample['group-notation-type']" name="sampleGroupNotation">
+ <option [value]="type" *ngFor="let type of groupAnotationType">{{type}}</option>
+ </select>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">Group Notation Value</label>
+ <input type="text" class="form-control" id="txtGroupValue" [(ngModel)]="Sample['group-notation-value']" name="sampleGroupValue">
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent clear-btn" (click)="clearVnfcData()">Clear VNFC Info
+ </button>
+ </div>
+ </div>
+ <hr>
+ <div *ngIf="(referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' )" class="row">
+ <div class="col-lg-2 col-md-2 hdden-sm-down">
+ <label style="margin-top: 17px;" class="headlinesInBold"> Number Of VM(s): </label>
+ </div>
+ <div class="col-lg-5 col-md-5 col-sm-6 col-xs-6">
+ <div class="form-group">
+ <input type="text" placeholder="Number of VM(s)" class="form-control" id="txtVmnumber22" [(ngModel)]="refernceScopeObj.from" (ngModelChange)="numberValidation($event)"
+ name="txtNumber23">
+ </div>
+ </div>
+ <div class="col-lg-5 col-md-5 col-sm-6 col-xs-6 text-right">
+ <div class="form-group">
+ <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" type="button" [disabled]="!refernceScopeObj.from || !numberOfVmTest"
+ (click)="addVms()">Add VM Information
+ </button>
+ </div>
+ </div>
+ </div>
+ <div *ngIf="referenceDataObject.vm?.length>0">
+ <div class="row" *ngFor="let noOfvm of referenceDataObject.vm | vmFiltering:referenceDataObject?.action:templateIdentifier; let j=index">
+ <div *ngIf="((referenceDataObject.action =='ConfigScaleOut' || referenceDataObject.action =='Configure'|| referenceDataObject.action =='' || referenceDataObject.action ==undefined ))"
+ class="col-12">
+ <div class="row" *ngFor="let item of noOfvm.vnfc; let i=index">
+ <div class="col-md-12" *ngIf="i==0">
+ <h5 class="headlinesInBold">VM Number: {{j+1}}</h5>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">VNFC Instance No.</label>
+ <input type="text" class="form-control" id="txtVmnumber" disabled='true' [(ngModel)]="item['vnfc-instance']" name="vmNumber{{j}}">
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">VNFC Type*</label>
+ <input type="text" class="form-control" id="txtVnfcTypeInColl" required [(ngModel)]="item['vnfc-type']" #vnfcType="ngModel" name="vnfcType{{j}}">
+ <span class="error-message" [hidden]="vnfcType.valid || (vnfcType.pristine && !userForm.submitted)">Required Field</span>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">VNFC Function Code*</label>
+ <input type="text" class="form-control" id="txtVnfcFunctionCode" required [(ngModel)]="item['vnfc-function-code']" #vnfcFunctionCode="ngModel" name="vnfcFunctionCode{{j}}">
+ <span class="error-message" [hidden]="vnfcFunctionCode.valid || (vnfcFunctionCode.pristine && !userForm.submitted)">Required Field</span>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">IPAddress V4 OAM VIP</label>
+ <select class="form-control" id="cmbIpAddress" [(ngModel)]="item['ipaddress-v4-oam-vip']" name="ipaddress{{j}}">
+ <option [value]="hasIP" [selected]="item.ipAddressBoolean===hasIP"
+ *ngFor="let hasIP of ipAddressBoolean">{{hasIP}}
+ </option>
+ </select>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">Group Notation Type</label>
+ <select class="form-control" id="cmbGroupType" [(ngModel)]="item['group-notation-type']" name="selectedGroupType{{j}}">
+ <option [value]="type" [selected]="item.groupNotationType===type"
+ *ngFor="let type of groupAnotationType">{{type}}
+ </option>
+ </select>
+ </div>
+ <div class="col-lg-2 col-sm-6 col-md-2 col-xs-12">
+ <label style="font-size:12px;">Group Notation Value</label>
+ <input type="text" class="form-control" id="txtGroupValue" [(ngModel)]="item['group-notation-value']" name="selectedGroupValue{{j}}">
+ </div>
+ <div class="col-lg-12 col-sm-12 col-md-12 col-xs-12">
+ <div class="removevnfcClass" *ngIf="refernceScopeObj.sourceType !='vnfcType'">
+ <a role="button" style="color: white" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="removeFeature(j,i)">Remove Vm</a>
+ </div>
+ <div>
+ <a *ngIf="(referenceDataObject.vm[j].vnfc.length-1) == i " [hidden]="true" role="button" (click)="addVnfcData(j)">Add VNFC
+ Information</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row" *ngIf="(referenceDataObject.action === 'OpenStack Actions')">
+ <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+ <div class="table-responsive" style="height:auto; overflow: auto;">
+ <table>
+ <thead>
+ <tr>
+ <td *ngFor="let item of firstArrayElement">
+ <div>
+ <h1 style="font-size: 110%"> {{item}} </h1>
+ </div>
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let item of remUploadedDataArray; let i=index">
+ <td *ngFor="let subItem of item; let j=index">
+ {{subItem}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+<!-- Modal -->
+<div id="messageModal" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" data-dismiss="modal">&times;
+ </button>
+ <h4 class="modal-title">Warning</h4>
+ </div>
+ <div class="modal-body">
+ <div *ngIf="allowAction==false" class="alert alert-danger">
+ <b> Configure </b> action not yet saved
+ </div>
+ <div *ngIf="actionExist" class="alert alert-danger">
+ <b> {{referenceDataObject.action}}</b> already exists. Please continue...
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="close" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" data-dismiss="modal">Close
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
+<div id="identifierModal" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="android-more-button mdl-button mdl-js-button mdl-button--accent" data-dismiss="modal">&times;
+ </button>
+ <h4 class="modal-title">Enter New Template Identifier</h4>
+ </div>
+ <div class="modal-body">
+ <div>
+ <div>
+ <input name="test" type="text" class="" [(ngModel)]="templateId" placeholder="identifier">
+ </div>
+ <div>
+ <button style="padding: 10px" class="btn btn-primary" data-dismiss="modal" (click)="addToIdentDrp()">submit
+ </button>
+ <button style="padding: 10px" class="btn btn-primary" (click)="templateId=''" data-dismiss="modal">cancel
+ </button>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+
+ </div>
+ </div>
+ </div>
+</div>
+<ng-template #content let-c="close" let-d="dismiss">
+ <div class="modal-header">
+ <h6 class="modal-title">Save all changes for current action to APPC database.</h6>
+ <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <p>Do you want to save the changes?</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="c('no')">No
+ </button>
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="c('yes')">Yes
+ </button>
+ </div>
+</ng-template> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts
new file mode 100644
index 0000000..67ba8f5
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.spec.ts
@@ -0,0 +1,67 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {NO_ERRORS_SCHEMA} from '@angular/core';
+import {ReferenceDataformComponent} from './reference-dataform.component';
+import {FormsModule} from '@angular/forms';
+import { NotificationService } from '../../../shared/services/notification.service';
+import { ParamShareService } from '../../..//shared/services/paramShare.service';
+import { MappingEditorService } from '../../..//shared/services/mapping-editor.service';
+import {DialogService} from 'ng2-bootstrap-modal';
+import {RouterTestingModule} from '@angular/router/testing';
+import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service';
+import { NgModule } from '@angular/core';
+import { NgProgress } from 'ngx-progressbar';
+import { HttpModule } from '@angular/http';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { SharedModule } from '../../../shared/shared.module';
+
+
+describe('ReferenceDataformComponent', () => {
+ let component: ReferenceDataformComponent;
+ let fixture: ComponentFixture<ReferenceDataformComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ReferenceDataformComponent],
+ schemas: [NO_ERRORS_SCHEMA],
+ imports: [FormsModule, RouterTestingModule,HttpModule,NgbModule.forRoot()],
+ providers: [NgProgress, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService]
+
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+
+ fixture = TestBed.createComponent(ReferenceDataformComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create reference component', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts
new file mode 100644
index 0000000..c66a003
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/reference-dataform/reference-dataform.component.ts
@@ -0,0 +1,1242 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+import * as XLSX from 'xlsx';
+import * as _ from 'underscore';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { BuildDesignComponent } from '../build-artifacts.component';
+import { HttpUtilService } from '../../../shared/services/httpUtil/http-util.service';
+import { Location } from '@angular/common';
+import { MappingEditorService } from '../../..//shared/services/mapping-editor.service';
+import { ModalComponent } from '../../../shared/modal/modal.component';
+import { NotificationService } from '../../../shared/services/notification.service';
+import { NotificationsService } from 'angular2-notifications';
+import { ParamShareService } from '../../..//shared/services/paramShare.service';
+import { environment } from '../../../../environments/environment';
+import { saveAs } from 'file-saver';
+import { NgProgress } from 'ngx-progressbar';
+
+
+declare var $: any;
+type AOA = Array<Array<any>>;
+
+@Component({
+ selector: 'reference-dataform',
+ templateUrl: './reference-dataform.component.html',
+ styleUrls: ['./reference-dataform.component.css']
+})
+export class ReferenceDataformComponent implements OnInit {
+ @ViewChild(ModalComponent) modalComponent: ModalComponent;
+ public showUploadStatus: boolean = false;
+ public fileUploaded: boolean = false;
+ public uploadedData: any;
+ public statusMsg: string;
+ public uploadStatus: boolean = false;
+ public isCollapsedContent: boolean = true;
+ public vnfcCollLength: number = 0;
+ public vfncCollection = [];
+ public userForm: any;
+ public actionType: any;
+ numberTest: RegExp = /^[^.a-z]+$/;
+ public numberOfVmTest: boolean = true;
+ public tempAllData = [];
+ public noRefData = false;
+ public disableRetrieve = false;
+ public getRefStatus = false;
+ public uploadStatusError: boolean;
+ public showUploadErrorStatus: boolean;
+ public noData: string;
+ selectedActions = [];
+ public appData = { reference: {}, template: { templateData: {}, nameValueData: {} }, pd: {} };
+ public downloadData = {
+ reference: {},
+ template: { templateData: {}, nameValueData: {}, templateFileName: '', nameValueFileName: '' },
+ pd: { pdData: '', pdFileName: '' }
+ };
+ fileName: any;
+ public uploadFileName: any;
+ public addVmClickedFlag: boolean = false;
+ public getExcelUploadStatus: boolean = false;
+ public uploadedDataArray: any;
+ public actionFlag = false;
+ currentAction: any;
+ oldAction: any;
+ nonConfigureAction: any;
+ templateId;
+ templateIdentifier;
+ public actionLevels = [
+ 'vnfc', 'vnf'
+ ];
+
+ identifierDrp: any;
+ identifierDrpValues: any = [];
+ //settings for the notifications.
+ options = {
+ timeOut: 1000,
+ showProgressBar: true,
+ pauseOnHover: true,
+ clickToClose: true,
+ maxLength: 200
+ };
+ //initializing this object to contain all the parameters to be captured
+ public referenceDataObject = {
+ action: '',
+ 'action-level': 'vnf',
+ scope: { 'vnf-type': '', 'vnfc-type': '' },
+ 'template': 'Y',
+ vm: [],
+ 'device-protocol': '',
+ 'user-name': '',
+ 'port-number': '',
+ 'artifact-list': []
+ };
+ public refernceScopeObj = { sourceType: '', from: '', to: '' };
+ public actions = ['', 'Configure', 'ConfigModify', 'ConfigBackup', 'ConfigRestore', 'GetRunningConfig', 'HealthCheck', 'StartApplication', 'StopApplication', 'QuiesceTraffic', 'ResumeTraffic', 'UpgradeBackout', 'UpgradeBackup', 'UpgradePostCheck', 'UpgradePreCheck', 'UpgradeSoftware', 'OpenStack Actions', 'ConfigScaleOut'];
+ public groupAnotationValue = ['', 'Pair'];
+ public groupAnotationType = ['', 'first-vnfc-name', 'fixed-value', 'relative-value'];
+ public deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'NETCONF-XML', 'REST', 'CLI', 'RESTCONF'];
+ public deviceTemplates = ['', 'Y', 'N'];
+ public sourceTypeColl = ['', 'vnfType', 'vnfcType'];
+ public ipAddressBoolean = ['', 'Y', 'N'];
+ public Sample: any = {
+ 'vnfc-instance': '1',
+ 'vnfc-function-code': '',
+ 'ipaddress-v4-oam-vip': '',
+ 'group-notation-type': '',
+ 'group-notation-value': ''
+ };
+ hideModal: boolean = false;
+ public self: any;
+ public uploadTypes = [{
+ value: 'Reference Data',
+ display: 'Sample Json Param File'
+ },
+ {
+ value: 'Mapping Data',
+ display: 'Sample Json Param File'
+ }
+ ];
+ public selectedUploadType: string = this.uploadTypes[0].value;
+ public vnfcTypeData: string = '';
+ public title: string;
+ public allowAction: boolean = true;
+ public actionExist: boolean = false;
+ public disableVnftype: boolean = false;
+ public otherActions: boolean = false;
+ public actionHealthCheck: boolean = false;
+ public actionChanged: boolean = false;
+ public initialAction: string = '';
+ public noCacheData: boolean;
+ public updateParams: any;
+ public vnfParams: any;
+ public firstArrayElement = [];
+ public remUploadedDataArray = [];
+
+ constructor (private buildDesignComponent: BuildDesignComponent, private httpUtils: HttpUtilService, private route: Router, private location: Location, private activeRoutes: ActivatedRoute, private notificationService: NotificationService,
+ private paramShareService: ParamShareService, private mappingEditorService: MappingEditorService, private modalService: NgbModal, private nService: NotificationsService, private ngProgress: NgProgress) {
+ }
+
+ ngOnInit() {
+ this.self = this;
+ let path = this.location.path;
+ this.title = 'Reference Data';
+ this.referenceDataObject = {
+ action: '',
+ 'action-level': 'vnf',
+ scope: { 'vnf-type': '', 'vnfc-type': '' },
+ 'template': 'Y',
+ vm: [],
+ 'device-protocol': '',
+ 'user-name': '',
+ 'port-number': '',
+ 'artifact-list': []
+ };
+ this.updateParams = sessionStorage.getItem('updateParams');
+ let cacheData = this.mappingEditorService.referenceNameObjects;
+ if (cacheData != undefined && cacheData != null && cacheData.length > 0) {
+ this.tempAllData = cacheData;
+ if (this.mappingEditorService.latestAction != undefined) {
+ this.referenceDataObject = this.mappingEditorService.latestAction;
+ //this.referenceDataObject['template-id-list'] = this.mappingEditorService.identifier
+ //use these commented objects to be used in template and pd pages
+ //this.templateIdentifier = this.mappingEditorService.identifier
+ this.refernceScopeObj.sourceType = this.referenceDataObject['scopeType'];
+ this.oldAction = this.referenceDataObject.action;
+ this.populateExistinAction(this.referenceDataObject.action);
+ }
+ } else if (this.updateParams != 'undefined') {
+ this.getArtifact();
+ }
+ var appData = this.mappingEditorService.appDataObject;
+ if (appData != null || appData != undefined) this.appData = appData;
+ var downloadData = this.mappingEditorService.downloadDataObject;
+ if (downloadData != null || downloadData != undefined) this.downloadData = downloadData;
+ this.vnfParams = JSON.parse(sessionStorage.getItem('vnfParams'));
+ if (this.vnfParams && this.vnfParams.vnfType) {
+ this.referenceDataObject['scope']['vnf-type'] = this.vnfParams.vnfType;
+ }
+ if (this.vnfParams && this.vnfParams.vnfcType) {
+ this.referenceDataObject['scope']['vnfc-type'] = this.vnfParams.vnfcType;
+ }
+ this.uploadedDataArray = [];
+ this.remUploadedDataArray = [];
+ this.firstArrayElement = [];
+ this.uploadFileName = '';
+ this.templateIdentifier = this.mappingEditorService.identifier
+ //this.tempAllData = [];
+ }
+
+ //to retrive the data from appc and assign it to the vaiables, if no data display the message reterived from the API
+ getArtifact() {
+ try {
+ let payload = JSON.parse(sessionStorage.getItem('updateParams'));
+ payload['userID'] = localStorage['userId'];
+ payload = JSON.stringify(payload);
+ let data = {
+ 'input': {
+ 'design-request': {
+ 'request-id': localStorage['apiToken'],
+ 'action': 'getArtifact',
+ 'payload': payload
+ }
+ }
+ };
+ this.ngProgress.start();
+ this.httpUtils.post({
+ url: environment.getDesigns,
+ data: data
+ }).subscribe(resp => {
+ if (resp.output.data.block != undefined) {
+ this.nService.success('Status', 'data fetched ');
+ let artifactInfo = JSON.parse(resp.output.data.block).artifactInfo[0];
+ let reference_data = JSON.parse(artifactInfo['artifact-content'])['reference_data'][0];
+ this.referenceDataObject = reference_data;
+ console.log('reference data obj==' + JSON.stringify(this.referenceDataObject));
+ this.refernceScopeObj.sourceType = this.referenceDataObject['scopeType'];
+ this.mappingEditorService.getReferenceList().push(JSON.parse(artifactInfo['artifact-content']));
+ this.tempAllData = JSON.parse(artifactInfo['artifact-content'])['reference_data'];
+ this.oldAction = this.referenceDataObject.action;
+ if (this.referenceDataObject.action === 'OpenStack Actions') {
+ this.deviceProtocols = ['', 'OpenStack'];
+ this.buildDesignComponent.tabs = [
+ {
+
+ name: 'Reference Data',
+ url: 'references',
+ }];
+ }
+ else {
+ this.buildDesignComponent.tabs = [
+ {
+ name: 'Reference Data',
+ url: 'references',
+ }, {
+ name: 'Template',
+ url: 'templates/myTemplates',
+ }, {
+ name: 'Parameter Definition',
+ url: 'parameterDefinitions/create'
+ }/*, {
+ name: "Test",
+ url: 'test',
+ }*/
+ ];
+ }
+ console.log('tempalldata===' + JSON.stringify(this.tempAllData));
+ } else {
+ this.nService.success('Status', 'Sorry !!! I dont have any artifact Named : ' + (JSON.parse(payload))['artifact-name']);
+ }
+ this.ngProgress.done();
+ });
+ }
+ catch (e) {
+ this.nService.warn('status', 'error while reteriving artifact');
+ }
+ setTimeout(() => {
+ this.ngProgress.done();
+ }, 3500);
+ }
+
+ //reinitializing the required values
+ ngOnDestroy() {
+ let referenceObject = this.prepareReferenceObject();
+ this.mappingEditorService.changeNavAppData(this.appData);
+ this.mappingEditorService.changeNavDownloadData(this.downloadData);
+ this.uploadedDataArray = [];
+ this.remUploadedDataArray = [];
+ this.firstArrayElement = [];
+ this.uploadFileName = '';
+ // this.tempAllData = [];
+ console.log('temp all data===' + JSON.stringify(this.tempAllData));
+ }
+
+ numberValidation(event: any) {
+ // console.log(this.numberTest.test(event));
+ if (this.numberTest.test(event) && event != 0) {
+ this.numberOfVmTest = true;
+ }
+ else {
+ this.numberOfVmTest = false;
+ }
+ }
+
+ updateSessionValues(event: any, type: string) {
+ if (type === 'action') {
+ sessionStorage.setItem('action', event);
+ }
+ if (type === 'vnfType') {
+ sessionStorage.setItem('vnfType', event);
+ }
+ }
+
+ checkConfigure(data) {
+ if (data == null) {
+ return;
+ }
+ if (this.fileUploaded && this.actionType == 'update') {
+ let refObject = this.uploadedData.find(obj => {
+ return obj.action == data;
+ });
+ this.referenceDataObject = JSON.parse(JSON.stringify(refObject));
+ if (data == 'HealthCheck') {
+ //show additional fileds user name port number and others
+ this.actionHealthCheck = true;
+ } else {
+ this.actionHealthCheck = false;
+ if (data == 'StartApplication' || data == 'StopApplication') {
+ this.disableVnftype = true;
+ } else {
+
+ this.otherActions = true;
+ }
+ }
+ return;
+ }
+ this.buildDesignComponent.updateAccessUpdatePages(data, this.mappingEditorService.getReferenceList());
+ let configureObject = _.find(this.tempAllData, function (obj) {
+ return obj['action'] == 'Configure';
+ });
+ if (data != 'Configure') {
+ if (!configureObject) {
+ this.allowAction = false;
+ $('#messageModal').modal();
+ } else {
+ this.allowAction = true;
+ }
+ if (this.referenceDataObject.action == 'Configure') {
+ this.allowAction = true;
+ }
+ }
+ //dont allow any action second time
+ let y = _.find(this.tempAllData, function (obj) {
+ return obj['action'] == data;
+ });
+ if (y) {
+ this.actionExist = true;
+ $('#messageModal').modal();
+ } else {
+ this.actionExist = false;
+ }
+ //populate configure values for other actions
+ if (data != 'Configure' && configureObject != undefined) {
+ if (data == 'HealthCheck') {
+ //show additional fileds user name port number and others
+ this.actionHealthCheck = true;
+ } else {
+ this.actionHealthCheck = false;
+ if (data == 'StartApplication' || data == 'StopApplication') {
+ this.disableVnftype = true;
+ } else {
+ this.otherActions = true;
+ }
+ }
+ this.referenceDataObject.scope['vnf-type'] = configureObject['scope']['vnf-type'];
+ this.referenceDataObject.scope['vnfc-type'] = configureObject['scope']['vnfc-type'];
+ this.referenceDataObject['device-protocol'] = configureObject['device-protocol'];
+ this.refernceScopeObj['sourceType'] = configureObject['scopeType'];
+ } else {
+ this.actionHealthCheck = false;
+ this.otherActions = false;
+ this.disableVnftype = false;
+ }
+ //set default values for further actions
+ }
+
+ addVnfcData(vmNumber: number) {
+ var newObj = {
+ 'vnfc-instance': this.referenceDataObject.vm[vmNumber].vnfc.length + 1,
+ 'vnfc-type': this.vnfcTypeData,
+ 'vnfc-function-code': '',
+ 'ipaddress-v4-oam-vip': '',
+ 'group-notation-type': '',
+ 'group-notation-value': ''
+ };
+ this.referenceDataObject.vm[vmNumber].vnfc.push(newObj);
+ }
+
+ //to remove the VM's created by the user
+ removeFeature(vmNumber: any, index: any) {
+ this.referenceDataObject.vm.splice(vmNumber, 1);
+ }
+
+ //add new VM's to the configure
+ addVms() {
+ let arr = [];
+ var vnfcObj = JSON.parse(JSON.stringify(this.Sample));
+ let mberOFVm = Number(this.refernceScopeObj.from);
+ let arrlength = this.referenceDataObject.vm.length;
+ mberOFVm = arrlength + mberOFVm;
+ for (var i = (arrlength); i < mberOFVm; i++) {
+ if (this.referenceDataObject.action == 'ConfigScaleOut') {
+ arr.push({ 'template-id': this.templateIdentifier, 'vm-instance': (i + 1), vnfc: [Object.assign({}, this.Sample)] });
+ } else {
+ arr.push({ 'vm-instance': (i + 1), vnfc: [Object.assign({}, this.Sample)] });
+ }
+
+ }
+ //this.referenceDataObject.vm.splice(arrlength, 0, ...arr);
+ this.referenceDataObject.vm = this.referenceDataObject.vm.concat(arr); //splice(arrlength, 0, ...arr);
+ }
+
+ //Reference object to create reference data
+ prepareReferenceObject() {
+ // console.log("this temp all data before=="+ JSON.stringify(this.tempAllData))
+
+ this.referenceDataObject['artifact-list'] = [];
+ let scopeName = '';
+ //if only vnf is there
+ if (this.referenceDataObject.scope['vnfc-type'] == '' || this.referenceDataObject.scope['vnfc-type'] == null || this.referenceDataObject.scope['vnfc-type'] == 'null') {
+ scopeName = this.referenceDataObject.scope['vnf-type'];
+ this.referenceDataObject.scope['vnfc-type'] = '';
+ this.referenceDataObject['action-level'] = 'vnf';
+ this.referenceDataObject['scopeType'] = 'vnf-type';
+ }
+ //if VNFC is entered set action level & Scope type to VNFC for configure and configure modify, and default the values to vnf and vnf type for all other actions
+ else {
+ scopeName = this.referenceDataObject.scope['vnfc-type'];
+ if (this.referenceDataObject.action == 'Configure' || this.referenceDataObject.action == 'ConfigModify') {
+ this.referenceDataObject['action-level'] = 'vnfc';
+ this.referenceDataObject['scopeType'] = 'vnfc-type';
+ } else {
+ this.referenceDataObject['action-level'] = 'vnf';
+ this.referenceDataObject['scopeType'] = 'vnf-type';
+ }
+ }
+ //replacing / with _ and removing spaces in the scopeName
+ if (scopeName) {
+ scopeName = scopeName.replace(/ /g, '').replace(new RegExp('/', 'g'), '_').replace(/ /g, '');
+ }
+ //marking the extension based on the device-protocol selected by the user
+ let extension = 'json';
+ if (this.referenceDataObject['device-protocol'] == 'ANSIBLE' || this.referenceDataObject['device-protocol'] == 'CHEF' || this.referenceDataObject['device-protocol'] == 'CLI') {
+ extension = 'json';
+ } else if (this.referenceDataObject['device-protocol'] == 'NETCONF-XML' || this.referenceDataObject['device-protocol'] == 'REST') {
+ extension = 'xml';
+ }
+ //preparing the artifact list array file names along with extension
+ let config_template_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.' + extension;
+ let pd_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.yaml';
+ let reference_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V.json';
+
+ let configTemplate = {
+ 'artifact-name': 'template_' + config_template_fileName,
+ 'artifact-type': 'config_template'
+ };
+
+ let pdTemplate = {
+ 'artifact-name': 'pd_' + pd_fileName,
+ 'artifact-type': 'parameter_definitions'
+ };
+ if (this.referenceDataObject.action != 'ConfigScaleOut') {
+
+ this.referenceDataObject['artifact-list'].push(configTemplate,
+ pdTemplate
+ );
+
+ } else {
+ let identifiers = this.referenceDataObject['template-id-list'];
+ if (identifiers) {
+
+
+ for (var x = 0; x < identifiers.length; x++) {
+ pd_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V_' + identifiers[x] + '.yaml';
+ config_template_fileName = this.referenceDataObject.action + '_' + scopeName + '_' + '0.0.1V_' + identifiers[x] + '.' + extension;
+
+ configTemplate = {
+ 'artifact-name': 'template_' + config_template_fileName,
+ 'artifact-type': 'config_template'
+ };
+ pdTemplate = {
+ 'artifact-name': 'pd_' + pd_fileName,
+ 'artifact-type': 'parameter_definitions'
+ };
+ this.referenceDataObject['artifact-list'].push(configTemplate,
+ pdTemplate
+ );
+ }
+ }
+
+ }
+
+ if (this.referenceDataObject.scope['vnfc-type'] === '') {
+ this.referenceDataObject.scope['vnfc-type'] = '';
+ }
+ if (this.referenceDataObject.action === 'OpenStack Actions') {
+ this.referenceDataObject['template'] = 'N';
+ this.referenceDataObject['artifact-list'] = [];
+ }
+ let newObj = $.extend(true, {}, this.referenceDataObject);
+ let action = this.referenceDataObject.action;
+ let configureObject = (newObj.action == 'Configure');
+ let ConfigScaleOut = (newObj.action == 'ConfigScaleOut');
+ //delete VM's if selected action is configure.
+ if (!ConfigScaleOut && !configureObject && this.tempAllData.length != 0) {
+ // delete newObj.vm
+ newObj.vm = [];
+ //this.tempAllData.push(newObj);
+ } else {
+ if (ConfigScaleOut) {
+
+
+ // //add template identifier
+ // for(let x=0;x<newObj.vm.length;x++){
+ // let vmObj= newObj.vm[x]
+ // vmObj['template-id'] = this.templateIdentifier
+ // }
+ } else {
+ delete newObj['template-id-list'];
+ }
+ }
+ //remove artifact list if template is N
+ if (this.referenceDataObject.template == 'N') {
+ }
+ let actionObjIndex = this.tempAllData.findIndex(obj => {
+ return obj['action'] == action;
+ });
+ if (newObj.action != 'HealthCheck') {
+ delete newObj['context-url'];
+ }
+ if (actionObjIndex > -1) {
+ this.tempAllData[actionObjIndex] = newObj;
+ this.mappingEditorService.saveLatestAction(this.tempAllData[actionObjIndex]);
+ this.mappingEditorService.saveLatestIdentifier(this.templateIdentifier);
+ } else {
+ if (newObj.action != '') {
+ this.tempAllData.push(newObj);
+ this.mappingEditorService.saveLatestAction(newObj);
+ this.mappingEditorService.saveLatestIdentifier(this.templateIdentifier);
+ }
+ }
+ //Creating all action block to allow mulitple actions at once
+ let allAction = {
+ action: 'AllAction',
+ 'action-level': 'vnf',
+ scope: newObj.scope,
+ 'artifact-list': [{
+ 'artifact-name': 'reference_AllAction' + '_' + scopeName + '_' + '0.0.1V.json',
+ 'artifact-type': 'reference_template'
+ }]
+ };
+ let allActionIndex = this.tempAllData.findIndex(obj => {
+ return obj['action'] == 'AllAction';
+ });
+ if (allActionIndex > -1) {
+ this.tempAllData[allActionIndex] = allAction;
+ } else {
+ this.tempAllData.push(allAction);
+ }
+ console.log('This uploaded array===' + JSON.stringify(this.uploadedDataArray));
+ if (this.uploadedDataArray && this.uploadedDataArray != undefined && this.uploadedDataArray.length != 0) {
+ /*for (var i = 0; i < this.uploadedDataArray.length; i++) {
+ var actionData = this.uploadedDataArray[i][0];
+ // console.log("Action data=="+ actionData);
+ for (var j = 0; j < this.tempAllData.length; j++) {
+ //console.log("Actions from temp all data=="+ this.tempAllData[j].action)
+ //console.log("Matched=="+ (actionData === this.tempAllData[j].action))
+ if (actionData === this.tempAllData[j].action) {
+ this.tempAllData.splice(j,1);
+
+ }
+ }
+ }*/
+ if (this.tempAllData && this.tempAllData != undefined) {
+ for (var i = 0; i < this.tempAllData.length; i++) {
+ // alert(this.checkIfelementExistsInArray(this.tempAllData[i].action,this.actions))
+ var result = false;
+
+ if (this.tempAllData[i].action === 'AllAction') {
+ result = true;
+ }
+ else {
+ result = this.checkIfelementExistsInArray(this.tempAllData[i].action, this.actions);
+ }
+ if (!result) {
+ console.log('Removing VM action==' + this.tempAllData[i].action);
+ this.tempAllData.splice(i, 1);
+ i = i - 1;
+ }
+
+ }
+ }
+ this.addVmCapabilitiesData();
+ }
+ // console.log("this temp all data after=="+ JSON.stringify(this.tempAllData))
+ //console.log("temp all data from save to appc=="+JSON.stringify(this.tempAllData))
+ this.mappingEditorService.getReferenceList().push(JSON.parse(JSON.stringify(this.referenceDataObject)));
+ this.buildDesignComponent.updateAccessUpdatePages(this.referenceDataObject.action, this.mappingEditorService.getReferenceList());
+ this.mappingEditorService.changeNav(this.tempAllData);
+ return { totlaRefDtaa: this.tempAllData, scopeName: scopeName };
+ }
+
+ public checkIfelementExistsInArray(element, array) {
+ //console.log("Element==" + element)
+ var result: boolean = false;
+
+ array.forEach(function (item) {
+ // console.log("Item==" + item)
+ if (element === item) {
+ console.log('Element==' + element + 'Item==' + item);
+ result = true;
+ }
+ }
+ );
+ return result;
+ }
+
+ upload(evt: any) {
+ /* console.log("This uploaded array==" + JSON.stringify(this.uploadedDataArray))
+ // console.log("This template data before==" + JSON.stringify(this.tempAllData))
+ if (this.uploadedDataArray && this.uploadedDataArray != undefined && this.uploadedDataArray.length!=0) {
+ /* for (var i = 0; i < this.uploadedDataArray.length; i++) {
+ var action = this.uploadedDataArray[i][0];
+ for (var j = 0; j < this.tempAllData.length; j++) {
+ if (action === this.tempAllData[j].action) {
+ this.tempAllData.splice(j);
+ console.log("This template data===" + this.tempAllData[j]);
+ }
+ }
+ }
+ if (this.tempAllData && this.tempAllData != undefined) {
+ for (var i = 0; i < this.tempAllData.length; i++) {
+ // alert(this.checkIfelementExistsInArray(this.tempAllData[i].action,this.actions))
+ var result = this.checkIfelementExistsInArray(this.tempAllData[i].action, this.actions);
+ if (this.tempAllData[i].action === "AllAction") result = true;
+ if (!result) {
+ console.log("Removing VM action==" + this.tempAllData[i].action)
+ this.tempAllData.splice(i, 1);
+ }
+
+ }
+ }
+ }
+ // console.log("This template data after==" + JSON.stringify(this.tempAllData))
+ /* wire up file reader */
+ const target: DataTransfer = <DataTransfer>(evt.target);
+
+ //console.log("filename========" + evt.target.files[0].name)
+ this.uploadFileName = evt.target.files[0].name;
+ var fileExtension = this.uploadFileName.substr(this.uploadFileName.lastIndexOf('.') + 1);
+ if (target.files.length != 1) {
+ throw new Error('Cannot upload multiple files on the entry');
+ }
+ if (fileExtension.toUpperCase() === 'XLS' || fileExtension.toUpperCase() === 'XLSX') {
+ const reader = new FileReader();
+ reader.onload = (e: any) => {
+ /* read workbook */
+ const bstr = e.target.result;
+ // console.log("print 1---" + bstr);
+ const wb = XLSX.read(bstr, { type: 'binary' });
+ // console.log("print 2---" + JSON.stringify(wb));
+ /* grab first sheet */
+ const wsname = wb.SheetNames[0];
+ // console.log("Name:---" + wsname);
+ const ws = wb.Sheets[wsname];
+
+ /* save data */
+
+ let arrData = (<AOA>(XLSX.utils.sheet_to_json(ws, { header: 1 })));
+ //console.log("row======" + (XLSX.utils.sheet_to_json(ws, { header: 1 })).toString())
+ // console.log("Array data---" + JSON.stringify(arrData));
+ this.uploadedDataArray = arrData;
+ this.firstArrayElement = arrData[0];
+ var remUploadedDataArray = arrData;
+ remUploadedDataArray.shift();
+ this.remUploadedDataArray = remUploadedDataArray;
+ if (arrData != null) {
+ this.getExcelUploadStatus = true;
+ this.nService.success('Success', 'Vm capabilities data uploaded successfully');
+
+ }
+ else {
+ this.nService.success('Error', 'Empty Vm capabilities file uploaded');
+ }
+ };
+ reader.readAsBinaryString(target.files[0]);
+ console.log('TARGET files---' + JSON.stringify(evt.target));
+ }
+ else {
+ this.nService.error('Error', 'Incorrect VM capabilities file uploaded');
+ }
+
+ }
+
+ addVmCapabilitiesData() {
+ for (var i = 0; i < this.uploadedDataArray.length; i++) {
+ var vnfcFuncCodeArray = [];
+ var data = this.uploadedDataArray[i];
+ // console.log("Data is "+ JSON.stringify(data))
+ //console.log("Data length: "+ data.length)
+ for (var j = 1; j < data.length; j++) {
+ // console.log("Data " +j +" is "+ JSON.stringify(data[j]))
+ if (data[j] != undefined) {
+ if (data[j].toUpperCase() === 'Y') {
+ vnfcFuncCodeArray.push(this.firstArrayElement[j]);
+ //vnfcFuncCodeArray.push({name:this.firstArrayElement[j]});
+ }
+ }
+ }
+ var action = this.uploadedDataArray[i][0];
+ if (action && action != undefined) {
+ var json = {
+ 'action': action,
+ 'action-level': 'vm',
+ 'scope': {
+ 'vnf-type': this.referenceDataObject['scope']['vnf-type'], //need to confirm what should be this value
+ 'vnfc-type': null
+ },
+ 'vnfc-function-code-list': vnfcFuncCodeArray,
+ 'template': 'N',
+ 'device-protocol': 'OS'
+ };
+
+ this.tempAllData.push(json);
+ }
+
+ }
+ }
+
+ //download template
+ save(form: any, isValid: boolean) {
+ if (this.referenceDataObject.action === '') {
+ this.nService.error('Error', 'Select a valid Action');
+ return;
+ }
+ if (this.referenceDataObject['device-protocol'] === '') {
+ this.nService.error('Error', 'Select a valid Device protocol');
+ return;
+ }
+
+ if (isValid) {
+ let referenceObject = this.prepareReferenceObject();
+ let theJSON = JSON.stringify({ 'reference_data': this.tempAllData }, null, '\t');
+ let uri = 'data:application/json;charset=UTF-8,' + encodeURIComponent(theJSON);
+ this.downloadData.reference = theJSON;
+ this.validateTempAllData();
+ var blob = new Blob([theJSON], {
+ type: 'text/plain'
+ });
+ let fileName = 'reference_AllAction_' + referenceObject.scopeName + '_' + '0.0.1V.json';
+ saveAs(blob, fileName);
+ var templateData = JSON.stringify(this.downloadData.template.templateData);
+ var nameValueData = JSON.stringify(this.downloadData.template.nameValueData);
+ var pdData = this.downloadData.pd.pdData;
+ if (templateData != '{}' && templateData != null && templateData != undefined) this.downloadTemplate();
+ if (nameValueData != '{}' && nameValueData != null && nameValueData != undefined) this.downloadNameValue();
+ if (pdData != '' && pdData != null && pdData != undefined) this.downloadPd();
+ }
+ }
+
+ downloadTemplate() {
+ var fileName = this.downloadData.template.templateFileName;
+ var theJSON = this.downloadData.template.templateData;
+ if (fileName != null || fileName != '') {
+ var fileExtensionArr = fileName.split('.');
+ var blob = new Blob([theJSON], {
+ type: 'text/' + fileExtensionArr[1]
+ });
+ saveAs(blob, fileName);
+ }
+ }
+
+ downloadNameValue() {
+ var fileName = this.downloadData.template.nameValueFileName;
+ var theJSON = this.downloadData.template.nameValueData;
+ var blob = new Blob([theJSON], {
+ type: 'text/json'
+ });
+
+ saveAs(blob, fileName);
+ }
+
+ downloadPd() {
+ let fileName = this.downloadData.pd.pdFileName;
+ let theJSON = this.downloadData.pd.pdData;
+ var blob = new Blob([theJSON], {
+ type: 'text/plain'
+ });
+
+ saveAs(blob, fileName);
+ }
+
+ saveToAppc(valid, form) {
+ if (this.referenceDataObject.action === '') {
+ this.nService.error('Error', 'Select a valid Action');
+ return;
+ }
+ if (this.referenceDataObject['device-protocol'] === '') {
+ this.nService.error('Error', 'Select a valid Device protocol');
+ return;
+ }
+
+ try {
+ form._submitted = true;
+ if (valid) {
+
+ let referenceObject = this.prepareReferenceObject();
+ console.log('##########');
+
+ console.log(referenceObject);
+ this.validateTempAllData();
+ let theJSON = JSON.stringify(this.tempAllData, null, '\t');
+ let fileName = 'reference_AllAction_' + referenceObject.scopeName + '_' + '0.0.1V.json';
+ this.uploadArtifact(JSON.stringify({ reference_data: this.tempAllData }), this.tempAllData[this.tempAllData.length - 1], fileName);
+ var templateData = JSON.stringify(this.appData.template.templateData);
+ var nameValueData = JSON.stringify(this.appData.template.nameValueData);
+ var pdData = JSON.stringify(this.appData.pd);
+ if (templateData != '{}' && templateData != null && templateData != undefined) this.saveTemp();
+ if (nameValueData != '{}' && nameValueData != null && nameValueData != undefined) this.saveNameValue();
+ if (pdData != '{}' && pdData != null && pdData != undefined) this.savePd();
+ if (this.actionChanged) {
+ this.referenceDataObject.action = this.currentAction;
+ this.populateExistinAction(this.referenceDataObject.action);
+ this.actionChanged = false;
+ }
+ }
+ }
+ catch (e) {
+ this.nService.warn('status', 'unable to save the artifact');
+ }
+ }
+
+ validateTempAllData() {
+ if (this.tempAllData) {
+ var updatedData = [];
+ this.tempAllData.forEach(data => {
+ if (data.action) {
+ updatedData.push(data);
+ }
+ });
+ this.tempAllData = updatedData;
+ }
+ }
+
+ appendSlashes(artifactData) {
+ return artifactData.replace(/"/g, '\\"');
+ }
+
+ uploadArtifact(artifactData, dataJson, fileName) {
+ let data = [];
+ let slashedPayload = this.appendSlashes(artifactData);
+ let newPyaload = '{"userID": "' + localStorage['userId'] + '","vnf-type" : "' + dataJson['scope']['vnf-type'] + '","action" : "AllAction","artifact-name" : "' + fileName + '","artifact-type" : "APPC-CONFIG","artifact-version" : "0.1","artifact-contents" :" ' + slashedPayload + '"}';
+ let payload = {
+ 'input': {
+ 'design-request': {
+ 'request-id': localStorage['apiToken'],
+ 'action': 'uploadArtifact',
+ 'payload': newPyaload,
+ }
+ }
+ };
+ this.ngProgress.start();
+ this.httpUtils.post({
+ url: environment.getDesigns,
+ data: payload
+ }).subscribe((resp) => {
+ if (resp != null && resp.output.status.code == '400') {
+ window.scrollTo(0, 0);
+ this.nService.success('Status', 'successfully uploaded the Reference Data');
+ } else {
+ this.nService.warn('Status', 'Error while saving Reference Data');
+ }
+ this.uploadStatusError = false;
+ this.getRefStatus = false;
+ this.ngProgress.done();
+ }, (err) => {
+ this.nService.error('Status', 'Error Connecting to the APPC Network');
+ window.scrollTo(0, 0);
+ });
+ this.appData.reference = payload;
+ setTimeout(() => {
+ this.ngProgress.done();
+ }, 3500);
+ }
+
+ retriveFromAppc() {
+ if (sessionStorage.getItem('updateParams') != 'undefined') {
+ this.getArtifact();
+ this.noCacheData = false;
+ } else {
+ this.noCacheData = true;
+ }
+ }
+
+ cloneMessage(servermessage) {
+ var clone = {};
+ for (var key in servermessage) {
+ if (servermessage.hasOwnProperty(key)) //ensure not adding inherited props
+ clone[key] = servermessage[key];
+ }
+ return clone;
+ }
+
+ public showUpload() {
+ this.selectedUploadType = this.uploadTypes[0].value;
+ };
+
+ public fileChange(input) {
+ this.fileName = input.target.files[0].name.replace(/C:\\fakepath\\/i, '');
+ this.fileUploaded = true;
+ this.disableRetrieve = true;
+ if (input.target.files && input.target.files[0]) {
+ // Create the file reader
+ let reader = new FileReader();
+ this.readFile(input.target.files[0], reader, (result) => {
+ // After the callback fires do:
+ if ('Reference Data' === this.selectedUploadType) {
+ try {
+ let obj: any;
+ let jsonObject = (JSON.parse(result))['reference_data'];
+ this.uploadedData = JSON.parse(JSON.stringify(jsonObject));
+ this.tempAllData = JSON.parse(JSON.stringify(jsonObject));
+ this.notificationService.notifySuccessMessage('Reference Data file successfully uploaded..');
+ if (jsonObject instanceof Array) {
+ this.referenceDataObject = jsonObject[0];
+ jsonObject.forEach(obj => {
+ this.selectedActions.push(obj.action);
+ });
+ } else {
+ this.referenceDataObject = jsonObject;
+ this.selectedActions.push(jsonObject.action);
+ }
+ if (this.referenceDataObject.action === 'OpenStack Actions') {
+ this.deviceProtocols = ['', 'OpenStack'];
+ this.buildDesignComponent.tabs = [
+ {
+ type: 'dropdown',
+ name: 'Reference Data',
+ url: 'references',
+ }];
+ }
+ else {
+ this.buildDesignComponent.tabs = [
+ {
+ name: 'Reference Data',
+ url: 'references',
+ }, {
+ name: 'Template',
+ url: 'templates/myTemplates',
+ }, {
+ name: 'Parameter Definition',
+ url: 'parameterDefinitions/create'
+ } /*, {
+ name: "Test",
+ url: 'test',
+ }*/
+ ];
+ }
+ if (this.referenceDataObject.template == null) {
+ this.referenceDataObject.template = 'Y';
+ }
+ if (this.referenceDataObject['action-level'] == null) {
+ this.referenceDataObject['action-level'] = 'VNF';
+ }
+ } catch (e) {
+ this.nService.error('Error', 'Incorrect file format');
+ }
+ }
+ this.hideModal = true;
+ });
+ } else {
+ this.notificationService.notifyErrorMessage('Failed to read file..');
+ }
+
+ }
+
+ public readFile(file, reader, callback) {
+ // Set a callback funtion to fire after the file is fully loaded
+ reader.onload = () => {
+ // callback with the results
+ callback(reader.result);
+ };
+ this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size);
+ // Read the file
+ reader.readAsText(file, 'UTF-8');
+ }
+
+ fileChangeEvent(fileInput: any) {
+ let obj: any = fileInput.target.files;
+ }
+
+ clearVnfcData() {
+ this.Sample = {
+ 'vnfc-instance': '1',
+ 'vnfc-function-code': '',
+ 'ipaddress-v4-oam-vip': '',
+ 'group-notation-type': '',
+ 'group-notation-value': ''
+ };
+ }
+
+ setVmInstance(index) {
+ this.referenceDataObject.vm[index]['vm-instance'] = index + 1;
+ }
+
+ setVnfcType(str: String) {
+ this.Sample['vnfc-type'] = str;
+ }
+
+ getChange(value: String) {
+ if (value === 'vnfType') {
+ this.referenceDataObject.scope['vnfc-type'] = '';
+ }
+ }
+
+ resetForm() {
+ this.referenceDataObject['action-level'] = 'vnf';
+ this.referenceDataObject.template = 'Y';
+ this.referenceDataObject['device-protocol'] = '';
+ this.referenceDataObject['user-name'] = '';
+ this.referenceDataObject['port-number'] = '';
+ this.refernceScopeObj.sourceType = '';
+ this.Sample['vnfc-type'] = '';
+ }
+
+ populateExistinAction(data) {
+ let existAction = this.tempAllData.findIndex(obj => {
+ return obj.action == data;
+ });
+ if (existAction > -1) {
+ let obj = $.extend(true, {}, this.tempAllData[existAction]);
+ this.referenceDataObject = obj;
+ this.referenceDataObject.scope['vnf-type'] = obj['scope']['vnf-type'];
+ this.referenceDataObject.scope['vnfc-type'] = obj['scope']['vnfc-type'];
+ this.referenceDataObject['device-protocol'] = obj['device-protocol'];
+ this.refernceScopeObj['sourceType'] = obj['scopeType'];
+ } else {
+ this.resetForm();
+ this.referenceDataObject.action = data;
+ }
+ //# iof healthCeck change deviceprotocol drp vaues
+ if (data == 'HealthCheck') {
+ this.deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'REST'];
+ this.actionHealthCheck = true;
+ } else if (data == 'UpgradeBackout' || data == 'ResumeTraffic' || data == 'QuiesceTraffic' || data == 'UpgradeBackup' || data == 'UpgradePostCheck' || data == 'UpgradePreCheck' || data == 'UpgradeSoftware' || data == 'ConfigBackup' || data == 'ConfigRestore' || data == 'StartApplication' || data == 'StopApplication') {
+ this.deviceProtocols = ['', 'CHEF', 'ANSIBLE'];
+ } else if (data == 'OpenStack Actions') {
+ this.deviceProtocols = ['', 'OpenStack'];
+ } else if (data == 'ConfigScaleOut' || data == 'Configure' || data == 'ConfigModify') {
+ this.deviceProtocols = ['', 'CHEF', 'ANSIBLE', 'NETCONF'];
+ } else if (data == 'GetRunningConfig') {
+ this.deviceProtocols = ['', 'NETCONF'];
+ } else {
+ this.deviceProtocols = ['', 'ANSIBLE', 'CHEF', 'NETCONF-XML', 'REST', 'RESTCONF', 'CLI'];
+ this.actionHealthCheck = false;
+ }
+ }
+
+ //Modal pop up for action change with values entered.
+ actionChange(data, content, userForm) {
+ // this.actionChanged = true;
+ if (data == null) {
+ return;
+ }
+ if ((userForm.valid) && this.oldAction != '' && this.oldAction != undefined) {
+ this.actionChanged = true;
+ this.modalService.open(content).result.then(res => {
+ if (res == 'yes') {
+ this.currentAction = this.referenceDataObject.action;
+ this.referenceDataObject.action = this.oldAction;
+ $('#saveToAppc').click();//make sure the save all is done before the tempall obj is saved form the API
+ this.oldAction = this.referenceDataObject.action + '';
+ if (this.oldAction === 'OpenStack Actions') {
+
+ this.uploadedDataArray = [];
+ this.remUploadedDataArray = [];
+ this.firstArrayElement = [];
+ this.uploadFileName = '';
+ //this.tempAllData = [];
+ }
+ this.clearCache();
+ } else {
+ this.populateExistinAction(data);
+ this.oldAction = this.referenceDataObject.action + '';
+ this.clearCache();
+ }
+ });
+ } else {
+ this.oldAction = this.referenceDataObject.action + '';
+ this.populateExistinAction(data);
+ }
+
+
+ if (data == 'OpenStack Actions') {
+ this.buildDesignComponent.tabs = [
+ {
+ type: 'dropdown',
+ name: 'Reference Data',
+ url: 'references',
+ }];
+ }
+ else {
+ this.buildDesignComponent.tabs = [
+ {
+ name: 'Reference Data',
+ url: 'references',
+ }, {
+ name: 'Template',
+ url: 'templates/myTemplates',
+ }, {
+ name: 'Parameter Definition',
+ url: 'parameterDefinitions/create'
+ }/*, {
+ name: "Test",
+ url: 'test',
+ }*/
+ ];
+ }
+ if (data == 'Configure' || data == 'ConfigModify') {
+ this.nonConfigureAction = false;
+ } else {
+ this.nonConfigureAction = true;
+ }
+ }
+
+ clearCache() {
+ // get the value and save the userid and persist it.
+ this.mappingEditorService.setTemplateMappingDataFromStore(undefined);
+ localStorage['paramsContent'] = '{}';
+ this.mappingEditorService.setParamContent(undefined);
+ this.paramShareService.setSessionParamData(undefined);
+ this.appData = { reference: {}, template: { templateData: {}, nameValueData: {} }, pd: {} };
+ this.downloadData = {
+ reference: {},
+ template: { templateData: {}, nameValueData: {}, templateFileName: '', nameValueFileName: '' },
+ pd: { pdData: '', pdFileName: '' }
+ };
+ }
+
+ saveTemp() {
+ this
+ .httpUtils
+ .post(
+ { url: environment.getDesigns, data: this.appData.template.templateData })
+ .subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === 'success') {
+ this.nService.success('Status', 'Successfully uploaded the Template Data');
+ }
+ if (resp.output.status.code === '401') {
+ this.nService.warn('Status', 'Error in saving the Template to Appc');
+
+ }
+ },
+ (err) => this.nService.error('Status', 'Error Connecting to the APPC Network'));
+ }
+
+ saveNameValue() {
+ this
+ .httpUtils
+ .post(
+ {
+ url: environment.getDesigns, data: this.appData.template.nameValueData
+ })
+ .subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === 'success') {
+ this.nService.success('Status', 'Successfully uploaded the Name Value Pairs');
+ }
+ if (resp.output.status.code === '401') {
+ this.nService.warn('Status', 'Error in saving the Name value pairs to Appc');
+ }
+ },
+ error => {
+ this.nService.error('Status', 'Error Connecting to the APPC Network');
+ return false;
+ });
+ }
+
+ savePd() {
+ this
+ .httpUtils
+ .post(
+ {
+ url: environment.getDesigns, data: this.appData.pd
+ })
+ .subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === 'success') {
+ this.nService.success('Status', 'Successfully uploaded PD file');
+ }
+ if (resp.output.status.code === '401') {
+ this.nService.warn('Status', 'Error in saving the PD to Appc');
+ }
+ },
+ error => {
+ this.nService.error('Status', 'Error Connecting to the APPC Network');
+ return false;
+ });
+ }
+
+ openModel(toShow: any, message: any, title: any) {
+ this.modalComponent.isShow = toShow;
+ this.modalComponent.message = message;
+ this.modalComponent.title = title;
+ }
+
+ browseOption() {
+ $('#inputFile').trigger('click');
+ }
+
+ excelBrowseOption() {
+ $('#excelInputFile').trigger('click');
+ }
+
+ showIdentifier() {
+ $('#identifierModal').modal();
+ }
+
+ addToIdentDrp() {
+ if (!(this.referenceDataObject['template-id-list'])) {
+ this.referenceDataObject['template-id-list'] = [];
+ }
+ this.referenceDataObject['template-id-list'].push(this.templateId);
+ // this.referenceDataObject['template-id-list'] = this.identifierDrpValues
+ //this.identifierDrp = ""
+ }
+
+ resetVms() {
+ this.referenceDataObject.vm = [];
+ }
+
+ dataModified() {
+ this.referenceDataObject.vm = this.referenceDataObject.vm;
+ }
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css
new file mode 100644
index 0000000..94ef767
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.css
@@ -0,0 +1,35 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+.file {
+ visibility: hidden;
+ position: absolute;
+}
+
+.mt-30 {
+ margin-top: 30px;
+}
+
+.active-tab > a {
+ border-bottom: 5px solid #4B515D;
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html
new file mode 100644
index 0000000..150d5ad
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.html
@@ -0,0 +1,119 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+
+<simple-notifications [options]="options"></simple-notifications>
+<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'"
+ [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress>
+
+<tabs>
+ <tab [tabTitle]="'Template Configuration'">
+ <div>
+ <app-golden-configuration [(configMappingEditorContent)]="configMappingEditorContent" [isMappingComp]="true" #mappingComponent>
+ </app-golden-configuration>
+ </div>
+ </tab>
+ <tab [tabTitle]="'Param Values'">
+ <div class="form-group">
+ <div [hidden]="true">
+ <button type="button" id="modalButton" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="modal.open()">Open me!
+ </button>
+ </div>
+ <div>
+ <modal #modal>
+ <modal-header [show-close]="true">
+ <h4 class="modal-title">{{title}}</h4>
+ </modal-header>
+ <modal-body>
+ {{message}}
+ </modal-body>
+ <modal-footer>
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" data-dismiss="modal">Close
+ </button>
+ </modal-footer>
+ </modal>
+ </div>
+ <div class="card" style=" margin-bottom: 23px;">
+ <img class="card-img-top" data-src="holder.js/100%x180/" alt="">
+ <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;">
+ <div class="row" style="padding: 15px 25px">
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Action</label>
+ <input class="form-control" type="text" disabled value="{{action}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" />
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-12">
+ <div class="input-group">
+ <input id="inputFile2" class="file" #myInput type='file' (change)='fileChange(myInput)'>
+ <input type="text" class="input-lg" [(ngModel)]="myfileName" disabled placeholder="Upload Param file from PC" style="width:80%">
+ <button (click)="browseOption($event)" [disabled]="!enableMappingBrowse" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg">
+ Upload Param file
+ </button>
+ </div>
+ </div>
+
+ <input type="file" id="filesparam" style="visibility:hidden;" class="form-control-file" (change)="fileParamChange(myInputParam)" #myInputParam placeholder="Upload file..."
+ />
+ <div class="row" style="margin-bottom: 20px;">
+ <div class="col-md-12 text-right">
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="retrieveNameValueFromAppc()">Retrieve Name/Value from APPC
+ </button>
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="syncParam()">Synchronize with name values
+ </button>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <!--Commenting out 1712 changes here-->
+ <!--<div class="col-md-12" [hidden]="!showMappingDownloadDiv"><label>Download Name/Value pair as : </label>
+ <select class="form-control col-md-3" [(ngModel)]="mapppingDownloadType" (ngModelChange)="onDownloadParameter()">
+ <option value="">Select</option>
+ <option value="Json">JSON</option>
+ <option value="Xls">XLS</option>
+ </select>
+</div>-->
+
+ <div class="col-md-12"></div>
+ <div><label for="textAreaGeneratedTemplate">
+ <div class="mdl-card__title-text">Param Name Value List</div>
+ <div><font size="1">(Please click anywhere on the editor to see the synced name value pairs)</font></div>
+ </label>
+ <!-- <ace-editor [(text)]="this.artifactRequest.paramsContent" [theme]="'chrome'" [mode]="'velocity'" (textChanged)="onParamChanges($event)" [options]="{maxLines: 'Infinity', fontSize: '13pt'}"
+ style="min-height: 500px; width: fit-content;"></ace-editor> -->
+ <ace-editor [(text)]="this.artifactRequest.paramsContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" (textChanged)="onParamChanges($event)"
+ [options]="{maxLines: 'Infinity', fontSize: '13pt' }" style="min-height: 500px; width: 100%"></ace-editor>
+ </div>
+
+ </tab>
+</tabs> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts
new file mode 100644
index 0000000..9ea95ec
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/param-name-value.component.ts
@@ -0,0 +1,711 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import { Component, ContentChildren, OnInit, QueryList, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { MappingEditorService } from '../../../../shared/services/mapping-editor.service';
+import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service';
+import { GoldenConfigurationComponent } from '../template-configuration/template-configuration.component';
+import { ArtifactRequest } from '../../../../shared/models/index';
+import { NotificationService } from '../../../../shared/services/notification.service';
+import { ModalComponent } from '../../../../shared/modal/modal.component';
+import { saveAs } from 'file-saver';
+import { DialogService } from 'ng2-bootstrap-modal';
+import { ConfirmComponent } from '../../../../shared/confirmModal/confirm.component';
+import { BuildDesignComponent } from '../../build-artifacts.component';
+import { ParamShareService } from '../../../../shared/services/paramShare.service';
+import { NotificationsService } from 'angular2-notifications';
+import { Tab } from './tab';
+import { environment } from '../../../../../environments/environment';
+import { NgProgress } from 'ngx-progressbar';
+import * as XLSX from 'xlsx';
+
+type AOA = Array<Array<any>>;
+
+function s2ab(s: string): ArrayBuffer {
+ const buf = new ArrayBuffer(s.length);
+ const view = new Uint8Array(buf);
+ for (let i = 0; i !== s.length; ++i) {
+ view[i] = s.charCodeAt(i) & 0xFF;
+ }
+ return buf;
+}
+
+declare var $: any;
+
+@Component({
+ selector: 'app-golden-configuration-mapping',
+ templateUrl: './param-name-value.component.html',
+ styleUrls: ['./param-name-value.component.css']
+})
+export class GoldenConfigurationMappingComponent implements OnInit {
+ enableMappingSave: boolean = false;
+ aceText: string = '';
+ fileName: string = '';
+ actionType: any;
+ modal: any;
+ configMappingEditorContent: any;
+ fileType: any = '';
+ myfileName: any;
+ initialData: any;
+ scopeName: any;
+ downloadedFileName: any;
+ enableSaveToAppc: boolean = false;
+ versionNo: any = '0.0.1';
+ showVersionDiv: boolean = false;
+ initialAction: any;
+ title: any;
+ message: any;
+ enableMappingBrowse: boolean = true;
+ enableDownload: boolean = false;
+ showMappingDownloadDiv: boolean = false;
+ mapppingDownloadType: any;
+ action: any;
+ artifactName: any;
+ enableMerge: boolean = false;
+ apiToken = localStorage['apiToken'];
+ userId = localStorage['userId'];
+ public uploadTypes = [
+ {
+ value: 'Mapping Data',
+ display: 'Sample Json Param File'
+ }
+ ];
+ selectedUploadType: string = this.uploadTypes[0].value;
+ options = {
+ timeOut: 1000,
+ showProgressBar: true,
+ pauseOnHover: true,
+ clickToClose: true,
+ maxLength: 200
+ };
+ artifactRequest: ArtifactRequest = new ArtifactRequest();
+ @ViewChild(GoldenConfigurationComponent) mappingComponent: GoldenConfigurationComponent;
+ @ViewChild('templateeditor') templateeditor;
+ @ViewChild('myInputParam') myInputParam: any;
+ @ViewChild(ModalComponent) modalComponent: ModalComponent;
+ @ContentChildren(Tab) tabs: QueryList<Tab>;
+ public subscription: any;
+ public item: any = {};
+
+ public Actions = [
+ { action: 'ConfigBackup', value: 'ConfigBackup' },
+ { action: 'ConfigModify', value: 'ConfigModify' },
+ { action: 'ConfigRestore', value: 'ConfigRestore' },
+ { action: 'Configure', value: 'Configure' },
+ { action: 'GetRunningConfig', value: 'GetRunningConfig' },
+ { action: 'HealthCheck', value: 'HealthCheck' },
+ { action: 'StartApplication', value: 'StartApplication' },
+ { action: 'StopApplication', value: 'StopApplication' }
+ ];
+ vnfType: any;
+ vnfcType: any;
+ protocol: any;
+ refObj: any;
+ public paramsContent = localStorage['paramsContent'];
+
+ constructor (private buildDesignComponent: BuildDesignComponent, private paramShareService: ParamShareService, private router: Router, private httpUtil: HttpUtilService, private dialogService: DialogService, private activeRoutes: ActivatedRoute, private mappingEditorService: MappingEditorService, private notificationService: NotificationService, private nService: NotificationsService, private ngProgress: NgProgress) {
+ this.artifactRequest.action = '';
+ this.artifactRequest.version = '';
+ this.artifactRequest.paramKeysContent = '';
+ }
+
+ ngOnInit() {
+ var refObj = this.refObj = this.prepareFileName();
+ if (refObj && refObj != undefined) {
+ if (this.paramsContent && this.paramsContent != undefined && this.paramsContent !== '{}') {
+ this.artifactRequest.paramsContent = this.formatNameValuePairs(this.paramsContent);
+ // this.artifactRequest.paramsContent = this.paramsContent;
+
+ }
+ else {
+ this.artifactRequest.paramsContent = '{}';
+ }
+
+ // refObj = refObj[refObj.length - 1];
+ this.item = refObj;
+ this.vnfType = this.item.scope['vnf-type'];
+ this.vnfcType = this.item.scope['vnfc-type'];
+ this.protocol = this.item['device-protocol'];
+ this.action = this.item.action;
+ var artifactList = this.item['artifact-list'];
+ for (var i = 0; i < artifactList.length; i++) {
+ var artifactName = artifactList[i]['artifact-name'];
+ var array = artifactName.split('_');
+ if (array[0].toUpperCase() === 'TEMPLATE') {
+ this.artifactName = artifactName;
+ }
+ }
+ }
+ else {
+ this.item = {
+ 'action': '',
+ 'scope': { 'vnf-type': '', 'vnfc-type': '' },
+ 'vm': [],
+ 'protocol': '',
+ 'download-dg-reference': '',
+ 'user-name': '',
+ 'port-number': '',
+ 'artifact-list': [],
+ 'deviceTemplate': '',
+ 'scopeType': ''
+ };
+ }
+ this.initialAction = this.item.action;
+ this.activeRoutes.url.subscribe(UrlSegment => {
+ this.actionType = UrlSegment[0].path;
+ });
+ if (this.actionType === 'configureTemplate') {
+ this.mappingEditorService.fromScreen = 'TemplateScreen';
+ }
+ if (this.actionType === 'myTemplates') {
+ this.mappingEditorService.fromScreen = 'MappingScreen';
+ }
+ this.mappingEditorService.paramData = [];
+
+
+ }
+
+ //========================== End of ngOnInit() Method============================================
+ browseOption() {
+ $('#filesparam').trigger('click');
+ }
+
+ //========================== End of browseOption() Method============================================
+ selectedNavItem(item: any) {
+ this.item = item;
+ }
+
+ //========================== End of selectedNavItem() Method============================================
+ ngOnDestroy() {
+ this.prepareFileName();
+ }
+
+ //========================== End of ngOnDestroy() Method============================================
+ ngAfterViewInit() {
+ if (this.mappingEditorService.fromScreen === 'MappingScreen') {
+ this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore();
+ this.fileType = sessionStorage.getItem('fileType');
+ if (this.configMappingEditorContent)
+ this.mappingEditorService.initialise(this.mappingComponent.templateeditor.getEditor(), this.configMappingEditorContent, this.modal);
+ }
+ if (this.refObj) {
+
+ this.artifactRequest.action = this.item.action;
+ this.artifactRequest.vnfType = this.vnfType;
+ if (this.vnfcType && this.vnfcType.length != 0) {
+ this.scopeName = this.vnfcType;
+ }
+ else {
+ this.scopeName = this.vnfType;
+ }
+ }
+ else {
+ this.Actions = [];
+ this.enableMappingBrowse = false;
+ }
+ }
+
+ //========================== End of ngAfterViewInit() Method============================================
+ upload(evt: any) {
+ /* wire up file reader */
+ if (evt.target.files[0]) {
+ const target: DataTransfer = <DataTransfer>(evt.target);
+ this.myfileName = evt.target.files[0].name;
+ var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1);
+ if (fileExtension.toUpperCase() === 'xls'.toUpperCase()) {
+ if (target.files.length != 1) {
+ throw new Error('Cannot upload multiple files on the entry');
+ }
+ const reader = new FileReader();
+ reader.onload = (e: any) => {
+ /* read workbook */
+ const bstr = e.target.result;
+ const wb = XLSX.read(bstr, { type: 'binary' });
+ /* grab first sheet */
+ const wsname = wb.SheetNames[0];
+ const ws = wb.Sheets[wsname];
+ /* save data */
+ let arrData = (<AOA>(XLSX.utils.sheet_to_json(ws, { header: 1 })));
+ var jsonStr = arrData.toString();
+ var JsonArr = jsonStr.split(',');
+ var finalStr = '{\r\n';
+ for (var i = 0; i < JsonArr.length; i = i + 2) {
+ var key = JsonArr[i];
+ var value = JsonArr[i + 1];
+ finalStr = finalStr + key + ':' + value + ',\r\n';
+ }
+ finalStr = finalStr.substring(0, finalStr.length - 3) + '\r\n}';
+ this.artifactRequest.paramsContent = finalStr;
+ this.initialData = finalStr;
+ this.enableMappingSave = true;
+ };
+ reader.readAsBinaryString(target.files[0]);
+ if ('Mapping Data' === this.selectedUploadType) {
+ this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
+ this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent);
+ }
+ }
+ else {
+ let reader = new FileReader();
+ this.readFile(evt.target.files[0], reader, (result) => {
+ if ('Mapping Data' === this.selectedUploadType) {
+ var jsonObject = JSON.parse(result);
+ this.artifactRequest.paramsContent = JSON.stringify(jsonObject, null, 1);
+ this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
+ this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent);
+ }
+ this.initialData = result;
+ this.enableMappingSave = true;
+ });
+ }
+ }
+ else {
+ this.notificationService.notifyErrorMessage('Failed to reading file..');
+ }
+ this.myInputParam.nativeElement.value = '';
+ }
+
+ //========================== End of upload() Method============================================
+ //uncommenting for 1710
+ public fileParamChange(input) {
+ if (input.files && input.files[0]) {
+ this.enableMappingSave = true;
+ this.myfileName = input.files[0].name;
+ var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1);
+ if (this.validateUploadedFile(fileExtension)) {
+ // Create the file reader
+ let reader = new FileReader();
+ this.readFile(input.files[0], reader, (result) => {
+ if ('Mapping Data' === this.selectedUploadType) {
+ var jsonObject = JSON.parse(result);
+ this.artifactRequest.paramsContent = JSON.stringify(jsonObject, null, 1);
+ this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
+ this.mappingEditorService.setParamContent(this.artifactRequest.paramsContent);
+ localStorage['paramsContent'] = this.artifactRequest.paramsContent;
+ }
+ this.enableMerge = true;
+ this.initialData = result;
+ });
+ }
+ else {
+ this.nService.error("Error", "Incorrect File Format")
+ this.artifactRequest.paramsContent = ''
+ }
+ }
+ else {
+ this.nService.error("Error", "Failed to read file");
+ }
+ this.myInputParam.nativeElement.value = '';
+ }
+
+ //========================== End of fileParamChange() Method============================================
+ validateUploadedFile(fileExtension) {
+
+ if (fileExtension.toUpperCase() === 'json'.toUpperCase()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ }
+ //========================== End of validateUploadedFile() Method============================================
+ public readFile(file, reader, callback) {
+ // Set a callback funtion to fire after the file is fully loaded
+ reader.onload = () => {
+ // callback with the results
+ callback(reader.result);
+ };
+ this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size);
+ // Read the file
+ reader.readAsText(file, 'UTF-8');
+ }
+
+ //========================== End of readFile() Method============================================
+ public onParamChanges(data) {
+ this.artifactRequest.paramsContent = data;
+ localStorage['paramsContent'] = this.artifactRequest.paramsContent;
+ }
+
+ //========================== End of onParamChanges() Method============================================
+ onDownloadParameter() {
+ let refObj = this.refObj;
+ if (refObj) {
+ // refObj = refObj[refObj.length - 1];
+ let paramsKeyValueFromEditor: JSON;
+ this.initialData = this.artifactRequest.paramsContent;
+ paramsKeyValueFromEditor = JSON.parse(this.artifactRequest.paramsContent);
+ let theJSON = JSON.stringify(paramsKeyValueFromEditor, null, '\t');
+ var blob = new Blob([theJSON], {
+ type: 'text/json'
+ });
+ this.showVersionDiv = true;
+ let fileName: any;
+ fileName = this.updateFileName(refObj.action, this.scopeName, this.versionNo);
+ saveAs(blob, fileName);
+ }
+ else {
+ this.nService.error('Error', 'Please enter Action and VNF type in Reference Data screen');
+
+ }
+ }
+
+ //========================== End of onDownloadParameter() Method============================================
+ JSONToCSVConvertor(JSONData, fileName, ShowLabel) {
+ //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
+ var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
+ var CSV = '';
+ //This condition will generate the Label/Header
+ if (ShowLabel) {
+ var testRow = '';
+ for (var index in arrData[0]) {
+ CSV += index + '\t' + arrData[0][index] + '\r\n';
+ }
+ }
+ if (CSV == '') {
+ return;
+ }
+ //Initialize file format you want csv or xls
+ var uri = 'data:application/vnd.ms-excel,' + encodeURI(CSV);
+ var link = document.createElement('a');
+ link.href = uri;
+ link.download = fileName + '.xls';
+ //this part will append the anchor tag and remove it after automatic click
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+
+ //========================== End of JSONToCSVConvertor() Method============================================
+ updateFileNameForXls(action: any, scopeName: any, versionNo: any) {
+ let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V';
+ return fileName;
+ }
+
+ //========================== End of updateFileNameForXls() Method============================================
+ appendSlashes(artifactData) {
+ let x = artifactData.replace(new RegExp(',"', 'g'), ',\"');
+ let y = x.replace(new RegExp('":', 'g'), '\":');
+ let z = y.replace(new RegExp('{"', 'g'), '{\"');
+ let t = z.replace(new RegExp(':"', 'g'), ':\"');
+ let m = t.replace(new RegExp('",', 'g'), '\",');
+ let n = y.replace(new RegExp('"}', 'g'), '\"}');
+ let nw = n.replace(new RegExp('{"', 'g'), '{\"');
+ let nw1 = nw.replace(new RegExp(':"', 'g'), ':\"');
+ let nw2 = nw1.replace(new RegExp('",', 'g'), '\",');
+ return nw2;
+ }
+
+ //========================== End of appendSlashes() Method============================================
+ updateFileName(action: any, scopeName: any, versionNo: any) {
+ let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V.json';
+ this.downloadedFileName = fileName;
+ return fileName;
+ }
+
+ //========================== End of updateFileName() Method============================================
+ prepareFileName(): any {
+ let fileNameObject: any = this.mappingEditorService.latestAction;
+ return fileNameObject;
+ }
+
+ //========================== End of prepareFileName() Method============================================
+ openModel(toShow: any, message: any, title: any) {
+ this.message = message;
+ this.title = title;
+ $('#modalButton').trigger('click');
+ }
+
+ //========================== End of openModel() Method============================================
+ checkSave(selectedAction): void {
+ if (this.actionType === 'updateTemplate') {
+ if (!this.buildDesignComponent.isReferenceFound(selectedAction, this.mappingEditorService.getReferenceList())) {
+ this.nService.error('Error', 'Reference Data not found. Please add Reference Data for Action:' + selectedAction);
+ }
+ }
+ if (this.initialData != this.artifactRequest.paramsContent) {
+ this.showConfirm(this.initialData);
+ }
+ else {
+ this.initialAction = this.item.action;
+ }
+ }
+
+ //========================== End of checkSave() Method============================================
+ showConfirm(initialData) {
+ let disposable = this.dialogService.addDialog(ConfirmComponent, {
+ title: 'Confirm title',
+ message: 'Confirm message'
+ })
+ .subscribe((isConfirmed) => {
+ //We get dialog result
+ if (isConfirmed) {
+ this.artifactRequest.paramsContent = initialData;
+ this.initialAction = this.item.action;
+ }
+ else {
+ this.item.action = this.initialAction;
+ }
+ });
+ }
+
+ //========================== End of showConfirm() Method============================================
+ retrieveNameValueFromAppc() {
+ let refObj = this.refObj;
+ if (refObj && refObj != undefined) {
+ // console.log("REF OBJECT IN RETRIVE"+JSON.stringify(refObj));
+ this.enableMerge = true;
+ var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, '');
+ let fileName = this.updateFileName(this.item.action, scopeName, this.versionNo);
+ let payload = '{"userID": "' + this.userId + '", "action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}';
+ // console.log("payload OBJECT IN RETRIVE"+JSON.stringify(payload));
+ let input = {
+ 'input': {
+ 'design-request': {
+ 'request-id': this.apiToken,
+ 'action': 'getArtifact',
+ 'payload': payload
+ }
+ }
+ };
+
+ console.log('Retrieve name value from appc payload===>>' + payload);
+ let artifactContent: any;
+ this.ngProgress.start();
+ this.httpUtil.post({
+ url: environment.getDesigns,
+ data: input
+ }).subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === 'success') {
+ this.nService.success('Success', 'Name/value pairs retrieved successfully from APPC');
+ this.enableMerge = true;
+ let result = JSON.parse(resp.output.data.block).artifactInfo[0];
+ result = result['artifact-content'];
+ var string = result.substring(2, result.length - 2);
+ var stringArr = string.split(',');
+ var newStringArr = [];
+ var resultStr = '{\r\n';
+ for (var index in stringArr) {
+ newStringArr[index] = stringArr[index] + ',\r\n';
+ }
+ for (var index in newStringArr) {
+ resultStr = resultStr + newStringArr[index];
+ }
+ resultStr = resultStr.substring(0, resultStr.length - 3) + '\r\n}';
+ this.artifactRequest.paramsContent = resultStr;
+ this.mappingEditorService.setParamContent(resultStr);
+ localStorage['paramsContent'] = resultStr;
+ this.enableMappingSave = true;
+ }
+ else {
+ this.nService.info('Information', 'There are no name value pairs saved in APPC for the selected action!');
+ }
+ this.ngProgress.done();
+ },
+ error => this.nService.error('Error', 'Error in connecting to APPC Server'));
+ }
+ setTimeout(() => {
+ this.ngProgress.done();
+ }, 3500);
+ }
+
+ //========================== End of retrieveNameValueFromAppc() Method============================================
+ saveNameValueToAppc() {
+ let refObj = this.refObj;
+ if (refObj && refObj != undefined) {
+ // refObj = refObj[refObj.length - 1];
+ let paramsKeyValueFromEditor = JSON.parse(this.artifactRequest.paramsContent);
+ let action = this.item.action;
+ let fileName = this.updateFileName(refObj.action, this.scopeName, this.versionNo);
+ let vnfType = this.vnfType;
+ let Json = [paramsKeyValueFromEditor];
+ let slashedPayload = this.appendSlashes(JSON.stringify(Json));
+ let newPayload =
+ {
+ 'userID': this.userId,
+ 'vnf-type': this.vnfType,
+ 'action': action,
+ 'artifact-name': fileName,
+ 'artifact-type': 'APPC-CONFIG',
+ 'artifact-version': this.versionNo,
+ 'artifact-contents': slashedPayload
+ };
+ let data =
+ {
+ 'input': {
+ 'design-request': {
+ 'request-id': this.apiToken,
+ 'action': 'uploadArtifact',
+ 'payload': JSON.stringify(newPayload)
+ }
+ }
+ };
+ this
+ .httpUtil
+ .post(
+ { url: environment.getDesigns, data: data })
+ .subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === 'success') {
+ this.nService.success('Success', 'Name/value pairs saved successfully to APPC');
+ }
+ if (resp.output.status.code === '401') {
+ this.nService.error('Error', resp.output.status.message);
+ }
+ },
+ error => this.nService.error('Error', 'Could not save name value pairs. Error in connecting APPC Server'));
+ }
+ setTimeout(() => {
+ this.ngProgress.done();
+ }, 3500);
+ }
+
+ //========================== End of saveNameValueToAppc() Method============================================
+ formatNameValuePairs(namevaluePairs: string) {
+ //var string = namevaluePairs.substring(2, namevaluePairs.length - 2);
+ /* var stringArr = string.split(",");
+ var newStringArr = [];
+ var resultStr = "{\r\n\"";
+ for (var index in stringArr) {
+ newStringArr[index] = stringArr[index] + ",\r\n";
+ }
+ for (var index in newStringArr) {
+ resultStr = resultStr + newStringArr[index];
+ }
+ resultStr = resultStr.substring(0, resultStr.length - 3) + "\"\r\n}"
+ return resultStr;*/
+
+ var string = namevaluePairs.substring(1, namevaluePairs.length - 1);
+ var stringArr = string.split(',');
+ var newStringArr = [];
+ var resultStr = '{\r\n';
+ for (var index in stringArr) {
+ newStringArr[index] = stringArr[index] + ',\r\n';
+ }
+ for (var index in newStringArr) {
+ resultStr = resultStr + newStringArr[index];
+ }
+ resultStr = resultStr.substring(0, resultStr.length - 3) + '\r\n}';
+ return resultStr;
+ }
+
+ //========================== End of formatNameValuePairs() Method============================================
+
+ public syncParam() {
+ var paramNameValuesStr = localStorage['paramsContent'];
+ var pdData = this.paramShareService.getSessionParamData();
+ var paramNameValues = [];
+ var pdDataArrayForParamShare = [];
+ var pdDataArrayForSession = [];
+ try {
+ paramNameValues = JSON.parse(paramNameValuesStr);
+ console.log('Param Name values array==' + JSON.stringify(paramNameValues));
+ if (paramNameValues && paramNameValues != undefined) {
+ for (var index in paramNameValues) {
+ var json = {
+ 'paramName': index,
+ 'paramValue': paramNameValues[index]
+ };
+ pdDataArrayForParamShare.push(json);
+
+ pdDataArrayForSession.push({
+ 'name': index,
+ 'type': null,
+ 'description': null,
+ 'required': null,
+ 'default': null,
+ 'source': 'Manual',
+ 'rule-type': null,
+ 'request-keys': [{
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }],
+ 'response-keys': [{
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }, {
+ 'key-name': null,
+ 'key-value': null
+ }],
+ 'ruleTypeValues': [null]
+
+ });
+
+ }
+ this.paramShareService.setTemplateData(pdDataArrayForParamShare);
+
+ if (pdData && pdData != undefined) {
+ for (var i = 0; i < pdDataArrayForSession.length; i++) {
+
+ pdData.forEach(function (arr2item) {
+ if (pdDataArrayForSession[i].name === arr2item.name) {
+
+ var json = {
+ 'name': arr2item.name,
+ 'type': arr2item.type,
+ 'description': arr2item.description,
+ 'required': arr2item.required,
+ 'default': arr2item.default,
+ 'source': arr2item.source,
+ 'rule-type': arr2item['rule-type'],
+ 'request-keys': arr2item['request-keys'],
+ 'response-keys': arr2item['response-keys'],
+ 'ruleTypeValues': arr2item.ruleTypeValues
+ };
+ pdDataArrayForSession.splice(i, 1, json);
+ // console.log("Result array index ==" + JSON.stringify(resultArr[i]))
+ }
+
+ });
+
+ }
+ }
+
+ this.paramShareService.setSessionParamData(pdDataArrayForSession);
+
+ this.router.navigate(['../../../vnfs/design/parameterDefinitions/create']);
+
+ }
+ }
+ catch (error) {
+ console.log('Error occured in syncing param names' + JSON.stringify(error));
+ this.nService.error('Error', 'Error synchronising with name values. Please check the format of json uploaded/ retrieved');
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts
new file mode 100644
index 0000000..5e4fa6c
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tab.ts
@@ -0,0 +1,43 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import {Component, Input} from '@angular/core';
+
+@Component({
+ selector: 'tab',
+ styles: [`
+ .pane {
+ padding: 1em;
+ }
+ `],
+ template: `
+ <div [hidden]="!isactive" class="pane">
+ <ng-content></ng-content>
+ </div>
+ `
+})
+export class Tab {
+ @Input('tabTitle') title: string;
+ @Input() isactive = false;
+ @Input() isParamTab = false;
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts
new file mode 100644
index 0000000..92f489e
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/param-name-value/tabs.ts
@@ -0,0 +1,63 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import {AfterContentInit, Component, ContentChildren, QueryList} from '@angular/core';
+import {Tab} from './tab';
+
+@Component({
+ selector: 'tabs',
+ template: `
+ <ul class="nav nav-tabs">
+ <li [ngClass]="{'active-tab':(tab.isactive==true)}" class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)"
+ [class.active]="tab.isactive">
+ <a class="nav-link" ng-href=''>{{tab.title}}</a>
+ </li>
+ </ul>
+ <ng-content></ng-content>
+ `, styleUrls: ['./param-name-value.component.css']
+})
+export class Tabs implements AfterContentInit {
+
+ @ContentChildren(Tab) tabs: QueryList<Tab>;
+
+
+ // contentChildren are set
+ ngAfterContentInit() {
+ // get all active tabs
+ let activeTabs = this.tabs.filter((tab) => tab.isactive);
+
+ // if there is no active tab set, activate the first
+ if (activeTabs.length === 0) {
+ this.selectTab(this.tabs.first);
+ }
+ }
+
+ public selectTab(tab: Tab) {
+ // deactivate all tabs
+ this.tabs.toArray().forEach(tab => tab.isactive = false);
+
+ // activate the tab the user has clicked on.
+ tab.isactive = true;
+ }
+
+}
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css
new file mode 100644
index 0000000..c8100e3
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.css
@@ -0,0 +1,35 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+.file {
+ visibility: hidden;
+ position: absolute;
+}
+
+.mt-30 {
+ margin-top: 30px;
+}
+
+.options-menu {
+ padding: 3px 20px;
+} \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html
new file mode 100644
index 0000000..c1fb030
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.html
@@ -0,0 +1,100 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+<simple-notifications [options]="options"></simple-notifications>
+<ng-progress [positionUsing]="'marginLeft'" [minimum]="0.15" [maximum]="1" [speed]="200" [showSpinner]="false" [direction]="'leftToRightIncreased'" [color]="'#6ab344'"
+ [trickleSpeed]="250" [thick]="true" [ease]="'linear'"></ng-progress>
+<div>
+ <div>
+ <div class="card" style="margin-bottom: 23px;">
+ <img class="card-img-top" data-src="holder.js/100%x180/" alt="">
+ <div class="card-block" style="border-top: 5px solid #6ab344;border-top-right-radius: 7px;border-top-left-radius: 7px;">
+ <div class="row" style="padding: 15px 25px">
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Action</label>
+ <input class="form-control" type="text" disabled value="{{action}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnf Type</label><input class="form-control" type="text" disabled value="{{vnfType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Vnfc Type</label><input class="form-control" type="text" disabled value="{{vnfcType}}" />
+ </div>
+ <div class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>Protocol</label><input class="form-control" type="text" disabled value="{{protocol}}" />
+ </div>
+ <div *ngIf="(action === 'ConfigScaleOut')" class="col-lg-3 col-sm-6 col-md-3 col-xs-12">
+ <label>templateIdentifier</label><input class="form-control" type="text" disabled value="{{identifier}}" />
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-12">
+ <div class="input-group">
+ <input id="inputFile" class="file" #myInput type='file' (change)='fileChange(myInput)'>
+ <input [(ngModel)]="fileName" type="text" class="input-lg" disabled placeholder="Upload template from PC" style="width:80%">
+ <button (click)="browseOption($event)" [disabled]="!enableBrowse" class="browse mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary input-lg"
+ type="button">Upload Template File
+ </button>
+ </div>
+ </div>
+
+ <br>
+ <div class="row" style="margin-bottom: 20px;">
+ <div class="col-md-12 text-right">
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="syncTemplate()">Synchronize Template Parameters
+ </button>
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="mergeParams()"> Merge from Param
+ </button>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <div><label for="textAreaGeneratedTemplate">
+ <div class="mdl-card__title-text">File Editor</div>
+ </label>
+ <!-- <ace-editor [(text)]="configMappingEditorContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" [options]="{maxLines: 'Infinity', fontSize: '13pt'}"
+ style="min-height: 500px; width: fit-content;scroll-snap-coordinate: 3%"></ace-editor> -->
+ <ace-editor [(text)]="configMappingEditorContent" #templateeditor [theme]="'chrome'" [mode]="'velocity'" [options]="{maxLines: 'Infinity', fontSize: '13pt' }"
+ style="min-height: 500px; width: 100%"></ace-editor>
+ </div>
+ <app-modal [title]="'Confirmation'" [isShow]="false" [message]="'Template is saved and ready for creating parameter definition'" #modalComponent>
+ </app-modal>
+ <modal #myModal>
+ <modal-header [show-close]="true">
+ <h4 class="modal-title">Enter Name for {{selectedWord}}</h4>
+ </modal-header>
+ <modal-body>
+ <div class="form-group row">
+ <label for="example-text-input" class="col-12 col-form-label">Name</label>
+ <div class="col-12">
+ <input class="form-control" [(ngModel)]="tempName" name="templateName" type="text" id="tempName">
+ <span class="error-message" [hidden]="checkNameEntered" style="color: red;">Required Field</span>
+ </div>
+ </div>
+ </modal-body>
+ <modal-footer [show-default-buttons]="false">
+ <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="submitNameValues()">Submit
+ </button>
+ </modal-footer>
+ </modal> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts
new file mode 100644
index 0000000..f26e5fd
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.spec.ts
@@ -0,0 +1,199 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+/* tslint:disable:no-unused-variable */
+import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
+import { By, BrowserModule } from '@angular/platform-browser';
+import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
+import { Component, OnInit, ViewChild, Input } from '@angular/core';
+//import { ModalComponent } from '../../modal/modal.component';
+import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service';
+import { MappingEditorService } from '../../../../shared/services/mapping-editor.service';
+import { ArtifactRequest } from '../../../../shared/models/index';
+import { ActivatedRoute, Router } from "@angular/router";
+import { saveAs } from "file-saver";
+import { NotificationService } from '../../../../shared/services/notification.service';
+import { NotificationsService } from "angular2-notifications"
+import { ParamShareService } from '../../../../shared/services/paramShare.service';
+import { DialogService } from "ng2-bootstrap-modal";
+import {ConfirmComponent} from '../../../../shared/confirmModal/confirm.component';
+import {BuildDesignComponent} from '../../build-artifacts.component';
+import { environment } from '../../../../../environments/environment';
+import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal'
+import { FormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+import { HomeComponent } from '../../../../home/home/home.component';
+import { LogoutComponent } from '../../../../shared/components/logout/logout.component';
+import { HelpComponent } from '../../../../shared/components/help/help/help.component';
+import { AboutUsComponent } from '../../../../about-us/aboutus.component';
+import { TestComponent } from '../../../../test/test.component';
+import { HttpModule } from '@angular/http';
+import { AceEditorComponent } from 'ng2-ace-editor';
+import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
+import { SimpleNotificationsModule } from 'angular2-notifications';
+import { GoldenConfigurationComponent } from './template-configuration.component';
+import { NgProgress } from 'ngx-progressbar';
+
+describe('GoldenConfigurationComponent', () => {
+ let component: GoldenConfigurationComponent;
+ let fixture: ComponentFixture<GoldenConfigurationComponent>;
+ let buildDesignComponent: BuildDesignComponent;
+ let paramShareService: ParamShareService;
+ let dialogService: DialogService;
+ let notificationService: NotificationService;
+ let httpUtil: HttpUtilService;
+ let mappingEditorService: MappingEditorService;
+ let activeRoutes: ActivatedRoute;
+ let router: Router;
+ let nService: NotificationsService
+ const routes = [
+ {
+ path: 'home',
+ component: HomeComponent
+ }, {
+ path: 'vnfs',
+ loadChildren: '../../../../vnfs/vnfs.module#VnfsModule'
+ }, {
+ path: 'test',
+ component: TestComponent
+ },
+ {
+ path: 'help',
+ component: HelpComponent
+ }, {
+ path: 'aboutUs',
+ component: AboutUsComponent
+ }, {
+ path: 'logout',
+ component: LogoutComponent
+ }, {
+ path: '',
+ redirectTo: '/home',
+ pathMatch: 'full'
+ }
+ ];
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [FormsModule, BrowserModule, RouterTestingModule.withRoutes(routes), HttpModule, Ng2Bs3ModalModule, SimpleNotificationsModule.forRoot()],
+ declarations: [GoldenConfigurationComponent, HomeComponent, TestComponent, HelpComponent, AboutUsComponent, LogoutComponent, AceEditorComponent],
+ providers: [BuildDesignComponent, NgProgress, ParamShareService, DialogService, NotificationService, HttpUtilService, MappingEditorService, NotificationsService],
+ schemas: [NO_ERRORS_SCHEMA],
+ })
+
+ });
+
+ beforeEach(async(() => {
+ TestBed.compileComponents()
+
+ }));
+
+
+ it('validate if uploaded file should be xml or json', () => {
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ expect(component.validateUploadedFile('xls')).toBe(false);
+ expect(component.validateUploadedFile('json')).toBe(true);
+ expect(component.validateUploadedFile('xml')).toBe(true);
+ });
+
+
+ it('validate initialisation of variables in ngOnit() function', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => {
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ mappingEditorService.latestAction = { "action": "Configure", "action-level": "vnf", "scope": { "vnf-type": "testVnf", "vnfc-type": "" }, "template": "Y", "vm": [], "device-protocol": "CHEF", "user-name": "", "port-number": "", "artifact-list": [{ "artifact-name": "template_Configure_test_0.0.1V.json", "artifact-type": "config_template" }, { "artifact-name": "pd_Configure_test_0.0.1V.yaml", "artifact-type": "parameter_definitions" }], "scopeType": "vnf-type" }
+
+ expect(component.ngOnInit());
+ expect(component.ngAfterViewInit());
+ expect(component.action).toEqual('Configure');
+ expect(component.vnfType).toEqual('testVnf');
+ expect(component.vnfcType).toEqual('');
+ expect(component.protocol).toEqual('CHEF');
+
+ expect(component.artifactName).toEqual('template_Configure_test_0.0.1V.json');
+
+ mappingEditorService.latestAction = { "action": "Configure", "action-level": "vnf", "scope": { "vnf-type": "testVnf", "vnfc-type": "testVnfc" }, "template": "Y", "vm": [], "device-protocol": "CHEF", "user-name": "", "port-number": "", "artifact-list": [{ "artifact-name": "template_Configure_test_0.0.1V.json", "artifact-type": "config_template" }, { "artifact-name": "pd_Configure_test_0.0.1V.yaml", "artifact-type": "parameter_definitions" }], "scopeType": "vnf-type" }
+ expect(component.ngOnInit());
+ expect(component.vnfcType).toEqual('testVnfc');
+
+
+ }));
+
+ it('check if variables are empty when reference data object is empty', inject([MappingEditorService], (mappingEditorService: MappingEditorService) => {
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ mappingEditorService.latestAction = { "action": "", "scope": { "vnf-type": "", "vnfc-type": "" }, "vm": [], "protocol": "", "download-dg-reference": "", "user-name": "", "port-number": "", "artifact-list": [], "deviceTemplate": "", "scopeType": "" };
+
+ expect(component.ngAfterViewInit());
+ expect(component.action).toEqual('');
+ expect(component.vnfType).toEqual('');
+ expect(component.vnfcType).toEqual('');
+ expect(component.protocol).toEqual('');
+ expect(component.artifactName).toEqual('');
+
+ }));
+
+ it('check if correct notification is fired while initialising if reference data object is undefined',()=>{
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ expect(component.ngAfterViewInit());
+ expect(component.Actions.length).toBe(0)
+ expect(component.enableBrowse).toBe(false)
+ });
+
+ it('test sync template when template data, param data and pd data are available', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ mappingEditorService.fromScreen === 'MappingScreen'
+ component.configMappingEditorContent="<configuration xmlns=\"http://xml.juniper.net/xnm/1.1/xnm\" \n xmlns:a=\"http://xml.juniper.net/junos/15.1X49/junos\" >\n <version>15.1X49-D50.3</version>\n <groups>\n <name>node0</name>\n <system>\n <tacplus-server>\n <name>${sync_auto-pop_name1}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n <tacplus-server>\n <name>${node0_tacplus_server_name2}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n </system> \n </groups>\n </configuration>"
+ mappingEditorService.initialise(component.templateeditor.getEditor(), component.configMappingEditorContent, component.modal);
+
+ var pdData=[{"name":"sync_auto-pop_name1","type":null,"description":null,"required":null,"default":null,"source":"A&AI","rule-type":"vnfc-oam-ipv4-address-list","request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":"unique-key-name","key-value":"parent-name"},{"key-name":"unique-key-value","key-value":"vnfc"},{"key-name":"field-key-name","key-value":"ipaddress-v4-oam-vip"},{"key-name":null,"key-value":"vm-number"},{"key-name":null,"key-value":"test"}],"ruleTypeValues":[null,"vnf-name","vm-name-list","vnfc-name-list","vnf-oam-ipv4-address","vnfc-oam-ipv4-address-list"],"showFilterFields":true,"enableFilterByValue":true},{"name":"sync_auto-pop_address1","type":null,"description":null,"required":null,"default":null,"source":"A&AI","rule-type":"vm-name-list","request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":"unique-key-name","key-value":"parent-name"},{"key-name":"unique-key-value","key-value":"vserver"},{"key-name":"field-key-name","key-value":"vserver-name"},{"key-name":null,"key-value":"vnfc-function-code"},{"key-name":null,"key-value":null}],"ruleTypeValues":[null,"vnf-name","vm-name-list","vnfc-name-list","vnf-oam-ipv4-address","vnfc-oam-ipv4-address-list"],"showFilterFields":true,"enableFilterByValue":true},{"name":"node0_tacplus_server_name2","type":null,"description":null,"required":null,"default":null,"source":"Manual","rule-type":null,"request-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"response-keys":[{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null},{"key-name":null,"key-value":null}],"ruleTypeValues":[null]}];
+ paramShareService.setSessionParamData([pdData]);
+ localStorage["paramsContent"]={
+ "sync_auto-pop_name1":"10.0.1.34",
+ "sync_auto-pop_address1":"",
+ "node0_tacplus_server_name2":"192.34.45.5"
+ };
+ expect(component.syncTemplate());
+
+
+ }));
+
+ it('test sync template when template data, param data and pd data are not available', inject([MappingEditorService, ParamShareService], (mappingEditorService: MappingEditorService, paramShareService:ParamShareService) => {
+ fixture = TestBed.createComponent(GoldenConfigurationComponent);
+ component = fixture.componentInstance;
+ mappingEditorService.fromScreen === 'MappingScreen'
+ component.configMappingEditorContent="<configuration xmlns=\"http://xml.juniper.net/xnm/1.1/xnm\" \n xmlns:a=\"http://xml.juniper.net/junos/15.1X49/junos\" >\n <version>15.1X49-D50.3</version>\n <groups>\n <name>node0</name>\n <system>\n <tacplus-server>\n <name>${sync_auto-pop_name1}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n <tacplus-server>\n <name>${node0_tacplus_server_name2}</name>\n <source-address>${sync_auto-pop_address1}</source-address>\n </tacplus-server>\n </system> \n </groups>\n </configuration>"
+ mappingEditorService.initialise(component.templateeditor.getEditor(), component.configMappingEditorContent, component.modal);
+
+ var pdData=[];
+ paramShareService.setSessionParamData([pdData]);
+ localStorage["paramsContent"]={};
+ expect(component.syncTemplate());
+
+
+ }));
+
+
+});
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts
new file mode 100644
index 0000000..8514e24
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-configuration/template-configuration.component.ts
@@ -0,0 +1,977 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
+//import { ModalComponent } from '../../modal/modal.component';
+import { HttpUtilService } from '../../../../shared/services/httpUtil/http-util.service';
+import { MappingEditorService } from '../../../../shared/services/mapping-editor.service';
+import { ArtifactRequest } from '../../../../shared/models/index';
+import { ActivatedRoute, Router } from '@angular/router';
+import { saveAs } from 'file-saver';
+import { NotificationService } from '../../../../shared/services/notification.service';
+import { NotificationsService } from 'angular2-notifications';
+import { ParamShareService } from '../../../../shared/services/paramShare.service';
+import { DialogService } from 'ng2-bootstrap-modal';
+import { ConfirmComponent } from '../../../../shared/confirmModal/confirm.component';
+import { BuildDesignComponent } from '../../build-artifacts.component';
+import { environment } from '../../../../../environments/environment';
+import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
+import { NgProgress } from 'ngx-progressbar';
+declare var $: any
+
+@Component({ selector: 'app-golden-configuration', templateUrl: './template-configuration.component.html', styleUrls: ['./template-configuration.component.css'] })
+export class GoldenConfigurationComponent implements OnInit {
+ @ViewChild('templateeditor') templateeditor;
+ @Input() configMappingEditorContent: string;
+ @Input() isMappingComp: boolean;
+ @ViewChild('myInput') myInputVariable: any;
+ // @ViewChild(ModalComponent) modalComponent: ModalComponent;
+ @ViewChild('myModal') modal: ModalComponent;
+ aceText: string = ""
+ fileName: string = ""
+ showTemplateVersionDiv: any;
+ downloadedTemplateFileName: any;
+ downloadedParamFileName: any;
+ templateVersionNo: any = '0.0.1';
+ saveToGuiCacheFlag = 'false';
+ initialAction: any;
+ public referenceData: Array<Object> = [];
+ public scopeName: any;
+ public subscription: any;
+ public item: any = {};
+ public goldenActions: Array<string> = [];
+ public refNameObj = {};
+ public action = '';
+ public artifactName = '';
+ public type;
+ public showError: boolean = false;
+ public tempretrieveFlag: boolean = false;
+ public fileNameForTempSave;
+ initialData: any;
+ showDownloadDiv: boolean = false;
+ downloadType: any;
+ enableBrowse: boolean = true;
+ enableMerge: boolean = false;
+ uploadValidationSuccess: boolean = false;
+ fileExtension: any = "xml";
+ apiToken = localStorage['apiToken'];
+ public appDataObject: any;
+ public downloadDataObject: any;
+ public checkNameEntered: boolean = true;
+ public selectedWord: any = this.mappingEditorService.getSelectedWord();
+ public Actions = [
+ { action: "ConfigBackup", value: "ConfigBackup" },
+ { action: "ConfigModify", value: "ConfigModify" },
+ { action: "ConfigRestore", value: "ConfigRestore" },
+ { action: "Configure", value: "Configure" },
+ { action: "GetRunningConfig", value: "GetRunningConfig" },
+ { action: "HealthCheck", value: "HealthCheck" },
+ { action: "StartApplication", value: "StartApplication" },
+ { action: "StopApplication", value: "StopApplication" }
+ ];
+ options = {
+ timeOut: 1000,
+ showProgressBar: true,
+ pauseOnHover: true,
+ clickToClose: true,
+ maxLength: 200
+ }
+ public enableDownloadButtons: boolean = false;
+ constructor(private buildDesignComponent: BuildDesignComponent, private paramShareService: ParamShareService, private dialogService: DialogService, private notificationService: NotificationService, private httpUtil: HttpUtilService, private mappingEditorService: MappingEditorService, private activeRoutes: ActivatedRoute, private router: Router, private nService: NotificationsService, private ngProgress: NgProgress) {
+ this.artifactRequest.action = '';
+ this.artifactRequest.version = '';
+ this.artifactRequest.paramsContent = '{}';
+ this.artifactRequest.paramKeysContent = '';
+ }
+ public templateEditor: any;
+ public fileType: any = '';
+ public actionType: any;
+ public myfileName: any;
+ userId = localStorage['userId'];
+ public artifactRequest: ArtifactRequest = new ArtifactRequest();
+ public showUploadStatus: boolean = false;
+ public uploadStatus: boolean = false;
+ public uploadTypes = [
+ {
+ value: 'Generated Template',
+ display: 'Sample Json Param File'
+ },
+ {
+ value: 'Mapping Data',
+ display: 'Sample Json Param File'
+ }
+ ];
+ vnfType: any = '';
+ vnfcType: any = '';
+ protocol: any = '';
+ refObj: any;
+ editor: any;
+ editorContent: any;
+ tempName: any;
+ enableValidateTemplate: boolean = false;;
+ public selectedUploadType: string = this.uploadTypes[0].value;
+ identifier: any;
+ //this.mappingeditorservice.referenceNameObjects = object;PLEASE USE THIS OBJECT TO GET TEMPALLDATA
+ //====================================================
+ ngOnInit() {
+ var refObj = this.refObj = this.prepareFileName();
+ // console.log("Ref object: " + JSON.stringify(refObj))
+ if (refObj && refObj != undefined) {
+ // refObj = refObj[refObj.length - 1];
+ this.item = refObj;
+
+ this.vnfType = this.item.scope["vnf-type"];
+ this.vnfcType = this.item.scope["vnfc-type"];
+ this.protocol = this.item['device-protocol'];
+ this.action = this.item.action;
+ this.artifactRequest.action = this.item.action;
+ this.artifactRequest.vnfType = this.vnfType;
+ if (this.vnfcType != undefined && this.vnfcType.length != 0) {
+ this.scopeName = this.vnfcType;
+ }
+ else {
+ this.scopeName = this.vnfType;
+ }
+ }
+ else {
+ this.item = { "action": "", "scope": { "vnf-type": "", "vnfc-type": "" }, "vm": [], "protocol": "", "download-dg-reference": "", "user-name": "", "port-number": "", "artifact-list": [], "deviceTemplate": "", "scopeType": "" };
+ }
+ this.initialAction = this.item.action;
+ this.activeRoutes.url.subscribe(UrlSegment => {
+ this.actionType = UrlSegment[0].path
+ })
+ /*if (this.actionType === 'createTemplate') {
+ this.mappingEditorService.fromScreen = 'TemplateScreen';
+ }
+ if (this.actionType === 'updateTemplate') {*/
+ this.mappingEditorService.fromScreen = 'MappingScreen';
+ // }
+ this.identifier = this.mappingEditorService.identifier;
+ }
+ //========================== End of ngOnInit() Method============================================
+ ngOnDestroy() {
+ //console.log("Reference object =="+ JSON.stringify(this.refObj));
+ if (this.refObj && this.refObj != undefined) {
+ if (this.configMappingEditorContent && this.configMappingEditorContent != undefined) {
+ this.saveTemplate();
+ this.prepareAppData();
+ this.prepareDownloadData();
+ this.mappingEditorService.changeNavAppData(this.appDataObject);
+ this.mappingEditorService.changeNavDownloadData(this.downloadDataObject);
+ }
+ }
+ }
+ //========================== End of ngOnDestroy() Method============================================
+ ngAfterViewInit() {
+ if (this.mappingEditorService.latestAction) {
+ this.refNameObj = this.mappingEditorService.latestAction;
+ if (this.vnfcType !== 'null') {
+ this.type = this.vnfcType;
+ }
+ else {
+ this.type = this.vnfType;
+ }
+ for (let i = 0; i < this.refNameObj['artifact-list'].length; i++) {
+ let artifactList = this.refNameObj['artifact-list'];
+ if (artifactList[i]['artifact-type'] === 'config_template') {
+ this.artifactName = artifactList[i]['artifact-name'];
+ }
+ }
+ }
+ let self = this;
+ this.templateEditor = self.templateeditor.getEditor();
+ /* this.templateeditor.getEditor().commands.addCommand({
+ name: 'annotateCommand',
+ bindKey: { win: 'Ctrl-4', mac: 'Command-4' },
+ exec: function (editor) {
+ self.mappingEditorService.checkMethodCall(this.modal);
+ }
+ });*/
+ this.templateeditor.getEditor().commands.addCommand({
+ name: 'annotateCommand',
+ bindKey: { win: 'ENTER', mac: 'ENTER' },
+ exec: (editor: any) => {
+ this.handleAnnotation(this.modal);
+ }
+ });
+ if (this.mappingEditorService.fromScreen === 'MappingScreen') {
+ this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore();
+ this.fileType = sessionStorage.getItem('fileType');
+ }
+ /* else if (this.mappingEditorService.fromScreen === 'TemplateScreen') {
+ this.configMappingEditorContent = this.mappingEditorService.getTemplateDataFromStore();
+ this.fileType = sessionStorage.getItem('fileType');
+ }*/
+ if (this.configMappingEditorContent) {
+ this.artifactRequest.templateContent = this.configMappingEditorContent;
+ this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
+ }
+ if (this.refObj) {
+ if (this.mappingEditorService.getTemplateMappingDataFromStore() && this.mappingEditorService.getTemplateMappingDataFromStore() != undefined) {
+ this.configMappingEditorContent = this.mappingEditorService.getTemplateMappingDataFromStore();
+ }
+ else {
+ if (this.artifactName) this.retrieveTemplateFromAppc();
+ }
+ }
+ else {
+ this.Actions = [];
+ this.enableBrowse = false;
+ this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
+ }
+ }
+
+ //========================== End of ngAfterViewInit() Method============================================
+ browseOption() {
+ $("#inputFile").trigger('click');
+ }
+ //========================== End of browseOption() Method============================================
+ /* openFile(event) {
+ let input = event.target;
+ this.fileName = event.currentTarget.value.replace(/C:\\fakepath\\/i, '');
+ for (let index = 0; index < input.files.length; index++) {
+ let reader = new FileReader();
+ reader.onload = () => {
+ this.configMappingEditorContent = reader.result;
+ }
+ reader.readAsText(input.files[index]);
+ };
+ }
+ //========================== End of openFile() Method============================================*/
+ //save to GUI
+ public saveTemplate() {
+ this.saveToGuiCacheFlag = 'true';
+ this.mappingEditorService.paramData = [];
+ if (this.configMappingEditorContent) {
+ this.initialData = this.configMappingEditorContent;
+ this.mappingEditorService.refreshEditor();
+ let paramArr: any = []
+ if (this.mappingEditorService.paramData && this.mappingEditorService.paramData != undefined) {
+ if (this.mappingEditorService.paramData.length === 0 && this.mappingEditorService.hasErrorCode === true) {
+ this.nService.error("Error", 'Special characters error', 'Error')
+ return;
+ }
+ else {
+ this.showError = false;
+ }
+ }
+ this.showTemplateVersionDiv = true;
+
+ if (this.mappingEditorService.fromScreen === 'MappingScreen') {
+ this.mappingEditorService.setTemplateMappingDataFromStore(this.configMappingEditorContent);
+ }
+ if (this.fileType === 'text/xml') {
+ sessionStorage.setItem('fileType', 'text/xml');
+ }
+ if (this.fileType === '') {
+ sessionStorage.setItem('fileType', '');
+ }
+ // paramArr = this.mappingEditorService.paramData;
+ // this.paramShareService.setTemplateData(paramArr)
+ }
+ }
+ //========================== End of saveTemplate() Method============================================
+ /* clearHighlight() {
+ this.mappingEditorService.removeTheSelectedMarkers();
+ }
+ //========================== End of clearHighlight() Method============================================*/
+ /*validateTemplate() {
+ var fileExtensionArr = this.fileType.split("/");
+ let data = {
+ "input": {
+ "design-request": {
+ "request-id": this.apiToken,
+ "action": "validateTemplate",
+ "data-type": fileExtensionArr[1].toUpperCase(),
+ "payload": this.configMappingEditorContent
+ }
+ }
+ };
+ let url = environment.validateTemplate;
+ this
+ .httpUtil
+ .post(
+ { url: url, data: data })
+ .subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === "success") {
+ this.uploadValidationSuccess = true;
+ this.nService.success("Success", "Template Validated succesfully");
+ return true;
+ }
+ else if (resp.output.status.code === '401') {
+ this.nService.error("Error", resp.output.status.message);
+ return false;
+ }
+ },
+ error => this.nService.error("Error", "Unable to validate the uploaded template. Error in connecting APPC Server"));
+ }
+ //========================== End of validateTemplate() Method============================================*/
+ retrieveTemplateFromAppc() {
+ let refObj = this.refObj;
+ if (refObj && refObj != undefined) {
+
+ let fileName = this.artifactName;
+ let payload = '{"userID": "' + this.userId + '","action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}';
+ let input = {
+ "input": {
+ "design-request": {
+ "request-id": this.apiToken,
+ "action": "getArtifact",
+ "payload": payload
+ }
+ }
+ };
+ // console.log("Retrieve artifact payload=="+ payload);
+ let artifactContent: any;
+ this.ngProgress.start();
+ this.httpUtil.post({
+ url: environment.getDesigns,
+ data: input
+ }).subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === "success") {
+ this.nService.success("Success", "Template retrieved successfully from APPC");
+ let result = JSON.parse(resp.output.data.block).artifactInfo[0];
+ result = result['artifact-content'];
+ if ('Generated Template' === this.selectedUploadType) {
+ this.configMappingEditorContent = result
+ this.artifactRequest.templateContent = this.configMappingEditorContent;
+ this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
+ if (this.artifactRequest.templateContent) {
+ this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
+ }
+ }
+ this.tempretrieveFlag = true;
+ this.fileNameForTempSave = fileName;
+ this.enableDownloadButtons = true;
+ this.initialData = result;
+ this.saveTemplate();
+ }
+ else {
+ this.nService.info("Information", "There is no template saved in APPC for the selected action!");
+ }
+ this.ngProgress.done();
+ },
+ /* (error) => {
+ // this.showUploadErrorStatus = true;
+ // this.nService.error('Status','Error Connecting to the APPC Network')
+ //this.notificationService.notifyErrorMessage('Configuration Template file successfully uploaded..')
+ //this.uploadStatusError = true;
+ //window.scrollTo(0, 0)
+ // this. nService.error('Status','Error Connecting to the APPC Network')
+ this.openModel(true, "Could not retrieve latest template for given action""Error in connecting to APPC database")
+ });*/
+ error => this.nService.error("Error", "Error in connecting to APPC Server"));
+ setTimeout(() => {
+ this.ngProgress.done();
+ }, 3500);
+ }
+ }
+ //========================== End of retrieveTemplateFromAppc() Method============================================
+ prepareAppData() {
+ let refObj = this.refObj;
+ //console.log("Reference object =="+ JSON.stringify(refObj));
+ if (refObj && refObj != undefined) {
+ // refObj = refObj[refObj.length - 1];
+ let paramsKeyValueFromEditor: JSON;
+ /* if (this.fileExtension.toUpperCase() === "XML")
+ paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent);
+ else*/
+ // paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent);
+ try {
+ paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]);
+ }
+ catch (error) {
+ console.log("Could not parse name value pairs==" + error);
+ }
+ if (paramsKeyValueFromEditor) {
+ this.showTemplateVersionDiv = true;
+ let action = this.item.action;
+ var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, '');
+ let fileName = this.updateParamFileName(refObj.action, scopeName, this.templateVersionNo);
+ let vnfType = this.vnfType;
+ let Json = [paramsKeyValueFromEditor];
+ let slashedPayload = this.appendSlashes(JSON.stringify(Json));
+ let newPayload =
+ {
+ "userID": this.userId,
+ "vnf-type": this.vnfType,
+ "action": action,
+ "artifact-name": fileName,
+ "artifact-type": "APPC-CONFIG",
+ "artifact-version": this.templateVersionNo,
+ "artifact-contents": slashedPayload
+ }
+ let data =
+ {
+ "input": {
+ "design-request": {
+ "request-id": this.apiToken,
+ "action": "uploadArtifact",
+ "payload": JSON.stringify(newPayload)
+
+ }
+ }
+ }
+ this.appDataObject.template.nameValueData = data;
+ }
+ if (this.configMappingEditorContent) {
+ let actualContent = this.configMappingEditorContent;
+ this.mappingEditorService.generateTemplate(this.templateEditor);
+ this.showTemplateVersionDiv = true;
+ let action = this.item.action;
+ let versionandFileType: any;
+ if (this.fileType === "text/xml") {
+
+ versionandFileType = this.templateVersionNo + 'V.xml'
+ } else {
+
+ versionandFileType = this.templateVersionNo + 'V.json'
+ }
+ let fileName: any;
+ if (this.tempretrieveFlag) {
+ fileName = this.fileNameForTempSave;
+ }
+ else {
+ // fileName = this.updateDownloadTemplateFileName(refObj.action, this.scopeName, versionandFileType);
+ fileName = this.artifactName;
+ }
+ let vnfType = this.vnfType;
+ let newPayload =
+ {
+ "userID": this.userId,
+ "vnf-type": this.vnfType,
+ "action": action,
+ "artifact-name": fileName,
+ "artifact-type": "APPC-CONFIG",
+ "artifact-version": this.templateVersionNo,
+ //"artifact-contents": this.configMappingEditorContent
+ "artifact-contents": this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}')
+
+ }
+ let data =
+ {
+ "input": {
+ "design-request": {
+ "request-id": this.apiToken,
+ "action": "uploadArtifact",
+ "payload": JSON.stringify(newPayload)
+
+ }
+ }
+ }
+ this.appDataObject.template.templateData = data;
+ this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal);
+ }
+ }
+ }
+ //========================== End of prepareAppData() Method============================================
+ /*retrieveNameValueFromAppc() {
+ let refObj: any = this.prepareFileName();
+ if (refObj && refObj != undefined) {
+ let fileName = this.updateParamFileName(this.item.action, this.scopeName, this.templateVersionNo);
+ let payload = '{"userID": "' + this.userId + '","action": "' + this.item.action + '", "vnf-type" : "' + this.vnfType + '", "artifact-type":"APPC-CONFIG", "artifact-name":"' + fileName + '"}';
+ let input = {
+ "input": {
+ "design-request": {
+ "request-id": this.apiToken,
+ "action": "getArtifact",
+ "payload": payload
+ }
+ }
+ };
+
+ let artifactContent: any;
+ this.httpUtil.post({
+ // url:"https://mtanjv9apdb51.aic.cip.att.com:8443/restconf/operations/design-services:dbservice",
+ url: environment.getDesigns,
+ data: input
+ }).subscribe(resp => {
+ if (resp.output.status.code === '400' && resp.output.status.message === "success") {
+ this.openModel(true, 'Name/value pairs retrieved successfully from APPC', 'Success');
+ let result = JSON.parse(resp.output.data.block).artifactInfo[0];
+ result = JSON.parse(result['artifact-content']);
+ var jsonString = JSON.stringify(result[0]);
+ var string = jsonString.substring(1, jsonString.length - 1);
+ var stringArr = string.split(",");
+ var newStringArr = [];
+ var resultStr = "{\r\n"
+ for (var index in stringArr) {
+ newStringArr[index] = stringArr[index] + ",\r\n";
+ }
+ for (var index in newStringArr) {
+ resultStr = resultStr + newStringArr[index];
+ }
+ resultStr = resultStr.substring(0, resultStr.length - 3) + "\r\n}"
+ this.configMappingEditorContent = resultStr;
+
+ }
+ },
+ error => this.openModel(true, "Could not retrieve the name value pairs. Error in connecting to APPC Server", "ERROR"));
+ }
+ }*/
+ //========================== End of retrieveNameValueFromAppc() Method============================================
+ prepareFileName(): any {
+ let fileNameObject: any = this.mappingEditorService.latestAction;
+ this.appDataObject = this.mappingEditorService.appDataObject;
+ this.downloadDataObject = this.mappingEditorService.downloadDataObject;
+ this.referenceData = fileNameObject;
+ return fileNameObject;
+ }
+ //========================== End of prepareFileName() Method============================================
+ onDownloadParameter() {
+ let refObj = this.refObj;
+ if (refObj) {
+ // refObj = refObj[refObj.length - 1];
+ let paramsKeyValueFromEditor: JSON;
+ if (this.fileExtension.toUpperCase() === "XML")
+ paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent);
+ else
+ paramsKeyValueFromEditor = this.mappingEditorService.generateParams(this.templateeditor.getEditor(), this.artifactRequest.templateContent);
+
+ try {
+ paramsKeyValueFromEditor = JSON.parse(localStorage["paramsContent"]);
+ }
+ catch (error) {
+ console.log("Could not parse name value pairs==" + error);
+ }
+ let theJSON = JSON.stringify(paramsKeyValueFromEditor, null, "\t")
+ var blob = new Blob([theJSON], {
+ type: "text/json"
+ });
+ this.showTemplateVersionDiv = true;
+ let fileName: any;
+ var scopeName = this.scopeName.replace(/ /g, '').replace(new RegExp('/', "g"), '_').replace(/ /g, '');
+ fileName = this.updateParamFileName(refObj.action, scopeName, this.templateVersionNo);
+ this.downloadDataObject.template.nameValueData = theJSON;
+ this.downloadDataObject.template.nameValueFileName = fileName;
+ }
+ else {
+ this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
+ }
+
+ }
+ //========================== End of onDownloadParameter() Method============================================
+ /* JSONToCSVConvertor(JSONData, fileName, ShowLabel) {
+ //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
+ var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
+ var CSV = '';
+ //This condition will generate the Label/Header
+ if (ShowLabel) {
+ var testRow = "";
+ for (var index in arrData[0]) {
+ CSV += index + '\t' + arrData[0][index] + '\r\n';
+ }
+ }
+ if (CSV == '') {
+ return;
+ }
+ //Initialize file format you want csv or xls
+ var uri = 'data:application/vnd.ms-excel,' + encodeURI(CSV);
+ var link = document.createElement("a");
+ link.href = uri;
+ link.download = fileName + ".xls";
+ //this part will append the anchor tag and remove it after automatic click
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+ //========================== End of JSONToCSVConvertor() Method============================================
+ updateParamFileNameForXls(action: any, scopeName: any, versionNo: any) {
+ let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V';
+ this.downloadedParamFileName = fileName;
+ return fileName;
+ }
+ //========================== End of updateParamFileNameForXls() Method============================================*/
+ updateParamFileName(action: any, scopeName: any, versionNo: any) {
+ let fileName = 'param_' + action + '_' + scopeName + '_' + versionNo + 'V.json';
+ this.downloadedParamFileName = fileName;
+ return fileName;
+ }
+ //========================== End of updateParamFileName() Method============================================
+ public onDownloadTemplate(artifact: string) {
+ let actualContent = this.configMappingEditorContent;
+ var textToSaveAsBlob: any;
+ var config_template_fileName: any
+ let refObj = this.refObj;
+ let versionandFileType: string;
+ this.mappingEditorService.generateTemplate(this.templateEditor);
+ if (artifact == 'Template' && this.artifactRequest && this.configMappingEditorContent && refObj) {
+ // refObj = refObj[refObj.length - 1];
+ this.showTemplateVersionDiv = true;
+ if (this.fileType === "text/xml") {
+ textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
+ type: "text/xml"
+ });
+ versionandFileType = this.templateVersionNo + 'V.xml'
+ }
+ if (this.fileType === "text/plain") {
+ textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
+ type: "text/plain"
+ });
+ versionandFileType = this.templateVersionNo + 'V.txt'
+ }
+ if (this.fileType === "text/json") {
+ textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
+ type: "text/json"
+ });
+ versionandFileType = this.templateVersionNo + 'V.json'
+ }
+ if (this.tempretrieveFlag) {
+ config_template_fileName = this.fileNameForTempSave;
+ var filextension = config_template_fileName.substring(config_template_fileName.indexOf("V") + 2, config_template_fileName.length);
+
+ textToSaveAsBlob = new Blob([this.configMappingEditorContent], {
+ type: "text/" + filextension
+ });
+ }
+ else {
+ // config_template_fileName = this.updateDownloadTemplateFileName(refObj.action, this.scopeName, versionandFileType);
+ config_template_fileName = this.artifactName;
+ }
+ // saveAs(textToSaveAsBlob, config_template_fileName);
+ this.mappingEditorService.initialise(this.templateeditor.getEditor(), actualContent, this.modal);
+ //this.downloadDataObject.template.templateData = this.configMappingEditorContent;
+ this.downloadDataObject.template.templateData = this.configMappingEditorContent.replace(/\(([^()]|(R))*\)=\(/g, '').replace(/\)}/g, '}');
+ this.downloadDataObject.template.templateFileName = config_template_fileName;
+ }
+
+ }
+ //========================== End of onDownloadTemplate() Method============================================
+ updateDownloadTemplateFileName(action: any, scopeName: any, versionandFileType: any) {
+ let fileName = 'template_' + action + '_' + scopeName + '_' + versionandFileType;
+ this.downloadedTemplateFileName = fileName;
+ return fileName;
+ }
+ //========================== End of updateDownloadTemplateFileName() Method============================================
+ /* openModel(toShow: any, message: any, title: any) {
+ //this.modalComponent.isShow = toShow;
+ //this.modalComponent.message = message;
+ //this.modalComponent.title = title;
+ }
+ //========================== End of openModel() Method============================================*/
+ fileChange(input) {
+
+ let self = this;
+ let refObj = this.refObj;
+ this.enableValidateTemplate = true;
+
+ if (refObj && refObj != undefined) {
+ // refObj = refObj[refObj.length - 1];
+ if (input.files && input.files[0]) {
+ console.log("input files0" + JSON.stringify(input.files[0]))
+ this.myfileName = input.files[0].name;
+ this.fileName = input.files[0].name;
+ this.fileType = input.files[0].type;
+ // var fileExtension = this.myfileName.substr(this.myfileName.lastIndexOf('.') + 1);
+
+ let reader = new FileReader();
+ // if(this.validateUploadedFile(fileExtension))
+ //{
+ this.readFile(input.files[0], reader, (result) => {
+ if (this.fileType === 'text/xml') {
+ sessionStorage.setItem('fileType', 'text/xml');
+ }
+ if (this.fileName.endsWith(".json")) {
+ this.fileType = "text/json";
+ sessionStorage.setItem('fileType', 'text/json');
+ }
+ if (this.fileType === '') {
+ sessionStorage.setItem('fileType', '');
+ }
+
+
+ if ('Generated Template' === this.selectedUploadType) {
+ this.configMappingEditorContent = result
+ this.artifactRequest.templateContent = this.configMappingEditorContent;
+ console.log("editor content==" + JSON.stringify(this.configMappingEditorContent))
+ this.notificationService.notifySuccessMessage('Configuration Template file successfully uploaded..');
+ if (this.artifactRequest.templateContent) {
+ this.mappingEditorService.initialise(this.templateeditor.getEditor(), this.artifactRequest.templateContent, this.modal);
+ }
+ }
+ this.enableDownloadButtons = true;
+ this.initialData = result;
+ this.saveTemplate();
+
+ });
+ // }
+ // else{
+ // this.nService.error("Error", "Incorrect File Format")
+ //this.configMappingEditorContent=''
+ //}
+ }
+ else {
+ this.nService.error("Error", "Failed to read file");
+ }
+ this.myInputVariable.nativeElement.value = "";
+ }
+ else {
+ this.nService.error("Error", "Please enter Action and VNF type in Reference Data screen");
+ return false;
+ }
+ }
+ //========================== End of fileChange() Method============================================
+ public readFile(file, reader, callback) {
+ // Set a callback funtion to fire after the file is fully loaded
+ reader.onload = () => {
+ // callback with the results
+ callback(reader.result);
+ }
+ this.notificationService.notifySuccessMessage('Uploading File ' + file.name + ':' + file.type + ':' + file.size);
+ // Read the file
+ reader.readAsText(file, "UTF-8");
+ }
+ //========================== End of readFile() Method============================================
+ validateUploadedFile(fileExtension) {
+
+ if (fileExtension.toUpperCase() === 'json'.toUpperCase() || fileExtension.toUpperCase() === 'xml'.toUpperCase()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ }
+ //========================== End of validateUploadedFile() Method============================================
+ appendSlashes(artifactData) {
+ let x = artifactData.replace(new RegExp(',"', "g"), ',\"');
+ let y = x.replace(new RegExp('":', 'g'), '\":');
+ let z = y.replace(new RegExp('{"', 'g'), '{\"')
+ let t = z.replace(new RegExp(':"', 'g'), ':\"')
+ let m = t.replace(new RegExp('",', 'g'), '\",');
+ let n = y.replace(new RegExp('"}', 'g'), '\"}')
+ let nw = n.replace(new RegExp('{"', 'g'), '{\"');
+ let nw1 = nw.replace(new RegExp(':"', 'g'), ':\"');
+ let nw2 = nw1.replace(new RegExp('",', 'g'), '\",');
+ return nw2;
+ }
+ //========================== End of appendSlashes() Method============================================
+ prepareDownloadData() {
+ this.onDownloadParameter();
+ this.onDownloadTemplate('Template');
+ }
+ //========================== End of prepareDownloadData() Method============================================
+ syncTemplate() {
+ this.mappingEditorService.replaceNamesWithBlankValues();
+ this.saveTemplate();
+
+ var templateData = this.mappingEditorService.paramData; //template data array
+ // this.paramShareService.setTemplateData(templateData);
+
+ //console.log("Template Name value pairs ===" + JSON.stringify(templateData))
+ var pdData = this.paramShareService.getSessionParamData(); //PD data array
+ console.log("PD name value pairs===" + JSON.stringify(pdData))
+
+
+ var paramsContent = localStorage["paramsContent"];
+ console.log("Param content before==" + paramsContent);
+
+ if (paramsContent && paramsContent != undefined) {
+ try {
+ var paramTabData = JSON.parse(paramsContent);
+ //console.log("Param content after==" + paramsContent);
+ //console.log("Param tab data after==" + JSON.stringify(paramTabData))
+ }
+ catch (error) {
+ console.log("error is : " + error)
+ }
+ }
+ var resultArr = [];
+ var json = {};
+ var resultParamObj = {};
+ let checkNamesOnlyCondition: boolean = true;
+
+ if (templateData && templateData != undefined) {
+ templateData.forEach(function (item) {
+ if (item.paramValue !== "" && item.paramValue != undefined && item.paramValue != null) {
+ checkNamesOnlyCondition = false;
+ }
+
+ });
+
+ templateData.forEach(function (item) {
+ resultParamObj[item.paramName] = item.paramValue;
+ });
+ // console.log("pARAM Result array before is " + JSON.stringify(resultParamObj))
+ if (paramTabData && paramTabData != undefined) {
+ templateData.forEach(function (item) {
+ for (var index in paramTabData) {
+ if (item.paramName === index) {
+ if (checkNamesOnlyCondition) {
+ resultParamObj[index] = paramTabData[index];
+ }
+ else {
+ if (item.paramValue === "") {
+ resultParamObj[index] = paramTabData[index];
+ }
+ else {
+ resultParamObj[index] = item.paramValue;
+ }
+ }
+ }
+
+ }
+
+ });
+
+ }
+ localStorage["paramsContent"] = JSON.stringify(resultParamObj);
+ //console.log("param content after==" +JSON.stringify(resultParamObj));
+
+ //removing duplicate elements from the array
+ templateData = Array.from(new Set(templateData.map((itemInArray) => itemInArray.paramName)))
+
+ //reformatting arr1 to match with PD
+ templateData.forEach(function (item) {
+
+ resultArr.push({
+ "name": item,
+ "type": null,
+ "description": null,
+ "required": null,
+ "default": null,
+ "source": "Manual",
+ "rule-type": null,
+ "request-keys": [{
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }],
+ "response-keys": [{
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }, {
+ "key-name": null,
+ "key-value": null
+ }],
+ "ruleTypeValues": [null]
+
+ })
+ });
+ }
+ //console.log("Result array before is " + JSON.stringify(resultArr))
+ // console.log("Length before is: " + resultArr.length)
+
+ if (pdData && pdData != undefined) {
+ for (var i = 0; i < resultArr.length; i++) {
+
+ pdData.forEach(function (arr2item) {
+ if (resultArr[i].name === arr2item.name) {
+
+ var json = {
+ "name": arr2item.name,
+ "type": arr2item.type,
+ "description": arr2item.description,
+ "required": arr2item.required,
+ "default": arr2item.default,
+ "source": arr2item.source,
+ "rule-type": arr2item["rule-type"],
+ "request-keys": arr2item["request-keys"],
+ "response-keys": arr2item["response-keys"],
+ "ruleTypeValues": arr2item.ruleTypeValues
+ };
+ resultArr.splice(i, 1, json)
+ // console.log("Result array index ==" + JSON.stringify(resultArr[i]))
+ }
+
+ });
+
+ };
+
+ }
+ this.paramShareService.setSessionParamData(resultArr);
+ //console.log("Result array after is " + JSON.stringify(resultArr))
+ //console.log("Length after is: " + resultArr.length)
+ this.mappingEditorService.paramData = [];
+ //navigate to PD page after sync
+ this
+ .router
+ .navigate(['../../../vnfs/design/parameterDefinitions/create']);
+ }
+
+ //========================== End of syncTemplate() Method============================================
+ mergeParams() {
+ var mergeStatus: boolean = this.mappingEditorService.autoAnnotateDataForParams(this.fileType);
+ if (mergeStatus) {
+ this.nService.success("Success", "Merge Successful");
+ }
+ else {
+ this.nService.error("Error", "Merge Unsuccessful");
+ }
+ this.saveTemplate();
+ }
+ //========================== End of mergeParams() Method============================================
+ public handleAnnotation(modal) {
+
+ let selectedWord: string = this.templateeditor.getEditor().session.getTextRange(this.templateeditor.getEditor().selectionRange);
+ this.selectedWord = selectedWord;
+ modal.open();
+ }
+ //========================== End of handleAnnotations() Method============================================
+ public submitNameValues() {
+ /*var editor = this.templateeditor.getEditor()
+ this.editor = editor;
+ this.editor.session = editor.session;
+ this.editor.selection.session.$backMarkers = {};
+ this.editorContent = this.artifactRequest.templateContent;
+ this.editor.$blockScrolling = Infinity;
+ this.editor.$blockSelectEnabled = false;*/
+ if (this.tempName) {
+ this.checkNameEntered = true;
+
+ if (this.selectedWord) {
+ if (this.selectedWord.startsWith('${(')) {
+ var replaceWord: any = this.selectedWord.substring(3, this.selectedWord.indexOf(')=(')) + this.tempName;
+ this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord);
+ } else {
+ let mappingKey = this.mappingEditorService.getKeysForValues(this.selectedWord);
+ var replaceWord: any = '${(' + this.selectedWord + ')=(' + this.tempName + ')}';
+ this.templateeditor.getEditor().session.replace(this.templateeditor.getEditor().session.selection.getRange(), replaceWord);
+ }
+ }
+ this.mappingEditorService.refreshEditor();
+ this.tempName = '';
+ this.modal.close();
+
+ }
+ else {
+ this.checkNameEntered = false;
+ }
+
+ }
+ //========================== End of submitNameValues() Method============================================
+}
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css
new file mode 100644
index 0000000..7c075eb
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.css
@@ -0,0 +1,22 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/ \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html
new file mode 100644
index 0000000..6668ed1
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.html
@@ -0,0 +1,24 @@
+<!--
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+-->
+
+<router-outlet></router-outlet> \ No newline at end of file
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts
new file mode 100644
index 0000000..22c71d1
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.spec.ts
@@ -0,0 +1,49 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+/* tslint:disable:no-unused-variable */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {GoldenConfigurationHolderComponent} from './template-holder.component';
+
+describe('GoldenConfigurationHolderComponent', () => {
+ let component: GoldenConfigurationHolderComponent;
+ let fixture: ComponentFixture<GoldenConfigurationHolderComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [GoldenConfigurationHolderComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(GoldenConfigurationHolderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts
new file mode 100644
index 0000000..33bed31
--- /dev/null
+++ b/src/app/vnfs/build-artifacts/template-holder/template-holder.component.ts
@@ -0,0 +1,39 @@
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018 AT&T 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.
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
+============LICENSE_END============================================
+*/
+
+import {Component, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-golden-configuration-holder',
+ templateUrl: './template-holder.component.html',
+ styleUrls: ['./template-holder.component.css']
+})
+export class GoldenConfigurationHolderComponent implements OnInit {
+
+ constructor() {
+ }
+
+ ngOnInit() {
+ }
+
+}