use of org.eclipse.winery.repository.backend.IRepository in project winery by eclipse.
the class DataFlowResource method parseDataFlowToServiceTemplate.
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response parseDataFlowToServiceTemplate(DataFlowModel dataFlowModel) {
if (Objects.isNull(dataFlowModel)) {
return Response.status(Response.Status.BAD_REQUEST).entity("Passed data flow model is null!").build();
}
if (Objects.isNull(dataFlowModel.getId().getNamespaceURI())) {
return Response.status(Response.Status.BAD_REQUEST).entity("Namespace must be defined for the data flow " + "model ID!").build();
}
IRepository repo = RepositoryFactory.getRepository();
ServiceTemplateId templateId = new ServiceTemplateId(dataFlowModel.getId());
if (repo.exists(templateId)) {
return Response.status(Response.Status.CONFLICT).entity("ServiceTemplate with name of the data flow model already exists!").build();
}
TDefinitions definitions = BackendUtils.createWrapperDefinitionsAndInitialEmptyElement(repo, templateId);
TServiceTemplate serviceTemplate = definitions.getServiceTemplates().stream().filter(template -> template.getId().equals(templateId.getQName().getLocalPart()) && templateId.getQName().getNamespaceURI().equals(template.getTargetNamespace())).findFirst().orElse(null);
if (Objects.isNull(serviceTemplate)) {
return Response.serverError().entity("Unable to create ServiceTemplate for the given data flow model!").build();
}
TTopologyTemplate topology = serviceTemplate.getTopologyTemplate();
if (Objects.isNull(topology)) {
topology = new TTopologyTemplate.Builder().build();
}
// iterate over all filters of the data flow and create corresponding NodeTemplates
for (DataFlowModel.Filter filter : dataFlowModel.getFilters()) {
if (Objects.isNull(filter.getType())) {
return Response.serverError().entity("Type is missing for a filter!").build();
}
NodeTypeId nodeTypeId = BackendUtils.getDefinitionsChildId(NodeTypeId.class, filter.getType());
if (!repo.exists(nodeTypeId)) {
TNodeType newNodeType = new TNodeType.Builder(nodeTypeId.getQName().getLocalPart()).setTargetNamespace(nodeTypeId.getQName().getNamespaceURI()).build();
try {
BackendUtils.persist(repo, nodeTypeId, newNodeType);
} catch (IOException e) {
return Response.serverError().entity("Unable to create NodeType " + filter.getType() + " which is not contained in the repository!").build();
}
}
topology = handleFilter(topology, nodeTypeId, filter.getId(), filter.getProperties(), filter.getArtifacts(), filter.getLocation(), filter.getProvider());
if (Objects.isNull(topology)) {
return Response.serverError().entity("Unable to handle filter with name: " + filter.getId()).build();
}
}
// without available connectsTo RelationshipType the transformation can not be done
RelationshipTypeId relationTypeId = BackendUtils.getDefinitionsChildId(RelationshipTypeId.class, ToscaBaseTypes.connectsToRelationshipType);
if (!repo.exists(relationTypeId)) {
return Response.serverError().entity("Unable to parse data flow model without available connectsTo " + "RelationshipType!").build();
}
// create connectsTo RelationshipTemplates between NodeTemplates corresponding to connected filters
for (DataFlowModel.Pipes pipe : dataFlowModel.getPipes()) {
if (Objects.isNull(pipe.getSource()) || Objects.isNull(pipe.getTarget())) {
return Response.serverError().entity("Unable to create RelationshipTemplate for pipe with source or " + "target equal to null!").build();
}
TNodeTemplate source = topology.getNodeTemplate(pipe.getSource());
TNodeTemplate target = topology.getNodeTemplate(pipe.getTarget());
if (Objects.isNull(source) || Objects.isNull(target)) {
return Response.serverError().entity("Unable to find NodeTemplates for relation with source: " + pipe.getSource() + " and target: " + pipe.getTarget()).build();
}
TRelationshipTemplate relationshipTemplate = createRelationshipTemplate(relationTypeId, source, target, pipe.getDataTransferType());
if (Objects.isNull(relationshipTemplate)) {
return Response.serverError().entity("Unable to create RelationshipTemplate between " + source.getId() + " and " + target.getId()).build();
}
topology.addRelationshipTemplate(relationshipTemplate);
}
serviceTemplate.setTopologyTemplate(topology);
try {
BackendUtils.persist(repo, templateId, definitions);
return Response.created(new URI(RestUtils.getAbsoluteURL(templateId))).build();
} catch (IOException e) {
return Response.serverError().entity("IOException while persisting ServiceTemplate for data flow model!").build();
} catch (URISyntaxException e) {
return Response.serverError().entity("Unable to parse URI for created ServiceTemplate!").build();
}
}
use of org.eclipse.winery.repository.backend.IRepository in project winery by eclipse.
the class GenericArtifactsResource method generateArtifact.
/**
* @return TImplementationArtifact | TDeploymentArtifact (XML) | URL of generated IA zip (in case of autoGenerateIA)
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Creates a new implementation/deployment artifact. If an implementation artifact with the same name already exists, it is <em>overridden</em>.")
@SuppressWarnings("unchecked")
public Response generateArtifact(GenerateArtifactApiData apiData, @Context UriInfo uriInfo) {
// we assume that the parent ComponentInstance container exists
final IRepository repository = RepositoryFactory.getRepository();
if (StringUtils.isEmpty(apiData.artifactName)) {
return Response.status(Status.BAD_REQUEST).entity("Empty artifactName").build();
}
if (StringUtils.isEmpty(apiData.artifactType)) {
if (StringUtils.isEmpty(apiData.artifactTemplateName) || StringUtils.isEmpty(apiData.artifactTemplateNamespace)) {
if (StringUtils.isEmpty(apiData.artifactTemplate)) {
return Response.status(Status.BAD_REQUEST).entity("No artifact type given and no template given. Cannot guess artifact type").build();
}
}
}
if (!StringUtils.isEmpty(apiData.autoGenerateIA)) {
if (StringUtils.isEmpty(apiData.javaPackage)) {
return Response.status(Status.BAD_REQUEST).entity("no java package name supplied for IA auto generation.").build();
}
if (StringUtils.isEmpty(apiData.interfaceName)) {
return Response.status(Status.BAD_REQUEST).entity("no interface name supplied for IA auto generation.").build();
}
}
// convert second calling form to first calling form
if (!StringUtils.isEmpty(apiData.artifactTemplate)) {
QName qname = QName.valueOf(apiData.artifactTemplate);
apiData.artifactTemplateName = qname.getLocalPart();
apiData.artifactTemplateNamespace = qname.getNamespaceURI();
}
Document doc = null;
// if invalid, abort and do not create anything
if (!StringUtils.isEmpty(apiData.artifactSpecificContent)) {
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
StringReader sr = new StringReader(apiData.artifactSpecificContent);
is.setCharacterStream(sr);
doc = db.parse(is);
} catch (Exception e) {
// FIXME: currently we allow a single element only. However, the content should be internally wrapped by an (arbitrary) XML element as the content will be nested in the artifact element, too
LOGGER.debug("Invalid content", e);
return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
// determine artifactTemplate and artifactType
ArtifactTypeId artifactTypeId;
ArtifactTemplateId artifactTemplateId = null;
boolean doAutoCreateArtifactTemplate = !(StringUtils.isEmpty(apiData.autoCreateArtifactTemplate) || apiData.autoCreateArtifactTemplate.equalsIgnoreCase("no") || apiData.autoCreateArtifactTemplate.equalsIgnoreCase("false"));
if (!doAutoCreateArtifactTemplate) {
// no auto creation
if (!StringUtils.isEmpty(apiData.artifactTemplateName) && !StringUtils.isEmpty(apiData.artifactTemplateNamespace)) {
QName artifactTemplateQName = new QName(apiData.artifactTemplateNamespace, apiData.artifactTemplateName);
artifactTemplateId = BackendUtils.getDefinitionsChildId(ArtifactTemplateId.class, artifactTemplateQName);
}
if (StringUtils.isEmpty(apiData.artifactType)) {
// derive the type from the artifact template
if (artifactTemplateId == null) {
return Response.status(Status.NOT_ACCEPTABLE).entity("No artifactTemplate and no artifactType provided. Deriving the artifactType is not possible.").build();
}
@NonNull final QName type = repository.getElement(artifactTemplateId).getType();
artifactTypeId = BackendUtils.getDefinitionsChildId(ArtifactTypeId.class, type);
} else {
// artifactTypeStr is directly given, use that
artifactTypeId = BackendUtils.getDefinitionsChildId(ArtifactTypeId.class, apiData.artifactType);
}
} else {
if (StringUtils.isEmpty(apiData.artifactType)) {
return Response.status(Status.BAD_REQUEST).entity("Artifact template auto creation requested, but no artifact type supplied.").build();
}
artifactTypeId = BackendUtils.getDefinitionsChildId(ArtifactTypeId.class, apiData.artifactType);
// ensure that given type exists
if (!repository.exists(artifactTypeId)) {
LOGGER.debug("Artifact type {} is created", apiData.artifactType);
final TArtifactType element = repository.getElement(artifactTypeId);
try {
repository.setElement(artifactTypeId, element);
} catch (IOException e) {
throw new WebApplicationException(e);
}
}
if (StringUtils.isEmpty(apiData.artifactTemplateName) || StringUtils.isEmpty(apiData.artifactTemplateNamespace)) {
// no explicit name provided
// we use the artifactNameStr as prefix for the
// artifact template name
// we create a new artifact template in the namespace of the parent
// element
Namespace namespace = this.resWithNamespace.getNamespace();
artifactTemplateId = new ArtifactTemplateId(namespace, new XmlId(apiData.artifactName + "artifactTemplate", false));
} else {
QName artifactTemplateQName = new QName(apiData.artifactTemplateNamespace, apiData.artifactTemplateName);
artifactTemplateId = new ArtifactTemplateId(artifactTemplateQName);
}
// even if artifactTemplate does not exist, it is loaded
final TArtifactTemplate artifactTemplate = repository.getElement(artifactTemplateId);
artifactTemplate.setType(artifactTypeId.getQName());
try {
repository.setElement(artifactTemplateId, artifactTemplate);
} catch (IOException e) {
throw new WebApplicationException(e);
}
}
// variable artifactTypeId is set
// variable artifactTemplateId is not null if artifactTemplate has been generated
// we have to generate the DA/IA resource now
// Doing it here instead of doing it at the subclasses is dirty on the
// one hand, but quicker to implement on the other hand
// Create the artifact itself
ArtifactT resultingArtifact;
if (this instanceof ImplementationArtifactsResource) {
TImplementationArtifact.Builder builder = new TImplementationArtifact.Builder(artifactTypeId.getQName()).setName(apiData.artifactName).setInterfaceName(apiData.interfaceName).setOperationName(apiData.operationName);
if (artifactTemplateId != null) {
builder.setArtifactRef(artifactTemplateId.getQName());
}
if (doc != null) {
// the content has been checked for validity at the beginning of the method.
// If this point in the code is reached, the XML has been parsed into doc
// just copy over the dom node. Hopefully, that works...
builder.setAny(Collections.singletonList(doc.getDocumentElement()));
}
resultingArtifact = (ArtifactT) builder.build();
} else {
// for comments see other branch
TDeploymentArtifact.Builder builder = new TDeploymentArtifact.Builder(apiData.artifactName, artifactTypeId.getQName());
if (artifactTemplateId != null) {
builder.setArtifactRef(artifactTemplateId.getQName());
}
if (doc != null) {
builder.setAny(Collections.singletonList(doc.getDocumentElement()));
}
resultingArtifact = (ArtifactT) builder.build();
}
this.list.add(resultingArtifact);
// TODO: Check for error, and in case one found return it
RestUtils.persist(super.res);
if (StringUtils.isEmpty(apiData.autoGenerateIA)) {
// No IA generation
return Response.created(URI.create(EncodingUtil.URLencode(apiData.artifactName))).entity(resultingArtifact).build();
} else {
// after everything was created, we fire up the artifact generation
return this.generateImplementationArtifact(apiData.interfaceName, apiData.javaPackage, uriInfo, artifactTemplateId);
}
}
use of org.eclipse.winery.repository.backend.IRepository in project winery by eclipse.
the class GenericArtifactsResource method generateImplementationArtifact.
/**
* Generates the implementation artifact using the implementation artifact generator. Also sets the properties
* according to the requirements of OpenTOSCA.
*/
private Response generateImplementationArtifact(String interfaceName, String javaPackage, UriInfo uriInfo, ArtifactTemplateId artifactTemplateId) {
assert (this instanceof ImplementationArtifactsResource);
IRepository repository = RepositoryFactory.getRepository();
QName type = RestUtils.getType(this.res);
EntityTypeId typeId = getTypeId(type).orElseThrow(IllegalStateException::new);
TInterface i = findInterface(typeId, interfaceName).orElseThrow(IllegalStateException::new);
Path workingDir;
try {
workingDir = Files.createTempDirectory("winery");
} catch (IOException e2) {
LOGGER.debug("Could not create temporary directory", e2);
return Response.serverError().entity("Could not create temporary directory").build();
}
URI artifactTemplateFilesUri = uriInfo.getBaseUri().resolve(RestUtils.getAbsoluteURL(artifactTemplateId)).resolve("files");
URL artifactTemplateFilesUrl;
try {
artifactTemplateFilesUrl = artifactTemplateFilesUri.toURL();
} catch (MalformedURLException e2) {
LOGGER.debug("Could not convert URI to URL", e2);
return Response.serverError().entity("Could not convert URI to URL").build();
}
String name = this.generateName(typeId, interfaceName);
Generator gen = new Generator(i, javaPackage, artifactTemplateFilesUrl, name, workingDir.toFile());
Path targetPath;
try {
targetPath = gen.generateProject();
} catch (Exception e) {
LOGGER.debug("IA generator failed", e);
return Response.serverError().entity("IA generator failed").build();
}
DirectoryId fileDir = new ArtifactTemplateSourceDirectoryId(artifactTemplateId);
try {
BackendUtils.importDirectory(targetPath, repository, fileDir);
} catch (IOException e) {
throw new WebApplicationException(e);
}
// clean up
FileUtils.forceDelete(workingDir);
this.storeProperties(artifactTemplateId, typeId, name);
URI url = uriInfo.getBaseUri().resolve(Util.getUrlPath(artifactTemplateId));
return Response.created(url).build();
}
use of org.eclipse.winery.repository.backend.IRepository in project winery by eclipse.
the class DataFlowResource method mergeTemplateForDataSource.
/**
* Replace a filter corresponding to a running and placed data source by a ServiceTemplate with the same location
* and provider tag which contains a NodeTemplate of the NodeType specified for the data source filter.
*/
private TTopologyTemplate mergeTemplateForDataSource(TTopologyTemplate topology, NodeTypeId nodeTypeId, String templateName, Map<String, String> properties, String location, String provider) {
// get all ServiceTemplates in the repo
IRepository repo = RepositoryFactory.getRepository();
List<ServiceTemplateId> serviceTemplateIds = repo.getAllDefinitionsChildIds().stream().filter(id -> id.getGroup().equals(SERVICE_TEMPLATE_GROUP) && id instanceof ServiceTemplateId).map(id -> (ServiceTemplateId) id).collect(Collectors.toList());
for (ServiceTemplateId id : serviceTemplateIds) {
TServiceTemplate serviceTemplate = repo.getElement(id);
// only ServiceTemplates with location and provider tags are possible substitution candidates
if (containsMatchingTags(serviceTemplate, location, provider) && containsMatchingNodeType(serviceTemplate, nodeTypeId)) {
LOGGER.debug("Found suited substitution candidate for filter {}: {}", templateName, id.getQName());
TTopologyTemplate substitutionTopology = serviceTemplate.getTopologyTemplate();
TNodeTemplate filterCorrespondingNode = null;
LinkedHashMap<String, String> filterCorrespondingNodeProperties = null;
Map<String, String> nameMap = new HashMap<>();
if (substitutionTopology == null) {
continue;
}
// insert all NodeTemplates from the substitution candidate
for (TNodeTemplate node : substitutionTopology.getNodeTemplates()) {
LinkedHashMap<String, String> propertyList = ModelUtilities.getPropertiesKV(node);
if (propertyList == null) {
propertyList = new LinkedHashMap<>();
}
if (node.getType().equals(nodeTypeId.getQName())) {
// the NodeTemplate from the data flow model must be renamed to the given name
nameMap.put(node.getId(), templateName);
node.setId(templateName);
filterCorrespondingNode = node;
filterCorrespondingNodeProperties = propertyList;
} else if (Objects.nonNull(topology.getNodeTemplate(node.getId()))) {
// all existing names must be changed too
while (Objects.nonNull(topology.getNodeTemplate(node.getId() + "-" + IdCounter))) {
IdCounter++;
}
nameMap.put(node.getId(), node.getId() + "-" + IdCounter);
node.setId(node.getId() + "-" + IdCounter);
}
// update properties of the NodeTemplate if they are set at the filter
Map<String, String> propertyCopy = new HashMap<>(properties);
for (String propertyName : propertyCopy.keySet()) {
if (propertyName != null && propertyList.containsKey(propertyName)) {
propertyList.put(propertyName, properties.get(propertyName));
properties.remove(propertyName);
}
}
// set the state of all components related to the data source to running
propertyList.put("State", "Running");
ModelUtilities.setPropertiesKV(node, propertyList);
topology.addNodeTemplate(node);
}
// add all properties that are not defined in the NodeTypes to the node corresponding to the filter
if (Objects.nonNull(filterCorrespondingNode)) {
LOGGER.debug("{} properties defined without property at a matching type. Adding to filter " + "NodeTemplate!", properties.size());
for (String propertyName : properties.keySet()) {
filterCorrespondingNodeProperties.put(propertyName, properties.get(propertyName));
}
ModelUtilities.setPropertiesKV(filterCorrespondingNode, filterCorrespondingNodeProperties);
// add location and provider attribute to the NodeTemplate
filterCorrespondingNode.getOtherAttributes().put(ModelUtilities.NODE_TEMPLATE_REGION, location);
filterCorrespondingNode.getOtherAttributes().put(ModelUtilities.NODE_TEMPLATE_PROVIDER, provider);
}
// add all relations from the substitution fragment to the incomplete topology
for (TRelationshipTemplate relation : substitutionTopology.getRelationshipTemplates()) {
// update source id if it was changed
String sourceId = relation.getSourceElement().getRef().getId();
if (nameMap.containsKey(sourceId)) {
TNodeTemplate nodeTemplate = topology.getNodeTemplate(nameMap.get(sourceId));
if (nodeTemplate != null) {
relation.setSourceNodeTemplate(nodeTemplate);
}
}
// update target id if it was changed
if (nameMap.containsKey(relation.getTargetElement().getRef().getId())) {
relation.setTargetNodeTemplate(topology.getNodeTemplate(nameMap.get(relation.getTargetElement().getRef().getId())));
}
// update id if RelationshipTemplate with same id exists
if (Objects.nonNull(topology.getRelationshipTemplate(relation.getId()))) {
while (Objects.nonNull(topology.getRelationshipTemplate(relation.getId() + "-" + IdCounter))) {
IdCounter++;
}
relation.setId(relation.getId() + "-" + IdCounter);
}
topology.addRelationshipTemplate(relation);
}
return topology;
}
}
// no substitution of data source possible
return null;
}
use of org.eclipse.winery.repository.backend.IRepository in project winery by eclipse.
the class AdminTopResource method checkConsistency.
@GET
@Path("consistencycheck")
@Produces(MediaType.APPLICATION_JSON)
public ConsistencyErrorCollector checkConsistency(@QueryParam("serviceTemplatesOnly") boolean serviceTemplatesOnly, @QueryParam("checkDocumentation") boolean checkDocumentation) {
IRepository repo = RepositoryFactory.getRepository();
EnumSet<ConsistencyCheckerVerbosity> verbosity = EnumSet.of(ConsistencyCheckerVerbosity.NONE);
ConsistencyCheckerConfiguration config = new ConsistencyCheckerConfiguration(serviceTemplatesOnly, checkDocumentation, verbosity, repo);
final ConsistencyChecker consistencyChecker = new ConsistencyChecker(config);
consistencyChecker.checkCorruption();
return consistencyChecker.getErrorCollector();
}
Aggregations