Add UI support for adding tosca artifact types 79/125379/5
authoraribeiro <anderson.ribeiro@est.tech>
Fri, 1 Oct 2021 10:30:49 +0000 (11:30 +0100)
committerAndr� Schmid <andre.schmid@est.tech>
Fri, 5 Nov 2021 17:14:06 +0000 (17:14 +0000)
UI support for adding artifacts to an interface operation implementation

Issue-ID: SDC-3768
Signed-off-by: aribeiro <anderson.ribeiro@est.tech>
Change-Id: I71b3e49a160521e35a45515ad7adef836f901e78

28 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaArtifactDefinition.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceOperationImplementation.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaLifecycleOperationDefinition.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaOperationAssignment.java
catalog-be/src/test/java/org/openecomp/sdc/be/tosca/builder/ToscaRelationshipBuilderTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaLifecycleOperationDefinitionTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/OperationUi.java
catalog-ui/src/app/models/artifacts.ts
catalog-ui/src/app/models/interfaceOperation.ts
catalog-ui/src/app/models/toscaArtifact.ts [new file with mode: 0644]
catalog-ui/src/app/modules/service-module.ts
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
catalog-ui/src/app/ng2/services/tosca-artifact.service.ts [new file with mode: 0644]
catalog-ui/src/assets/languages/en_US.json
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ArtifactDataDefinition.java

index e73ade1..9eaf1ee 100644 (file)
@@ -175,7 +175,7 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic
     }
 
     private void updateOperationDefinitionImplementation(final OperationDataDefinition updatedOperationDataDefinition) {
-        final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition();
+        final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition(updatedOperationDataDefinition.getImplementation());
         artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName()));
         updatedOperationDataDefinition.setImplementation(artifactInfo);
     }
index 438ad5b..52e7562 100644 (file)
@@ -32,10 +32,13 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
@@ -43,9 +46,11 @@ import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Product;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
+import org.openecomp.sdc.be.tosca.model.ToscaArtifactDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaInput;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType;
+import org.openecomp.sdc.be.tosca.model.ToscaInterfaceOperationImplementation;
 import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
