summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java31
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java2
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java1
-rw-r--r--catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts2
-rw-r--r--catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.html2
-rw-r--r--catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts62
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AttributesTabComponent.java5
9 files changed, 116 insertions, 5 deletions
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
index c5b417d725..4d26e08831 100644
--- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
+++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
@@ -2926,3 +2926,11 @@ errors:
message: "Error: The following properties:\n%1\nused in the substitution mapping node type in CSAR are missing from the system. Please add these to the node in the SDC catalog prior to importing the template",
messageId: "SVC4021"
}
+
+ # %1 - Output name
+ #---------SVC4022-----------------------------
+ OUTPUT_NAME_ALREADY_EXIST: {
+ code: 400,
+ message: "Output name '%1' already exist.",
+ messageId: "SVC4022"
+ }
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java
index 394d6b314b..e494934d4d 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java
@@ -119,7 +119,13 @@ public abstract class DefaultAttributeDeclarator<PROPERTYOWNER extends Propertie
//Creating input from property create on self using add property..Do not add the prefix
generatedInputPrefix = null;
}
- final String generatedOutputName = generateOutputName(generatedInputPrefix, attribOutput);
+ String generatedOutputName = null;
+ if (StringUtils.isNotEmpty(attribOutput.getOutputName())) {
+ generatedOutputName = attribOutput.getOutputName();
+ } else {
+ generatedOutputName = generateOutputName(generatedInputPrefix, attribOutput);
+ }
+
log.debug("createInput: propOwner.uniqueId={}, attribOutput.parentUniqueId={}", propertiesOwner.getUniqueId(),
attribOutput.getParentUniqueId());
return createOutputFromAttribute(component.getUniqueId(), propertiesOwner, generatedOutputName, attribOutput, attributeDataDefinition);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java
index 62ef98b985..58baad1a58 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java
@@ -23,10 +23,14 @@ package org.openecomp.sdc.be.components.impl;
import fj.data.Either;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.jetbrains.annotations.NotNull;
import org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator;
import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
@@ -130,6 +134,10 @@ public class OutputsBusinessLogic extends BaseBusinessLogic {
try {
validateUserExists(userId);
component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
+ ImmutablePair<StorageOperationStatus, String> status = validateOutputName(component, componentInstOutputsMapUi);
+ if (status.getLeft() != StorageOperationStatus.OK) {
+ throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.OUTPUT_NAME_ALREADY_EXIST, status.getRight()));
+ }
result = attributeDeclarationOrchestrator.declareAttributesToOutputs(component, componentInstOutputsMapUi).left()
.bind(outputsToCreate -> prepareOutputsForCreation(userId, componentId, outputsToCreate)).right()
.map(componentsUtils::getResponseFormat);
@@ -155,6 +163,29 @@ public class OutputsBusinessLogic extends BaseBusinessLogic {
}
}
+ private ImmutablePair<StorageOperationStatus, String> validateOutputName(final Component component,
+ final ComponentInstOutputsMap componentInstOutputsMapUi) {
+ final Map<String, List<ComponentInstanceAttribOutput>> outputDeclaredProperties = new HashMap<>();
+ if (MapUtils.isNotEmpty(componentInstOutputsMapUi.getComponentInstanceOutputsMap())) {
+ outputDeclaredProperties.putAll(componentInstOutputsMapUi.getComponentInstanceOutputsMap());
+ } else if (MapUtils.isNotEmpty(componentInstOutputsMapUi.getComponentInstanceAttributes())) {
+ outputDeclaredProperties.putAll(componentInstOutputsMapUi.getComponentInstanceAttributes());
+ }
+ if (MapUtils.isNotEmpty(outputDeclaredProperties) && CollectionUtils.isNotEmpty(component.getOutputs())) {
+ for (final List<ComponentInstanceAttribOutput> componentInstancePropOutputs : outputDeclaredProperties.values()) {
+ for (final ComponentInstanceAttribOutput componentInstancePropOutput : componentInstancePropOutputs) {
+ final Optional<OutputDefinition> outputDefinition = component.getOutputs().stream()
+ .filter(output -> output.getName().equals(componentInstancePropOutput.getOutputName())
+ || output.getName().equals(componentInstancePropOutput.getName())).findAny();
+ if (outputDefinition.isPresent()) {
+ return new ImmutablePair<>(StorageOperationStatus.INVALID_VALUE, outputDefinition.get().getName());
+ }
+ }
+ }
+ }
+ return new ImmutablePair<>(StorageOperationStatus.OK, StringUtils.EMPTY);
+ }
+
private Component getAndValidateComponentForCreate(final String userId, final String componentId,
final ComponentTypeEnum componentType,
final boolean shouldLockComp) {
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
index 52162fc272..fbe1c2e376 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
@@ -94,7 +94,7 @@ public enum ActionStatus {
// Inputs
INPUT_IS_NOT_CHILD_OF_COMPONENT, CFVC_LOOP_DETECTED, INPUT_ALREADY_EXIST, INPUT_NAME_ALREADY_EXIST,
// Outputs
- OUTPUT_IS_NOT_CHILD_OF_COMPONENT, OUTPUT_ALREADY_EXIST,
+ OUTPUT_IS_NOT_CHILD_OF_COMPONENT, OUTPUT_ALREADY_EXIST, OUTPUT_NAME_ALREADY_EXIST,
//Forwarding Path related
FORWARDING_PATH_NAME_MAXIMUM_LENGTH, FORWARDING_PATH_NAME_ALREADY_IN_USE, FORWARDING_PATH_NAME_EMPTY, FORWARDING_PATH_PROTOCOL_MAXIMUM_LENGTH, FORWARDING_PATH_DESTINATION_PORT_MAXIMUM_LENGTH, MISSING_OLD_COMPONENT_INSTANCE, MISSING_NEW_COMPONENT_INSTANCE,
//policies
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java
index 8531a36843..42ff192ac7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java
@@ -28,6 +28,7 @@ public class ComponentInstanceAttribOutput extends ComponentInstanceAttribute {
private String attributesName;
private AttributeDefinition output;
+ private String outputName;
public ComponentInstanceAttribOutput() {
super();
diff --git a/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts b/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts
index a6966cd799..3ec03c5121 100644
--- a/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts
+++ b/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts
@@ -51,6 +51,7 @@ export class AttributeBEModel {
subAttributeOutputPath: string;
outputPath: string;
toscaPresentation: ToscaPresentationData;
+ outputName: string;
constructor(attribute?: AttributeBEModel) {
if (attribute) {
@@ -77,6 +78,7 @@ export class AttributeBEModel {
this.subAttributeOutputPath = attribute.subAttributeOutputPath;
this.toscaPresentation = attribute.toscaPresentation;
this.outputPath = attribute.outputPath;
+ this.outputName = attribute.outputName;
}
if (!this.schema || !this.schema.property) {
diff --git a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.html b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.html
index e4f672ce9b..e55fc47007 100644
--- a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.html
+++ b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.html
@@ -57,7 +57,7 @@
</div>
</tabs>
<div class="header">
- <button class="tlv-btn blue declare-button" [disabled]="!checkedAttributesCount || isReadonly || hasChangedData" (click)="declareAttributes()" data-tests-id="declare-button declare-output">Declare Output</button>
+ <button class="tlv-btn blue declare-button" [disabled]="!checkedAttributesCount || isReadonly || hasChangedData" (click)="declareOutput()" data-tests-id="declare-button declare-output">Declare Output</button>
</div>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts
index 85d2756da8..48700f2ecb 100644
--- a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts
@@ -60,6 +60,7 @@ import {DerivedFEAttribute} from "../../../models/attributes-outputs/derived-fe-
import {AttributeBEModel} from "../../../models/attributes-outputs/attribute-be-model";
import {AttributeCreatorComponent} from "app/ng2/pages/attributes-outputs/attribute-creator/attribute-creator.component";
import {AttributeRowSelectedEvent} from "app/ng2/components/logic/attributes-table/attributes-table.component";
+import { DeclareInputComponent } from '../properties-assignment/declare-input/declare-input.component';
const SERVICE_SELF_TITLE = "SELF";
@@ -432,9 +433,62 @@ export class AttributesOutputsComponent {
this.searchQuery = '';
};
+ declareOutput = (): void => {
+ if (this.checkedAttributesCount == 1) {
+ this.openAddOutputNameModal();
+ } else if (this.checkedAttributesCount > 1) {
+ this.declareAttributes();
+ }
+ }
+
+ private openAddOutputNameModal = (): void => {
+ const modalTitle = 'Enter name of the ouput to be created';
+ const modalButtons = [];
+ const modal = this.ModalService.createCustomModal(new ModalModel(
+ 'sm',
+ modalTitle,
+ null,
+ modalButtons,
+ null /* type */
+ ));
+ modalButtons.push(new ButtonModel('Save', 'blue',
+ () => {
+ const outputName: string = modal.instance.dynamicContent.instance.inputNameForm.value;
+ if (outputName) {
+ this.declareAttributes(outputName);
+ } else {
+ this.Notification.warning({
+ message: 'Failed to set input name',
+ title: 'Warning'
+ });
+ }
+ this.ModalService.closeCurrentModal();
+ }
+ ));
+ modalButtons.push(new ButtonModel('Cancel', 'outline grey', () => {
+ this.ModalService.closeCurrentModal();
+ }));
+ this.ModalService.addDynamicContentToModal(modal, DeclareInputComponent, {defaultInputName: this.generateDefaultOutputName()});
+ modal.instance.open();
+ }
+
+ generateDefaultOutputName = (): string => {
+ let defaultInputName: string;
+ let instancesIds = this.keysPipe.transform(this.instanceFeAttributesMap, []);
+ angular.forEach(instancesIds, (instanceId: string) => {
+ const selectedOutput : AttributeBEModel = this.attributesService.getCheckedAttributes(this.instanceFeAttributesMap[instanceId])[0];
+ let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
+ defaultInputName = selectedOutput.name;
+ if (selectedInstanceData.invariantName) {
+ defaultInputName = selectedInstanceData.invariantName+'_'+selectedOutput.name;
+ }
+ });
+ return defaultInputName;
+ }
/*** DECLARE ATTRIBUTES/OUTPUTS ***/
- declareAttributes = (): void => {
+ declareAttributes = (outputName?: string): void => {
+ this.loadingAttributes = true;
let selectedComponentInstancesAttributes: InstanceBeAttributesMap = new InstanceBeAttributesMap();
let selectedComponentInstancesOutputs: InstanceBeAttributesMap = new InstanceBeAttributesMap();
let instancesIds = this.keysPipe.transform(this.instanceFeAttributesMap, []);
@@ -445,6 +499,9 @@ export class AttributesOutputsComponent {
if (!this.isOutput(selectedInstanceData.originType)) {
// convert Attribute FE model -> Attribute BE model, extract only checked
selectedComponentInstancesAttributes[instanceId] = this.attributesService.getCheckedAttributes(this.instanceFeAttributesMap[instanceId]);
+ if (outputName) {
+ selectedComponentInstancesAttributes[instanceId][0].outputName = outputName;
+ }
} else {
selectedComponentInstancesOutputs[instanceId] = this.attributesService.getCheckedAttributes(this.instanceFeAttributesMap[instanceId]);
}
@@ -463,7 +520,8 @@ export class AttributesOutputsComponent {
this.outputs.push(newOutput);
this.updateAttributeValueAfterDeclare(newOutput);
});
- });
+ this.loadingAttributes = false;
+ }, error => {this.loadingAttributes = false;}); //ignore error
};
saveChangedData = (): Promise<(AttributeBEModel | OutputBEModel)[]> => {
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AttributesTabComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AttributesTabComponent.java
index e06d702afe..207c79a49e 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AttributesTabComponent.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AttributesTabComponent.java
@@ -45,6 +45,9 @@ public class AttributesTabComponent extends AbstractPageObject {
}
waitForElementVisibility(By.xpath(XpathSelector.ATTRIBUTES_CHECKBOX.getXpath(attributeName))).click();
waitToBeClickable(By.xpath(XpathSelector.DECLARE_OUTPUT_BTN.getXpath())).click();
+ final By setInputNameLocator = By.xpath(XpathSelector.SET_INPUT_NAME_FIELD.getXpath());
+ final WebElement inputNameField = waitForElementVisibility(setInputNameLocator, 5);
+ waitToBeClickable(By.xpath(XpathSelector.INPUT_NAME_SAVE_BTN.getXpath())).click();
waitForAddedOutputNotification();
}
@@ -82,6 +85,8 @@ public class AttributesTabComponent extends AbstractPageObject {
ATTRIBUTES_CHECKBOX("//checkbox[@data-tests-id='%s']"),
DECLARE_OUTPUT_BTN("declare-button declare-output", "//button[@data-tests-id='%s']"),
INSTANCE_SPAN("//div[contains(@class,'table-rows-header')]"),
+ SET_INPUT_NAME_FIELD("//*[@id=\"myText\"]"),
+ INPUT_NAME_SAVE_BTN("//button[@data-tests-id='Save']"),
ADDED_OUTPUT_NOTIFICATION("tab-indication", "//div[@data-tests-id='Outputs']/div[contains(@class, '%s')]");
@Getter