TopologyTemplateResource { @PUT @Path("availablefeatures") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public TTopologyTemplate applyAvailableFeatures(ArrayList<AvailableFeaturesApiData> featuresList) { Map<String, Map<QName, String>> featureMap = new HashMap<>(); featuresList.forEach(availableFeaturesApiData -> { HashMap<QName, String> featureTypesMap = new HashMap<>(); if (Objects.nonNull(availableFeaturesApiData.getFeatures()) && availableFeaturesApiData.getFeatures().size() > 0) { availableFeaturesApiData.getFeatures() .forEach(features -> featureTypesMap.put(features.getType(), features.getFeatureName())); featureMap.put(availableFeaturesApiData.getNodeTemplateId(), featureTypesMap); } }); TTopologyTemplate enrichedTopology = EnhancementUtils.applyFeaturesForTopology(this.topologyTemplate, featureMap); this.parent.setTopology(enrichedTopology, this.type); RestUtils.persist(this.parent); return enrichedTopology; } TopologyTemplateResource(AbstractComponentInstanceResourceContainingATopology parent, TTopologyTemplate topologyTemplate, String type); @GET @ApiOperation(value = "?edit is used in the URL to get the jsPlumb-based editor") @Produces(MediaType.TEXT_HTML) // @formatter:off Response getHTML(
        @QueryParam(value = "edit") String edit,
        @QueryParam(value = "script") @ApiParam(value = "the script to include in a <script> tag. The function wineryViewExternalScriptOnLoad if it is defined. Only available if 'view' is also set") String script,
        @QueryParam(value = "view") String view,
        @QueryParam(value = "autoLayoutOnLoad") String autoLayoutOnLoad,
        @Context UriInfo uriInfo); @GET @ApiOperation(value = "Returns a JSON representation of the topology template." + "X and Y coordinates are embedded as attributes. QName string with Namespace: " + "{@link org.eclipse.winery.repository.common.constants.Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE}" + "@return The JSON representation of the topology template <em>without</em> associated artifacts and without the parent service template") @Produces(MediaType.APPLICATION_JSON) // @formatter:on TTopologyTemplate getTopologyTempalte(); @Path("merge/") @Consumes(MediaType.TEXT_PLAIN) @POST Response mergeWithOtherTopologyTemplate(String strOtherServiceTemplateQName); @Path("nodetemplates/") NodeTemplatesResource getNodeTemplatesResource(); @Path("relationshiptemplates/") RelationshipTemplatesResource getRelationshipTemplatesResource(); @PUT @ApiOperation(value = "Replaces the topology by the information given in the XML") @Consumes(MediaType.TEXT_XML) Response setModel(TTopologyTemplate topologyTemplate); @PUT @ApiOperation(value = "Replaces the topology by the information given in the JSON") @Consumes(MediaType.APPLICATION_JSON) Response setModelJson(TTopologyTemplate topologyTemplate); @GET @ApiOperation(value = "<p>Returns an XML representation of the topology template." + " X and Y coordinates are embedded as attributes. Namespace:" + "{@link org.eclipse.winery.repository.common.constants.Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE} </p>" + "<p>{@link org.eclipse.winery.repository.client.WineryRepositoryClient." + "getTopologyTemplate(QName)} consumes this template</p>" + "<p>@return The XML representation of the topology template <em>without</em>" + "associated artifacts and without the parent service template </p>") @Produces( {MediaType.APPLICATION_XML, MediaType.TEXT_XML}) // @formatter:on Response getComponentInstanceXML(); @Path("split/") @Produces(MediaType.TEXT_PLAIN) @POST Response split(@Context UriInfo uriInfo); @Path("match/") @Produces(MediaType.TEXT_PLAIN) @POST Response match(@Context UriInfo uriInfo); @Path("allocate") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @POST Response allocate(@Context UriInfo uriInfo, AllocationRequest allocationRequest); @POST @Path("compose/") @Consumes( {MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON}) @Produces( {MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON}) Response composeServiceTemplates(CompositionData compositionData, @Context UriInfo uriInfo); @POST @Path("resolve/") @Produces(MediaType.TEXT_PLAIN) Response resolve(@Context UriInfo uriInfo); @POST @Path("kvcomparison") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) PropertyDiffList computeDi(UpdateInfo updateInfo); @POST @Path("update") @Consumes(MediaType.APPLICATION_JSON) TTopologyTemplate updateVersionOfNodeTemplate(UpdateInfo updateInfo); @POST @Path("applysolution") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) TTopologyTemplate applySolution(SolutionInputData data); @GET @Produces(MediaType.APPLICATION_JSON) @Path("determinestatefulcomponents") TTopologyTemplate determineStatefulComponents(); @GET @Produces(MediaType.APPLICATION_JSON) @Path("determinefreezablecomponents") TopologyAndErrorList determineFreezableComponents(); @GET @Produces(MediaType.APPLICATION_JSON) @Path("cleanfreezablecomponents") TTopologyTemplate cleanFreezableComponents(); @GET @Path("availablefeatures") @Produces(MediaType.APPLICATION_JSON) ArrayList<AvailableFeaturesApiData> getAvailableFeatures(); @PUT @Path("availablefeatures") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) TTopologyTemplate applyAvailableFeatures(ArrayList<AvailableFeaturesApiData> featuresList); @GET @Path("newversions") @Produces(MediaType.APPLICATION_JSON) List<NewVersionListElement> getNewVersionList(); @POST @Path("applyplacement") @Produces(MediaType.APPLICATION_JSON) Response applyGroupingAndPlacement(@Context UriInfo uriInfo);  }
@Test public void applyAvailableFeatures() throws Exception { this.setRevisionTo("origin/plain"); this.assertPutWithResponse("servicetemplates/http%253A%252F%252Fopentosca.org%252Fadd%252Fmanagement%252Fto%252Finstances%252Fservicetemplates/STWithBasicManagementOnly_w1-wip1/topologytemplate/availablefeatures", "entitytypes/servicetemplates/topologytemplates/availableFeaturesForBasicManagementST.json"); }