@@ -285,12 +290,32 @@ public class InterfacesOperationsConverter {
                                                         final Entry<String, OperationDataDefinition> operationEntry,
                                                         final ToscaLifecycleOperationDefinition toscaOperation) {
         final String operationArtifactPath;
+        final ToscaInterfaceOperationImplementation toscaInterfaceOperationImplementation = new ToscaInterfaceOperationImplementation();
+        toscaInterfaceOperationImplementation.setPrimary(new ToscaArtifactDefinition());
+        final ToscaArtifactDefinition toscaArtifactDefinition = toscaInterfaceOperationImplementation.getPrimary();
         if (isArtifactPresent(operationEntry) && StringUtils.isNotEmpty(operationEntry.getValue().getImplementation().getArtifactName())) {
             operationArtifactPath = OperationArtifactUtil
                 .createOperationArtifactPath(component, componentInstance, operationEntry.getValue(), isAssociatedComponent);
-            toscaOperation.setImplementation(operationArtifactPath);
+            toscaArtifactDefinition.setFile(operationArtifactPath);
+            toscaArtifactDefinition.setArtifact_version(!operationEntry.getValue().getImplementation().getArtifactVersion()
+                .equals(NumberUtils.INTEGER_ZERO.toString()) ? operationEntry.getValue().getImplementation().getArtifactVersion() : null);
+            toscaArtifactDefinition.setType(operationEntry.getValue().getImplementation().getArtifactType());
+            handleInterfaceOperationImplementationProperties(operationEntry, toscaArtifactDefinition);
+            toscaOperation.setImplementation(
+                toscaArtifactDefinition.getType() != null ? toscaInterfaceOperationImplementation : operationArtifactPath);
         } else {
-            toscaOperation.setImplementation(operationEntry.getValue().getImplementation().getArtifactName());
+            toscaArtifactDefinition.setFile(operationEntry.getValue().getImplementation().getArtifactName());
+            toscaOperation.setImplementation(toscaInterfaceOperationImplementation);
+        }
+    }
+
+    private void handleInterfaceOperationImplementationProperties(final Entry<String, OperationDataDefinition> operationEntry,
+                                                                  final ToscaArtifactDefinition toscaArtifactDefinition) {
+        final var properties = operationEntry.getValue().getImplementation().getProperties();
+        if (CollectionUtils.isNotEmpty(properties)) {
+            final Map<String, PropertyDataDefinition> propertiesMap = new HashMap<>();
+            properties.forEach(propertyDefinition -> propertiesMap.put(propertyDefinition.getName(), propertyDefinition));
+            toscaArtifactDefinition.setProperties(propertiesMap);
         }
     }
 
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaArtifactDefinition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaArtifactDefinition.java
new file mode 100644 (file)
index 0000000..f49d047
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.tosca.model;
+
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+
+@Getter
+@Setter
+public class ToscaArtifactDefinition {
+
+    private String type;
+    private String file;
+    private String repository;
+    private String description;
+    private String deploy_path;
+    private String artifact_version;
+    private String checksum;
+    private String checksum_algorithm;
+    private Map<String, PropertyDataDefinition> properties;
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceOperationImplementation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceOperationImplementation.java
new file mode 100644 (file)
index 0000000..270bd72
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.tosca.model;
+
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+
+@Getter
+@Setter
+public class ToscaInterfaceOperationImplementation {
+
+    private ToscaArtifactDefinition primary;
+    private List<ArtifactDataDefinition> dependencies;
+    private Integer timeout;
+    private String operation_host;
+}
index f35cab2..575c025 100644 (file)
 package org.openecomp.sdc.be.tosca.model;
 
 import java.util.Map;
-import java.util.Objects;
+import lombok.Data;
 
 /**
  * @author KATYR
  * @since March 26, 2018
  */
+@Data
 public class ToscaLifecycleOperationDefinition {
 
     private String description;
-    private String implementation;
+    private Object implementation;
     private Map<String, ToscaProperty> inputs;
 
-    public String getImplementation() {
-        return implementation;
-    }
-
-    public void setImplementation(String implementation) {
-        this.implementation = implementation;
-    }
-
-    public Map<String, ToscaProperty> getInputs() {
-        return inputs;
-    }
-
-    public void setInputs(Map<String, ToscaProperty> inputs) {
-        this.inputs = inputs;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        ToscaLifecycleOperationDefinition that = (ToscaLifecycleOperationDefinition) o;
-        return Objects.equals(implementation, that.implementation) && Objects.equals(inputs, that.inputs);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(implementation, inputs);
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
 }
index d7f918d..23e50cf 100644 (file)
@@ -27,6 +27,6 @@ import lombok.Setter;
 public class ToscaOperationAssignment {
 
     private String description;
-    private String implementation;
+    private Object implementation;
     private Map<String, ToscaPropertyAssignment> inputs;
 }
index cee7066..a5008b3 100644 (file)
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import org.junit.jupiter.api.Test;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
 import org.openecomp.sdc.be.model.RelationshipImpl;
 import org.openecomp.sdc.be.model.RelationshipInfo;
@@ -55,13 +56,13 @@ class ToscaRelationshipBuilderTest {
         final OperationUi operationUi1 = new OperationUi();
         operationUi1.setInterfaceType("interfaceType1");
         operationUi1.setOperationType("operation1");
-        operationUi1.setImplementation("implementation");
+        operationUi1.setImplementation(new ArtifactDataDefinition());
         operationList.add(operationUi1);
 
         final OperationUi operationUi2 = new OperationUi();
         operationUi2.setInterfaceType("interfaceType1");
         operationUi2.setOperationType("operation2");
-        operationUi2.setImplementation("implementation");
+        operationUi2.setImplementation(new ArtifactDataDefinition());
         operationList.add(operationUi2);
         final List<PropertyAssignmentUi> operation2InputList = new ArrayList<>();
         final PropertyAssignmentUi propertyAssignmentUi1 = new PropertyAssignmentUi();
@@ -79,7 +80,7 @@ class ToscaRelationshipBuilderTest {
         final OperationUi operationUi3 = new OperationUi();
         operationUi3.setInterfaceType("interfaceType2");
         operationUi3.setOperationType("operation1");
-        operationUi3.setImplementation("implementation");
+        operationUi3.setImplementation(new ArtifactDataDefinition());
         operationList.add(operationUi3);
 
         relationship.setOperations(operationList);
index 054a6cf..7d5e957 100644 (file)
 
 package org.openecomp.sdc.be.tosca.model;
 
+import java.util.Map;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.Map;
-
 public class ToscaLifecycleOperationDefinitionTest {
 
        private ToscaLifecycleOperationDefinition createTestSubject() {
@@ -34,7 +33,7 @@ public class ToscaLifecycleOperationDefinitionTest {
        @Test
        public void testGetImplementation() throws Exception {
                ToscaLifecycleOperationDefinition testSubject;
-               String result;
+               Object result;
 
                // default test
                testSubject = createTestSubject();
@@ -44,11 +43,10 @@ public class ToscaLifecycleOperationDefinitionTest {
        @Test
        public void testSetImplementation() throws Exception {
                ToscaLifecycleOperationDefinition testSubject;
-               String implementation = "";
 
                // default test
                testSubject = createTestSubject();
-               testSubject.setImplementation(implementation);
+               testSubject.setImplementation(new ToscaInterfaceOperationImplementation());
        }
 
        @Test
index 9db61e8..0e7b9f0 100644 (file)
@@ -1718,9 +1718,9 @@ public class NodeTemplateOperation extends BaseOperation {
         final OperationDataDefinition operationDataDefinition = new OperationDataDefinition();
         operationDataDefinition.setName(operation.getOperationType());
         operationDataDefinition.setUniqueId(UUID.randomUUID().toString());
-        final ArtifactDataDefinition implementation = new ArtifactDataDefinition();
-        implementation.setArtifactName(operation.getImplementation());
-        operationDataDefinition.setImplementation(implementation);
+        final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition();
+        artifactDataDefinition.setArtifactName((String) operation.getImplementation());
+        operationDataDefinition.setImplementation(artifactDataDefinition);
         if (CollectionUtils.isNotEmpty(operation.getInputs())) {
             final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
             operation.getInputs().forEach(input -> {
index 9efef3b..16d225a 100644 (file)
@@ -425,9 +425,9 @@ public class ModelConverter {
                 operationUi.setOperationType(operationEntry.getKey());
                 operationUi.setInterfaceType(interfaceDataDefinition.getType());
                 final OperationDataDefinition operationDataDefinition = operationEntry.getValue();
-                final ArtifactDataDefinition implementation = operationDataDefinition.getImplementation();
-                if (implementation != null) {
-                    operationUi.setImplementation(implementation.getArtifactName());
+                final ArtifactDataDefinition artifactDataDefinition = operationDataDefinition.getImplementation();
+                if (artifactDataDefinition != null) {
+                    operationUi.setImplementation(artifactDataDefinition);
                 }
                 final ListDataDefinition<OperationInputDefinition> inputs = operationDataDefinition.getInputs();
                 if (inputs != null && !inputs.isEmpty()) {
index d80e1cb..1f63b4c 100644 (file)
@@ -29,7 +29,7 @@ public class OperationUi {
 
     private String interfaceType;
     private String operationType;
-    private String implementation;
+    private Object implementation;
     private List<PropertyAssignmentUi> inputs;
 
     public void addToInputs(final PropertyAssignmentUi input) {
index e290dc6..e6e76e0 100644 (file)
@@ -24,6 +24,7 @@
 import * as _ from "lodash";
 import {ArtifactType} from './../utils';
 import {HeatParameterModel} from "./heat-parameters";
+import {PropertyBEModel} from "./properties-inputs/property-be-model";
 
 //this object contains keys, each key contain ArtifactModel
 export class ArtifactGroupModel {
@@ -76,6 +77,7 @@ export class ArtifactModel {
     originalDescription:string;
     envArtifact:ArtifactModel;
     allowDeleteAndUpdate: boolean;
+    properties:Array<PropertyBEModel>;
 
     constructor(artifact?:ArtifactModel) {
         if (artifact) {
@@ -104,6 +106,7 @@ export class ArtifactModel {
             this.selected = artifact.selected ? artifact.selected : false;
             this.originalDescription = artifact.description;
             this.isFromCsar = artifact.isFromCsar;
+            this.properties = _.sortBy(_.cloneDeep(artifact.properties), 'name');
         }
     }
 
index 5c69688..109babb 100644 (file)
@@ -19,6 +19,8 @@
 
 'use strict';
 
+import {ArtifactModel} from "./artifacts";
+
 export class InputOperationParameter {
     name: string;
     type: string;
@@ -36,6 +38,22 @@ export class InputOperationParameter {
     }
 }
 
+export class PropertyOperationParameter {
+    name: string;
+    type: string;
+    value?: string;
+    propertyId: string;
+
+    constructor(param?: any) {
+        if (param) {
+            this.name = param.name;
+            this.type = param.type;
+            this.value = param.value;
+            this.propertyId = param.propertyId;
+        }
+    }
+}
+
 export interface IOperationParamsList {
     listToscaDataDefinition: Array<InputOperationParameter>;
 }
@@ -45,7 +63,7 @@ export class BEInterfaceOperationModel {
     description: string;
     uniqueId: string;
     inputs: IOperationParamsList;
-    implementation?: InterfaceOperationImplementation;
+    implementation: ArtifactModel;
 
     constructor(operation?: any) {
         if (operation) {
@@ -64,8 +82,8 @@ export class InterfaceOperationModel extends BEInterfaceOperationModel {
     operationType: string;
     description: string;
     uniqueId: string;
-    implementation?: InterfaceOperationImplementation;
     inputParams: IOperationParamsList;
+    implementation: ArtifactModel;
 
     constructor(operation?: any) {
         super(operation);
@@ -76,6 +94,7 @@ export class InterfaceOperationModel extends BEInterfaceOperationModel {
             this.operationType = operation.operationType;
             this.uniqueId = operation.uniqueId;
             this.inputParams = operation.inputParams;
+            this.implementation = operation.implementation;
         }
     }
 
@@ -84,10 +103,6 @@ export class InterfaceOperationModel extends BEInterfaceOperationModel {
     }
 }
 
-export class InterfaceOperationImplementation {
-    artifactName: string;
-}
-
 export class ComponentInstanceInterfaceModel {
     type: string;
     uniqueId: string;
diff --git a/catalog-ui/src/app/models/toscaArtifact.ts b/catalog-ui/src/app/models/toscaArtifact.ts
new file mode 100644 (file)
index 0000000..eb87728
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+* ============LICENSE_START=======================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file 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.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+
+import {PropertyBEModel} from "./properties-inputs/property-be-model";
+
+export class ToscaArtifactModel {
+  type: string;
+  file: string;
+  repository: string
+  description: string
+  deploy_path: string;
+  artifact_version: string;
+  checksum: string;
+  checksum_algorithm: string;
+  propertiesData: Array<PropertyBEModel>;
+
+  constructor(param?: any) {
+    this.type = param.type;
+    this.file = param.file;
+    this.repository = param.repository;
+    this.description = param.description;
+    this.deploy_path = param.deploy_path;
+    this.artifact_version = param.artifact_version;
+    this.checksum = param.checksum;
+    this.checksum_algorithm = param.checksum_algorithm;
+    this.propertiesData = param.propertiesData;
+  }
+
+}
index de62091..b9191cc 100644 (file)
@@ -70,6 +70,7 @@ import { UrlToBase64Service } from '../services/url-tobase64-service';
 import { FileUtils } from '../utils/file-utils';
 import { ValidationUtils } from '../utils/validation-utils';
 import {ReqAndCapabilitiesService} from "../ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service";
+import {ToscaArtifactService} from "../ng2/services/tosca-artifact.service";
 
 const moduleName: string = 'Sdc.Services';
 const serviceModule: ng.IModule = angular.module(moduleName, []);
@@ -131,3 +132,4 @@ serviceModule.service('OnboardingService', downgradeInjectable(OnboardingService
 serviceModule.service('ElementService', downgradeInjectable(ElementService));
 serviceModule.service('ModelService', downgradeInjectable(ModelService));
 serviceModule.service('ImportVSPService', downgradeInjectable(ImportVSPService));
+serviceModule.service('ToscaArtifactService', downgradeInjectable(ToscaArtifactService));
index bb11199..5b12ae9 100644 (file)
@@ -101,6 +101,7 @@ import {InterfaceOperationHandlerModule} from "./pages/composition/interface-ope
 import {AttributesOutputsModule} from "./pages/attributes-outputs/attributes-outputs.module";
 import { ElementService } from "./services/element.service";
 import { ModelService } from "./services/model.service";
+import {ToscaArtifactService} from "./services/tosca-artifact.service";
 
 
 declare const __ENV__: string;
@@ -201,6 +202,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent
     OnboardingService,
     ElementService,
     ModelService,
+    ToscaArtifactService,
     ServiceServiceNg2,
     AutomatedUpgradeService,
     WorkflowServiceNg2,
index 304fbce..2cc91a9 100644 (file)
@@ -19,7 +19,7 @@
 *  ============LICENSE_END=========================================================
 */
 
-import {Component, ComponentRef, Input} from '@angular/core';
+import {Component, ComponentRef, Inject, Input} from '@angular/core';
 import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
 import {TranslateService} from "../../../shared/translator/translate.service";
 import {ModalService } from 'app/ng2/services/modal.service';
@@ -45,15 +45,17 @@ import {
   InterfaceModel,
   InputBEModel,
   ModalModel,
-  ComponentInstance
+  ComponentInstance, ArtifactModel
 } from 'app/models';
+import {ArtifactGroupType} from "../../../../utils/constants";
+import {DropdownValue} from "../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {ToscaArtifactService} from "../../../services/tosca-artifact.service";
+import {ToscaArtifactModel} from "../../../../models/toscaArtifact";
 
 export class UIInterfaceOperationModel extends InterfaceOperationModel {
   isCollapsed: boolean = true;
   isEllipsis: boolean;
   MAX_LENGTH = 75;
-  _description: string;
-
   constructor(operation: InterfaceOperationModel) {
     super(operation);
 
@@ -119,7 +121,6 @@ export class UIInterfaceModel extends ComponentInstanceInterfaceModel {
 })
 export class InterfaceOperationsComponent {
   interfaces: UIInterfaceModel[];
-  selectedOperation: InterfaceOperationModel;
   inputs: Array<InputBEModel>;
   isLoading: boolean;
   interfaceTypes: { [interfaceType: string]: string[] };
@@ -130,6 +131,9 @@ export class InterfaceOperationsComponent {
   modalTranslation: ModalTranslation;
   componentInstancesInterfaces: Map<string, InterfaceModel[]>;
 
+  deploymentArtifactsFilePath: Array<DropdownValue> = [];
+  toscaArtifactTypes: Array<DropdownValue> = [];
+
   @Input() component: ComponentInstance;
   @Input() readonly: boolean;
   @Input() enableMenuItems: Function;
@@ -141,8 +145,10 @@ export class InterfaceOperationsComponent {
       private TranslateService: TranslateService,
       private PluginsService: PluginsService,
       private topologyTemplateService: TopologyTemplateService,
+      private toscaArtifactService: ToscaArtifactService,
       private modalServiceNg2: ModalService,
       private workspaceService: WorkspaceService,
+      @Inject("Notification") private Notification: any,
   ) {
     this.modalTranslation = new ModalTranslation(TranslateService);
   }
@@ -150,6 +156,8 @@ export class InterfaceOperationsComponent {
   ngOnInit(): void {
     this.componentMetaData = this.workspaceService.metadata;
     this.loadComponentInstances();
+    this.loadDeployedArtifacts();
+    this.loadToscaArtifacts()
   }
 
   private loadComponentInstances() {
@@ -167,7 +175,7 @@ export class InterfaceOperationsComponent {
     this.sortInterfaces();
   }
 
-  private initInterfaces(interfaces: InterfaceModel[]): void {
+  private initInterfaces(interfaces: ComponentInstanceInterfaceModel[]): void {
     this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
   }
 
@@ -201,7 +209,7 @@ export class InterfaceOperationsComponent {
   }
 
   private enableOrDisableSaveButton = (): boolean => {
-    return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+    return this.modalInstance.instance.dynamicContent.instance.readonly;
   }
 
   onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
@@ -215,6 +223,8 @@ export class InterfaceOperationsComponent {
         this.modalInstance,
         InterfaceOperationHandlerComponent,
         {
+          deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
+          toscaArtifactTypes: this.toscaArtifactTypes,
           selectedInterface: interfaceModel,
           selectedInterfaceOperation: operation,
           validityChangedCallback: this.enableOrDisableSaveButton
@@ -235,13 +245,43 @@ export class InterfaceOperationsComponent {
         this.componentMetaData.uniqueId,
         this.componentMetaData.componentType,
         this.componentInstanceSelected.uniqueId,
-        operationUpdated)
-    .subscribe((updatedComponentInstance: ComponentInstance) => {
-      this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
-      this.initComponentInstanceInterfaceOperations();
+        operationUpdated).subscribe((updatedComponentInstance: ComponentInstance) => {
+          this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance);
+          this.initComponentInstanceInterfaceOperations();
     });
     this.modalServiceNg2.closeCurrentModal();
     this.isLoading = false;
   }
 
+  loadDeployedArtifacts() {
+    this.topologyTemplateService.getArtifactsByType(this.componentMetaData.componentType, this.componentMetaData.uniqueId, ArtifactGroupType.DEPLOYMENT)
+    .subscribe(response => {
+      let artifactsDeployment = response.deploymentArtifacts;
+      if (artifactsDeployment) {
+        let deploymentArtifactsFound = <ArtifactModel[]>_.values(artifactsDeployment)
+        deploymentArtifactsFound.forEach(value => {
+          this.deploymentArtifactsFilePath.push(new DropdownValue(value, value.artifactType.concat('->').concat(value.artifactName)));
+        });
+      }}, error => {
+      this.Notification.error({
+        message: 'Failed to Load the Deployed Artifacts:' + error,
+        title: 'Failure'
+      });
+    });
+  }
+
+  loadToscaArtifacts() {
+    this.toscaArtifactService.getToscaArtifacts(this.componentMetaData.model).subscribe(response => {
+      if (response) {
+        let toscaArtifactsFound = <ToscaArtifactModel[]>_.values(response);
+        toscaArtifactsFound.forEach(value => this.toscaArtifactTypes.push(new DropdownValue(value, value.type)));
+      }
+    }, error => {
+      this.Notification.error({
+        message: 'Failed to Load Tosca Artifacts:' + error,
+        title: 'Failure'
+      });
+    });
+  }
+
 }
index f711020..428c4cd 100644 (file)
@@ -41,7 +41,7 @@
             </div>
         </div>
 
-        <div class="i-sdc-form-item">
+        <div class="form-item">
             <sdc-input
                 label="{{'OPERATION_DESCRIPTION' | translate}}"
                 [(value)]="operationToUpdate.description"
             </sdc-input>
         </div>
 
-        <div class="i-sdc-form-item">
-            <sdc-input
-                label="{{'IMPLEMENTATION_NAME' | translate}}"
-                testId="interface-operation-implementation-name"
-                [(value)]="operationToUpdate.implementation.artifactName">
-            </sdc-input>
+        <div class="group-with-border content-row">
+            <label class="occurrences-label"> {{ 'INTERFACE_OPERATION_IMPLEMENTATION' | translate}}</label>
+            <div class="form-item">
+                <checkbox [label]="'Add Artifact To Implementation'"
+                          [(checked)]="enableAddArtifactImplementation"
+                          (checkedChange)="onMarkToAddArtifactToImplementation($event)">
+                </checkbox>
+            </div>
+            <div class="form-item" *ngIf="!enableAddArtifactImplementation">
+                <sdc-input
+                    label="{{'INTERFACE_OPERATION_IMPLEMENTATION_NAME' | translate}}"
+                    testId="interface-operation-implementation-name"
+                    [(value)]="artifactName"
+                    (valueChange)="onImplementationNameChange($event)">
+                </sdc-input>
+            </div>
+
+            <div class="side-by-side" *ngIf="enableAddArtifactImplementation">
+                <div class="form-item" *ngIf="toscaArtifactTypes">
+                    <sdc-dropdown
+                        label="{{ 'TOSCA_ARTIFACT_TYPE' | translate }}"
+                        testId="selectToscaArtifactType"
+                        [required]="true"
+                        [selectedOption]="toscaArtifactTypeSelected"
+                        placeHolder="{{toscaArtifactTypeSelected != undefined ? toscaArtifactTypeSelected : 'Select...'}}"
+                        (changed)="onSelectToscaArtifactType($event)"
+                        [options]="toscaArtifactTypes">
+                    </sdc-dropdown>
+                </div>
+                <div class="form-item" *ngIf="toscaArtifactTypeSelected && enableAddArtifactImplementation">
+                    <sdc-input
+                        label="{{ 'INTERFACE_OPERATION_IMPLEMENTATION_FILE' | translate }}"
+                        data-tests-id="artifactFile"
+                        [(value)]="artifactName"
+                        [required]="true"
+                        (valueChange)="onArtifactFileChange($event)">
+                    </sdc-input>
+                </div>
+                <div class="form-item">
+                    <sdc-input
+                        label="{{ 'ARTIFACT_VERSION' | translate }}"
+                        data-tests-id="artifactVersion"
+                        [(value)]="artifactVersion"
+                        (valueChange)="onArtifactVersionChange($event)">
+                    </sdc-input>
+                </div>
+            </div>
+            <div class="form-item" *ngIf="toscaArtifactTypeSelected && enableAddArtifactImplementation">
+                <label class="sdc-input__label">{{ 'ENTITY_VIEWER_PROPERTIES_TAB' | translate }}</label>
+                <div class="generic-table">
+                    <div class="header-row table-row">
+                        <span class="cell header-cell field-input-name">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_NAME' | translate }}</span>
+                        <span class="cell header-cell field-input-type">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE' | translate }}</span>
+                        <span class="cell header-cell field-input-value">{{ 'IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE' | translate }}</span>
+                    </div>
+
+                    <div class="empty-msg data-row" *ngIf="!toscaArtifactTypeProperties.length">
+                        <div>{{ 'EMPTY_PARAM_TABLE_HEADER' | translate }}</div>
+                    </div>
+                    <property-param-row
+                        *ngFor="let property of toscaArtifactTypeProperties"
+                        class="data-row"
+                        [artifactProperty]="property"
+                        [isPropertyValueValid]="propertyValueValidation">
+                    </property-param-row>
+                </div>
+            </div>
         </div>
 
         <div class="separator-buttons">
index 8bbed9d..955720c 100644 (file)
     padding-top: 12px;
     padding-bottom: 20px;
 
+    .group-with-border {
+        margin: 25px 0;
+        padding: 15px 0;
+        border-top: 1px solid @tlv_color_u;
+        border-bottom: 1px solid @tlv_color_u;
+        .content-row:not(:last-of-type) {
+            padding-bottom: 13px;
+        }
+    }
+
+    .occurrences-label {
+        font-family: @font-opensans-regular;
+        margin-bottom: 19px;
+        font-size: 14px;
+    }
+
     .i-sdc-form-label {
         font-size: 12px;
     }
         }
 
         /deep/ .cell {
-            &.field-input-name, &.field-input-value{
+            &.field-input-name, &.field-input-type, &.field-input-value{
                 flex: 1;
             }
 
index 1618af4..0b0efde 100644 (file)
@@ -19,7 +19,7 @@
 *  ============LICENSE_END=========================================================
 */
 
-import {Component} from '@angular/core';
+import {Component, EventEmitter, Output} from '@angular/core';
 import {UIInterfaceModel} from "../interface-operations.component";
 import {
     InputOperationParameter,
@@ -27,6 +27,12 @@ import {
     IOperationParamsList
 } from "../../../../../models/interfaceOperation";
 import {TranslateService} from "../../../../shared/translator/translate.service";
+import {IDropDownOption} from "onap-ui-angular/dist/form-elements/dropdown/dropdown-models";
+import {DropdownValue} from "../../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {ArtifactModel} from "../../../../../models/artifacts";
+import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
+import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
+import {PropertyFEModel} from "../../../../../models/properties-inputs/property-fe-model";
 
 @Component({
     selector: 'operation-handler',
@@ -36,20 +42,32 @@ import {TranslateService} from "../../../../shared/translator/translate.service"
 })
 
 export class InterfaceOperationHandlerComponent {
+    @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
 
     input: {
+        toscaArtifactTypes: Array<DropdownValue>;
         selectedInterface: UIInterfaceModel;
         selectedInterfaceOperation: InterfaceOperationModel;
         validityChangedCallback: Function;
     };
 
     interfaceType: string;
+    artifactVersion: string;
+    artifactName: string;
     interfaceOperationName: string;
     operationToUpdate: InterfaceOperationModel;
     inputs: Array<InputOperationParameter> = [];
+    properties: Array<PropertyParamRowComponent> = [];
     isLoading: boolean = false;
     readonly: boolean;
 
+    toscaArtifactTypeSelected: string;
+    toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
+
+    toscaArtifactTypes: Array<DropdownValue> = [];
+
+    enableAddArtifactImplementation: boolean;
+
     ngOnInit() {
         this.interfaceType = this.input.selectedInterface.displayType();
         this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
@@ -60,9 +78,82 @@ export class InterfaceOperationHandlerComponent {
                 listToscaDataDefinition: Array<InputOperationParameter> = [];
             }
         }
+
         this.inputs = this.operationToUpdate.inputs.listToscaDataDefinition;
         this.removeImplementationQuote();
         this.validityChanged();
+        this.loadInterfaceOperationImplementation();
+    }
+
+    private loadInterfaceOperationImplementation() {
+        this.toscaArtifactTypes = this.input.toscaArtifactTypes;
+        this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
+        this.artifactName = this.operationToUpdate.implementation.artifactName;
+        this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
+        this.getArtifactTypesSelected();
+    }
+
+    onDescriptionChange= (value: any): void => {
+        this.operationToUpdate.description = value;
+    }
+
+    onImplementationNameChange(value: any) {
+        this.readonly = true
+        if (value) {
+            let artifact = new ArtifactModel();
+            artifact.artifactName = value;
+            this.operationToUpdate.implementation = artifact;
+            this.enableAddArtifactImplementation = false;
+            this.readonly = false;
+        }
+    }
+
+    onPropertyValueChange = (propertyValue) => {
+        this.emitter.emit(propertyValue);
+    }
+
+    onMarkToAddArtifactToImplementation(event: any) {
+        if (!event) {
+            this.toscaArtifactTypeSelected = undefined;
+            this.artifactVersion = undefined;
+            if (this.operationToUpdate.implementation.artifactType) {
+                this.artifactName = undefined;
+            }
+            this.toscaArtifactTypeProperties = undefined;
+        } else {
+            this.getArtifactTypesSelected();
+        }
+        this.enableAddArtifactImplementation = event;
+        this.validateRequiredField();
+    }
+
+    onSelectToscaArtifactType(type: IDropDownOption) {
+        if (type) {
+            let toscaArtifactType = type.value;
+            let artifact = new ArtifactModel();
+            this.artifactName = undefined;
+            this.artifactVersion = undefined;
+            artifact.artifactType = toscaArtifactType.type;
+            artifact.properties = toscaArtifactType.properties;
+            this.toscaArtifactTypeProperties = artifact.properties;
+            this.toscaArtifactTypeSelected = artifact.artifactType;
+            this.operationToUpdate.implementation = artifact;
+            this.getArtifactTypesSelected();
+        }
+        this.validateRequiredField();
+    }
+
+    onArtifactFileChange(value: any) {
+        if (value) {
+            this.operationToUpdate.implementation.artifactName = value;
+        }
+        this.validateRequiredField();
+    }
+
+    onArtifactVersionChange(value: any) {
+        if (value) {
+            this.operationToUpdate.implementation.artifactVersion = value;
+        }
     }
 
     onAddInput(inputOperationParameter?: InputOperationParameter): void {
@@ -73,12 +164,32 @@ export class InterfaceOperationHandlerComponent {
         this.validityChanged();
     }
 
+    propertyValueValidation = (propertyValue): void => {
+        this.onPropertyValueChange(propertyValue);
+        this.readonly = !propertyValue.isValid;
+    }
+
     onRemoveInput = (inputParam: InputOperationParameter): void => {
         let index = this.inputs.indexOf(inputParam);
         this.inputs.splice(index, 1);
         this.validityChanged();
     }
 
+    private removeImplementationQuote(): void {
+        if (this.operationToUpdate.implementation) {
+            if (!this.operationToUpdate.implementation
+                || !this.operationToUpdate.implementation.artifactName) {
+                return;
+            }
+
+            let implementation = this.operationToUpdate.implementation.artifactName.trim();
+
+            if (implementation.startsWith("'") && implementation.endsWith("'")) {
+                this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
+            }
+        }
+    }
+
     private generateUniqueId = (): string => {
         let result = '';
         const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@@ -97,8 +208,24 @@ export class InterfaceOperationHandlerComponent {
         }
     }
 
-    onDescriptionChange= (value: any): void => {
-        this.operationToUpdate.description = value;
+    private getArtifactTypesSelected() {
+        if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.artifactType) {
+            this.artifactName = this.operationToUpdate.implementation.artifactName;
+            this.toscaArtifactTypeSelected = this.operationToUpdate.implementation.artifactType;
+            this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
+            this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
+            this.enableAddArtifactImplementation = true;
+        }
+        this.validateRequiredField();
+    }
+
+    validateRequiredField = () => {
+        this.readonly = true;
+        let requiredFieldSelected = this.toscaArtifactTypeSelected && this.artifactName ? true : false;
+        this.input.validityChangedCallback(requiredFieldSelected);
+        if (requiredFieldSelected) {
+            this.readonly = false;
+        }
     }
 
     private checkFormValidForSubmit = (): boolean => {
@@ -114,17 +241,8 @@ export class InterfaceOperationHandlerComponent {
         return isValid;
     }
 
-    private removeImplementationQuote(): void {
-        if (!this.operationToUpdate.implementation
-            || !this.operationToUpdate.implementation.artifactName) {
-            return;
-        }
-
-        let implementation = this.operationToUpdate.implementation.artifactName.trim();
-
-        if (implementation.startsWith("'") && implementation.endsWith("'")) {
-            this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
-        }
+    toDropDownOption(val: string) {
+        return { value : val, label: val };
     }
 
 }
index deba50a..2595301 100644 (file)
@@ -30,11 +30,14 @@ import {SdcUiComponentsModule} from 'onap-ui-angular';
 import {UiElementsModule} from '../../../../components/ui/ui-elements.module';
 import {InputParamRowComponent} from './input-param-row/input-param-row.component';
 import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.component";
+import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
+import {PropertyTableModule} from "../../../../components/logic/properties-table/property-table.module";
 
 @NgModule({
   declarations: [
     InterfaceOperationHandlerComponent,
-    InputParamRowComponent
+    InputParamRowComponent,
+    PropertyParamRowComponent
   ],
   imports: [
     CommonModule,
@@ -42,9 +45,12 @@ import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.
     FormsModule,
     FormElementsModule,
     TranslateModule,
-    UiElementsModule
+    UiElementsModule,
+    PropertyTableModule
+  ],
+  exports: [
+    PropertyParamRowComponent
   ],
-  exports: [],
   entryComponents: [
     InterfaceOperationHandlerComponent
   ],
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.html
new file mode 100644 (file)
index 0000000..ef7b94c
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2021 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ -->
+
+<div class="cell field-input-name">
+    <sdc-input
+        [(value)]="artifactProperty.name"
+        [disabled]="true"
+        testId="interface-operation-input-name">
+    </sdc-input>
+</div>
+
+<div class="cell field-input-type">
+    <sdc-input
+        [(value)]="artifactProperty.type"
+        [disabled]="true"
+        testId="operation-implementation-property-type">
+    </sdc-input>
+</div>
+
+<div class="cell field-input-value">
+    <dynamic-element
+        [(value)]="artifactProperty.value"
+        data-tests-id="operation-implementation-property-value"
+        (elementChanged)="isPropertyValueValid($event)"
+        [type]="artifactProperty ? artifactProperty.type : 'string'">
+    </dynamic-element>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.less
new file mode 100644 (file)
index 0000000..12eacc6
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2021 Nordix Foundation. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+@import '../../../../../../../assets/styles/variables.less';
+
+.remove {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    svg-icon {
+        position: relative;
+        right: -3px;
+
+        &:hover {
+            cursor: pointer;
+        }
+    }
+}
+
+.cell {
+    min-height: 50px;
+    padding: 10px;
+    display: flex;
+    align-items: center;
+
+    > * {
+        flex-basis: 100%;
+    }
+
+    /deep/ select {
+        height: 30px;
+    }
+
+    input {
+        height: 30px;
+        border: none;
+        padding-left: 10px;
+    }
+
+    select {
+        width: 100%;
+    }
+
+    &.field-property {
+        &:last-child {
+            flex: 1;
+        }
+
+        .no-properties-error {
+            color: @func_color_q;
+            font-style: italic;
+        }
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/property-param-row/property-param-row.component.ts
new file mode 100644 (file)
index 0000000..6ae75fa
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file 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.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+
+import {Component, Input} from '@angular/core';
+import {PropertyOperationParameter} from "../../../../../../models/interfaceOperation";
+
+@Component({
+  selector: 'property-param-row',
+  templateUrl: './property-param-row.component.html',
+  styleUrls: ['./property-param-row.component.less']
+})
+
+export class PropertyParamRowComponent {
+  @Input() artifactProperty: PropertyOperationParameter;
+  @Input() isPropertyValueValid: Function;
+
+}
index 1e217f1..16c3f33 100644 (file)
@@ -211,8 +211,6 @@ export class OperationCreatorComponent implements OperationCreatorInput {
         if (inputOperation) {
             this.onSelectInterface(new DropDownOption(this.operation.interfaceType));
 
-            this.operation.artifactFileName = this.operation.artifactFileName || this.operation.implementation.artifactName;
-
             if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
                 this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
                 this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
diff --git a/catalog-ui/src/app/ng2/services/tosca-artifact.service.ts b/catalog-ui/src/app/ng2/services/tosca-artifact.service.ts
new file mode 100644 (file)
index 0000000..11a8cb9
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+* ============LICENSE_START=======================================================
+*  Copyright (C) 2021 Nordix Foundation. All rights reserved.
+*  ================================================================================
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file 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.
+*
+*  SPDX-License-Identifier: Apache-2.0
+*  ============LICENSE_END=========================================================
+*/
+import { HttpClient } from '@angular/common/http';
+import { Inject, Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config';
+import {ToscaArtifactModel} from "../../models/toscaArtifact";
+
+@Injectable()
+export class ToscaArtifactService {
+
+  protected baseUrl;
+
+  constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
+    this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root;
+  }
+
+  getToscaArtifacts(modelName: string):Observable<ToscaArtifactModel[]> {
+    const url = this.baseUrl + "artifactTypes";
+    if (modelName) {
+      return this.http.get<ToscaArtifactModel[]>(url, {params: {model: modelName}});
+    }
+    return this.http.get<ToscaArtifactModel[]>(url);
+  }
+
+}
index cf27783..1a79c0a 100644 (file)
 
     "PARAM_NONE_OF_TYPE": "No available properties of this type.",
 
+    "=========== OPERATION UPDATE ===============": "",
+    "DEPLOYMENT_ARTIFACT_TYPE": "Deployment Artifact Type",
+    "TOSCA_ARTIFACT_TYPE": "Tosca Artifact Type",
+    "ARTIFACT_VERSION": "Artifact Version",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_NAME": "Name",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_TYPE": "Type",
+    "IMPLEMENTATION_ARTIFACT_PROPERTY_VALUE": "Value",
+    "INTERFACE_OPERATION_IMPLEMENTATION": "Implementation",
+    "INTERFACE_OPERATION_IMPLEMENTATION_NAME": "Name",
+    "INTERFACE_OPERATION_IMPLEMENTATION_FILE": "File",
+    "ADD_INTERFACE_OPERATION_IMPLEMENTATION_ARTIFACT": "Enable add Artifact To Implementation",
+
     "=========== PLUGIN NOT CONNECTED ===========": "",
     "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
     "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",
index bc9bc33..4eee042 100644 (file)
 
 package org.openecomp.sdc.be.datatypes.elements;
 
-import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
-import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 
 public class ArtifactDataDefinition extends ToscaDataDefinition {
@@ -78,7 +77,9 @@ public class ArtifactDataDefinition extends ToscaDataDefinition {
         }
         this.setGeneratedFromId(a.getGeneratedFromId());
         this.setIsFromCsar(a.getIsFromCsar());
-
+        if (a.getProperties() != null) {
+            this.setProperties(new ArrayList<>(a.getProperties()));
+        }
 
     }
 
@@ -365,6 +366,14 @@ public class ArtifactDataDefinition extends ToscaDataDefinition {
     }
 
 
+    public List<PropertyDataDefinition> getProperties() {
+        return (List<PropertyDataDefinition>) getToscaPresentationValue(JsonPresentationFields.PROPERTIES);
+    }
+
+    private void setProperties(final List<PropertyDataDefinition> properties) {
+        setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties);
+    }
+
     @Override
     public String toString() {
         return "ArtifactDataDefinition [uniqueId=" + getUniqueId() + ", artifactType=" + getArtifactType() + ", artifactRef=" + getArtifactRef() + ", artifactName=" + getArtifactName() + ", artifactRepository=" + getArtifactRepository() + ", artifactChecksum="