Specify model at service creation 19/122219/5
authoraribeiro <anderson.ribeiro@est.tech>
Wed, 16 Jun 2021 22:21:04 +0000 (23:21 +0100)
committerMichael Morris <michael.morris@est.tech>
Thu, 15 Jul 2021 13:22:37 +0000 (13:22 +0000)
Allows a user to select a model when designing a service

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

25 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ModelBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ModelServletTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceUploadServletTest.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.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/UiComponentDataTransfer.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentMetadata.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java
catalog-ui/src/app/models/components/component.ts
catalog-ui/src/app/models/model.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/services/model.service.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
catalog-ui/src/app/services-ng2.ts
catalog-ui/src/app/utils/component-factory.ts
catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html

index 6eb806d..de79ec1 100644 (file)
@@ -50,7 +50,7 @@ public class ModelBusinessLogic {
     }
 
     public Model createModel(final Model model) {
-        LOGGER.debug("createModel: creating model {}", model);
+        LOGGER.debug("creating model {}", model);
         return modelOperation.createModel(model, false);
     }
 
index 2956abf..c0c68d6 100644 (file)
@@ -2451,6 +2451,9 @@ public class ServiceImportBusinessLogic {
         if (CollectionUtils.isEmpty(newResource.getProperties())) {
             newResource.setProperties(oldResource.getProperties());
         }
+        if (newResource.getModel() == null) {
+            newResource.setModel(oldResource.getModel());
+        }
     }
 
     protected Map<String, Resource> createResourcesFromYamlNodeTypesList(String yamlName, Service service, Map<String, Object> mappedToscaTemplate,
index 706f7a7..32a63dc 100644 (file)
@@ -445,6 +445,7 @@ public class UiComponentDataConverter {
                     dataTransfer.setMetadata(metadata);
                     dataTransfer.setDerivedFromGenericType(service.getDerivedFromGenericType());
                     dataTransfer.setDerivedFromGenericVersion(service.getDerivedFromGenericVersion());
+                    dataTransfer.setModel(service.getModel());
                     break;
                 case NODE_FILTER:
                     if (service.getNodeFilterComponents() == null) {
index bdc9ffc..e7966e0 100644 (file)
@@ -123,6 +123,7 @@ public class ResourceUploadServlet extends AbstractValidationsServlet {
             commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString);
             final String modelNameToBeAssociated = uploadResourceInfoWrapper.getInnerElement().getModel();
             if (modelNameToBeAssociated != null) {
+                log.debug("Model Name to be validated {}", modelNameToBeAssociated);
                 validateModel(modelNameToBeAssociated);
             }
             fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString,
@@ -155,6 +156,7 @@ public class ResourceUploadServlet extends AbstractValidationsServlet {
      */
     private void validateModel(final String modelName) {
         if (modelBusinessLogic.findModel(modelName).isEmpty()) {
+            log.error("Could not find model name {}", modelName);
             throw ModelOperationExceptionSupplier.invalidModel(modelName).get();
         }
     }
index 12f803f..e40124f 100644 (file)
@@ -49,7 +49,6 @@ import org.glassfish.jersey.test.TestProperties;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
@@ -105,8 +104,6 @@ class ModelServletTest extends JerseyTest {
     private ResourceImportManager resourceImportManager;
     @Mock
     private ModelBusinessLogic modelBusinessLogic;
-    @InjectMocks
-    private ModelServlet modelServlet;
     @Mock
     private ResponseFormat responseFormat;
     @Mock
index 31152c6..9d0966b 100644 (file)
@@ -122,7 +122,6 @@ class ResourceUploadServletTest extends JerseyTest {
     private final String modelName = "ETSI-SOL001-331";
 
     private final String rootPath = "/v1/catalog/upload/multipart";
-    private Response response;
     private User user;
 
     @BeforeAll
@@ -203,7 +202,7 @@ class ResourceUploadServletTest extends JerseyTest {
         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.of(new Model(modelName)));
-        response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
+        final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
             .header(Constants.USER_ID_HEADER, USER_ID)
             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
@@ -219,7 +218,7 @@ class ResourceUploadServletTest extends JerseyTest {
         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
-        response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
+        final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
             .header(Constants.USER_ID_HEADER, USER_ID)
             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
                 "src/test/resources/node-types/nodeTypeWithoutModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
@@ -228,11 +227,13 @@ class ResourceUploadServletTest extends JerseyTest {
 
     @Test
     void uploadMultipartFailWithEmptyModelsTest() throws IOException, ParseException, URISyntaxException {
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
         when(modelBusinessLogic.findModel("")).thenReturn(Optional.empty());
-        response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
+        final Response response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
             .header(Constants.USER_ID_HEADER, USER_ID)
             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
                 "src/test/resources/node-types/nodeTypeWithEmptyModels.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
@@ -245,7 +246,7 @@ class ResourceUploadServletTest extends JerseyTest {
         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.empty());
-        response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
+        final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
             .header(Constants.USER_ID_HEADER, USER_ID)
             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
@@ -254,10 +255,12 @@ class ResourceUploadServletTest extends JerseyTest {
 
     @Test
     void uploadMultipartThrowsBusinessExceptionTest() throws IOException, ParseException, URISyntaxException {
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
-        response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
+        final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
             .header(Constants.USER_ID_HEADER, USER_ID)
             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
                 "src/test/resources/node-types/invalid.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
index 7fc954e..633c535 100644 (file)
@@ -70,7 +70,8 @@ public enum EdgeLabelEnum {
     NODE_FILTER_TEMPLATE,
     SUBSTITUTION_FILTER_TEMPLATE,
     DATA_TYPES,
-    MODEL_ELEMENT;
+    MODEL_ELEMENT,
+    MODEL;
     // @formatter:on
 
     /**
index 1b5038e..e0ca719 100644 (file)
@@ -90,6 +90,7 @@ public abstract class Component implements PropertiesOwner {
     private Map<String, InterfaceDefinition> interfaces;
     private List<DataTypeDefinition> dataTypes;
     private SubstitutionFilterDataDefinition substitutionFilter;
+    private String model;
 
     protected Component(ComponentMetadataDefinition componentMetadataDefinition) {
         this.componentMetadataDefinition = componentMetadataDefinition;
index 21c25a2..b74b290 100644 (file)
@@ -137,7 +137,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
         if (addAdditionalInformation != StorageOperationStatus.OK) {
             return Either.right(addAdditionalInformation);
         }
-        final StorageOperationStatus associateNodeTypeToModel = associateResourceMetadataToModel(nodeTypeVertex, nodeType);
+        final StorageOperationStatus associateNodeTypeToModel = associateComponentToModel(nodeTypeVertex, nodeType, EdgeLabelEnum.MODEL_ELEMENT);
         if (associateNodeTypeToModel != StorageOperationStatus.OK) {
             return Either.right(associateNodeTypeToModel);
         }
index 3827cc5..78aa4c7 100644 (file)
@@ -89,7 +89,6 @@ import org.openecomp.sdc.common.api.Constants;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
 import org.openecomp.sdc.common.log.elements.ErrorLogOptionalData;
-import org.openecomp.sdc.common.log.enums.EcompErrorSeverity;
 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
@@ -188,6 +187,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         if (associateCapProperties != StorageOperationStatus.OK) {
             return Either.right(associatePathProperties);
         }
+        final StorageOperationStatus associateServiceToModel = associateComponentToModel(topologyTemplateVertex, topologyTemplate,
+            EdgeLabelEnum.MODEL);
+        if (associateServiceToModel != StorageOperationStatus.OK) {
+            return Either.right(associateServiceToModel);
+        }
         return Either.left(topologyTemplate);
     }
 
index eb85090..d08d705 100644 (file)
@@ -425,13 +425,13 @@ public abstract class ToscaElementOperation extends BaseOperation {
         return StorageOperationStatus.OK;
     }
 
-    protected StorageOperationStatus associateResourceMetadataToModel(final GraphVertex nodeTypeVertex, final ToscaElement nodeType) {
+    protected StorageOperationStatus associateComponentToModel(final GraphVertex nodeTypeVertex, final ToscaElement nodeType,
+                                                               final EdgeLabelEnum edgeLabelEnum) {
         if (nodeType.getMetadataValue(JsonPresentationFields.MODEL) == null) {
             return StorageOperationStatus.OK;
         }
         final String model = ((String) nodeType.getMetadataValue(JsonPresentationFields.MODEL));
-        final JanusGraphOperationStatus createEdge = janusGraphDao
-            .createEdge(getModelVertex(model), nodeTypeVertex, EdgeLabelEnum.MODEL_ELEMENT, new HashMap<>());
+        final JanusGraphOperationStatus createEdge = janusGraphDao.createEdge(getModelVertex(model), nodeTypeVertex, edgeLabelEnum, new HashMap<>());
         if (createEdge != JanusGraphOperationStatus.OK) {
             log.trace("Failed to associate resource {} to model {}", nodeType.getUniqueId(), model);
             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdge);
index 1932709..079f5a4 100644 (file)
@@ -736,7 +736,6 @@ public class ModelConverter {
             resource.setToscaResourceName((String) toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
             resource.setVendorName((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_NAME));
             resource.setVendorRelease((String) toscaElement.getMetadataValue(JsonPresentationFields.VENDOR_RELEASE));
-            resource.setModel((String) toscaElement.getMetadataValue(JsonPresentationFields.MODEL));
             // field isn't mandatory , but shouldn't be null(should be an empty string instead)
             if (((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER)) != null) {
                 resource.setResourceVendorModelNumber((String) toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER));
@@ -769,6 +768,7 @@ public class ModelConverter {
         component.setContactId((String) toscaElement.getMetadataValue(JsonPresentationFields.CONTACT_ID));
         component.setUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.UUID));
         component.setIsDeleted((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
+        component.setModel((String) toscaElement.getMetadataValue(JsonPresentationFields.MODEL));
         component.setToscaType(toscaElement.getToscaType().getValue());
         final List<MetadataKeyDataDefinition> metadataKeys = getCategorySpecificMetadataKeys(toscaElement);
         if (CollectionUtils.isNotEmpty(metadataKeys)) {
@@ -1331,6 +1331,8 @@ public class ModelConverter {
         toscaElement.setMetadataValue(JsonPresentationFields.TAGS, component.getTags());
         toscaElement.setMetadataValue(JsonPresentationFields.INVARIANT_UUID, component.getInvariantUUID());
         toscaElement.setMetadataValue(JsonPresentationFields.CONTACT_ID, component.getContactId());
+        toscaElement.setMetadataValue(JsonPresentationFields.MODEL, component.getModel());
+        toscaElement.setModel(component.getModel());
         for (final String key : component.getCategorySpecificMetadata().keySet()) {
             toscaElement.setMetadataValue(key, component.getCategorySpecificMetadata().get(key));
         }
index 96c1613..474a66e 100644 (file)
@@ -80,5 +80,6 @@ public class UiComponentDataTransfer {
     private Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces;
     private String derivedFromGenericType;
     private String derivedFromGenericVersion;
+    private String model;
 
 }
index 09cee8b..a0d7873 100644 (file)
@@ -63,6 +63,7 @@ public abstract class UiComponentMetadata {
     private Boolean isArchived;
     private Long archiveTime;
     private Boolean isVspArchived;
+    private String model;
 
     public UiComponentMetadata() {
     }
@@ -98,5 +99,6 @@ public abstract class UiComponentMetadata {
         this.isArchived = metadata.isArchived();
         this.archiveTime = metadata.getArchiveTime();
         this.isVspArchived = metadata.isVspArchived();
+        this.model = metadata.getModel();
     }
 }
index e6c0a2d..a44aa44 100644 (file)
@@ -39,6 +39,7 @@ public class UiServiceMetadata extends UiComponentMetadata {
     private String instantiationType;
     private String serviceFunction;
     private Map<String, String> categorySpecificMetadata;
+    private String model;
 
     public UiServiceMetadata(List<CategoryDefinition> categories, ServiceMetadataDataDefinition metadata) {
         super(categories, metadata);
@@ -51,5 +52,6 @@ public class UiServiceMetadata extends UiComponentMetadata {
         this.instantiationType = metadata.getInstantiationType();
         this.serviceFunction = metadata.getServiceFunction();
         this.categorySpecificMetadata = metadata.getCategorySpecificMetadata();
+        this.model = metadata.getModel();
     }
 }
index be92f76..a60d7be 100644 (file)
@@ -146,6 +146,7 @@ export abstract class Component implements IComponent {
     public categorySpecificMetadata: Metadata = new Metadata();
     public derivedFromGenericType: string;
     public derivedFromGenericVersion: string;
+    public model: Model;
 
     constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) {
         if (component) {
@@ -210,6 +211,7 @@ export abstract class Component implements IComponent {
 
             this.derivedFromGenericType = component.derivedFromGenericType;
             this.derivedFromGenericVersion = component.derivedFromGenericVersion;
+            this.model = component.model;
         }
 
         //custom properties
diff --git a/catalog-ui/src/app/models/model.ts b/catalog-ui/src/app/models/model.ts
new file mode 100644 (file)
index 0000000..239d86e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+* ============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=========================================================
+*/
+
+interface Model {
+  name:string;
+}
index 38cd272..de62091 100644 (file)
@@ -44,6 +44,7 @@ import { HomeService } from '../ng2/services/home.service';
 import { ModalService } from '../ng2/services/modal.service';
 import { OnboardingService } from '../ng2/services/onboarding.service';
 import { ElementService } from '../ng2/services/element.service';
+import { ModelService } from '../ng2/services/model.service';
 import { PluginsService } from '../ng2/services/plugins.service';
 import { PoliciesService as PoliciesServiceNg2 } from '../ng2/services/policies.service';
 import { SharingService } from '../ng2/services/sharing.service';
@@ -128,4 +129,5 @@ serviceModule.factory('ReqAndCapabilitiesService', downgradeInjectable(ReqAndCap
 serviceModule.factory('NodesFactory', downgradeInjectable(NodesFactory));
 serviceModule.service('OnboardingService', downgradeInjectable(OnboardingService));
 serviceModule.service('ElementService', downgradeInjectable(ElementService));
+serviceModule.service('ModelService', downgradeInjectable(ModelService));
 serviceModule.service('ImportVSPService', downgradeInjectable(ImportVSPService));
index 88a5610..bb11199 100644 (file)
@@ -100,6 +100,7 @@ import {CapabilitiesFilterPropertiesEditorComponentModule} from "./pages/composi
 import {InterfaceOperationHandlerModule} from "./pages/composition/interface-operatons/operation-creator/interface-operation-handler.module";
 import {AttributesOutputsModule} from "./pages/attributes-outputs/attributes-outputs.module";
 import { ElementService } from "./services/element.service";
+import { ModelService } from "./services/model.service";
 
 
 declare const __ENV__: string;
@@ -199,6 +200,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent
     ImportVSPService,
     OnboardingService,
     ElementService,
+    ModelService,
     ServiceServiceNg2,
     AutomatedUpgradeService,
     WorkflowServiceNg2,
diff --git a/catalog-ui/src/app/ng2/services/model.service.ts b/catalog-ui/src/app/ng2/services/model.service.ts
new file mode 100644 (file)
index 0000000..33d5729
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* ============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';
+
+@Injectable()
+export class ModelService {
+
+  protected baseUrl;
+
+  constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
+    this.baseUrl = sdcConfig.api.root;
+  }
+
+  getModels():Observable<Model[]> {
+    return this.http.get<Model[]>(this.baseUrl + "/v1/catalog/model");
+  }
+
+}
index 6011aab..96a2126 100644 (file)
@@ -61,6 +61,7 @@ export class ComponentGenericResponse  implements Serializable<ComponentGenericR
     public substitutionFilters: any;
     public derivedFromGenericType;
     public derivedFromGenericVersion;
+    public model:Model;
 
     deserialize (response): ComponentGenericResponse {
 
@@ -138,6 +139,9 @@ export class ComponentGenericResponse  implements Serializable<ComponentGenericR
         if(response.derivedFromGenericVersion) {
             this.derivedFromGenericVersion = response.derivedFromGenericVersion;
         }
+        if(response.model) {
+            this.model = response.model;
+        }
         return this;
     }
 }
index 119f2e3..3d52e00 100644 (file)
@@ -17,6 +17,7 @@ export * from './ng2/services/dynamic-component.service';
 export * from './ng2/services/event-bus.service';
 export * from './ng2/services/groups.service';
 export * from './ng2/services/element.service';
+export * from './ng2/services/model.service';
 
 export * from './ng2/services/component-services/component.service';
 export * from './ng2/services/component-services/component.service.factory';
index 667c6bc..2ff2af9 100644 (file)
@@ -199,6 +199,7 @@ export class ComponentFactory {
             component.setComponentMetadata(response.metadata);
             component.derivedFromGenericType = response.derivedFromGenericType;
             component.derivedFromGenericVersion = response.derivedFromGenericVersion;
+            component.model = response.model;
             deferred.resolve(component);
         });
         return deferred.promise;
index b456bec..9b7a92b 100644 (file)
@@ -33,7 +33,7 @@ import {
     ValidationUtils
 } from "app/utils";
 import {EventListenerService, ProgressService} from "app/services";
-import {CacheService, ElementService, ImportVSPService, OnboardingService} from "app/services-ng2";
+import {CacheService, ElementService, ModelService, ImportVSPService, OnboardingService} from "app/services-ng2";
 import {Component, IAppConfigurtaion, ICsarComponent, IMainCategory, IMetadataKey, ISubCategory, IValidate, Resource, Service} from "app/models";
 import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
 import {CATEGORY_SERVICE_METADATA_KEYS, PREVIOUS_CSAR_COMPONENT} from "../../../../utils/constants";
@@ -53,6 +53,10 @@ export class componentCategories {//categories field bind to this obj in order t
     selectedCategory:string;
 }
 
+export class componentModel {
+    selectedModel:string;
+}
+
 export interface IEnvironmentContext {
     defaultValue:string;
     validValues:Array<string>;
@@ -73,6 +77,7 @@ export interface IGeneralScope extends IWorkspaceViewModelScope {
     importCsarProProgressKey:string;
     browseFileLabel:string;
     componentCategories:componentCategories;
+    componentModel:componentModel;
     instantiationTypes:Array<instantiationType>;
     isHiddenCategorySelected: boolean;
 
@@ -95,6 +100,7 @@ export interface IGeneralScope extends IWorkspaceViewModelScope {
     onInstantiationTypeChange():void;
     updateIcon():void;
     possibleToUpdateIcon():boolean;
+    initModel():void;
 }
 
 // tslint:disable-next-line:max-classes-per-file
@@ -124,6 +130,7 @@ export class GeneralViewModel {
         'ComponentFactory',
         'ImportVSPService',
         'ElementService',
+        'ModelService',
         '$stateParams'
     ];
 
@@ -150,6 +157,7 @@ export class GeneralViewModel {
                 private ComponentFactory:ComponentFactory,
                 private importVSPService: ImportVSPService,
                 private elementService: ElementService,
+                private modelService: ModelService,
                 private $stateParams: any) {
 
         this.initScopeValidation();
@@ -270,6 +278,7 @@ export class GeneralViewModel {
             // Init Instantiation types
             this.$scope.initInstantiationTypes();
             this.$scope.initBaseTypes();
+            this.$scope.initModel();
         }
 
         if (this.cacheService.get(PREVIOUS_CSAR_COMPONENT)) { //keep the old component in the cache until checkout, so we dont need to pass it around
@@ -451,6 +460,15 @@ export class GeneralViewModel {
             }
         };
 
+        this.$scope.initModel = ():void => {
+            if (this.$scope.componentType === ComponentType.SERVICE) {
+                this.$scope.models = new Array();
+                this.modelService.getModels().subscribe((modelsFound: Model[]) => {
+                    modelsFound.forEach(model => {this.$scope.models.push(model.name)});})
+                this.$scope.models.filter(model => model.name === (<Service>this.$scope.component).model);
+            }
+        };
+
         this.$scope.initEnvironmentContext = ():void => {
             if (this.$scope.componentType === ComponentType.SERVICE) {
                 this.$scope.environmentContextObj = this.cacheService.get('UIConfiguration').environmentContext;
index d598e17..d2529f9 100644 (file)
                                </div>
                        </div>
 
-                    <!--------------------- Instantiation Type -------------------->
+                    <!--------------------- Base Type -------------------->
+
+                  <!--------------------- Model -------------------->
+                  <div class="i-sdc-form-item" data-ng-if="component.isService()">
+                    <label class="i-sdc-form-label">Model</label>
+                    <select class="i-sdc-form-select"
+                            name="modelName"
+                            data-ng-class="{'view-mode': isViewMode()}"
+                            data-ng-disabled="component.isCsarComponent() || !isCreateMode()"
+                            data-ng-model="component.model"
+                            data-tests-id="modelName">
+                      <option value="">SDC AID</option>
+                      <option ng-repeat="model in models | orderBy:[name]">{{model}}</option>
+                    </select>
+                  </div>
+                  <!--------------------- Model -------------------->
 
                     <div class="meta-data" data-ng-if="component.creationDate">
                         <div>