Skip to content

Commit

Permalink
Add ability to manage EDMM types (winery#694)
Browse files Browse the repository at this point in the history
Signed-off-by: Ghareeb Falazi <[email protected]>
Co-authored-by: Lukas Harzenetter <[email protected]>
  • Loading branch information
ghareeb-falazi and lharzenetter authored Jan 12, 2023
1 parent 0e8f698 commit 86b6876
Show file tree
Hide file tree
Showing 37 changed files with 928 additions and 453 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,13 @@ static EdmmManager forRepository(IRepository repo) {
return new JsonBasedEdmmManager(repo.ref2AbsolutePath(ref).toFile());
}

List<EdmmMappingItem> getOneToOneMappings();

void setOneToOneMappings(List<EdmmMappingItem> list);
List<EdmmType> getEdmmTypes();

List<EdmmMappingItem> getTypeMappings();
void setEdmmTypes(List<EdmmType> newTypes);

void setTypeMappings(List<EdmmMappingItem> list);
List<EdmmMappingItem> getOneToOneMappings();

default Map<QName, EdmmType> getTypeMap() {
Map<QName, EdmmType> typeMappings = new HashMap<>();
this.getTypeMappings().forEach(m -> typeMappings.put(m.toscaType, m.edmmType));
return typeMappings;
}
void setOneToOneMappings(List<EdmmMappingItem> list);

default Map<QName, EdmmType> getOneToOneMap() {
Map<QName, EdmmType> typeMappings = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ public static ToscaLightChecker getToscaLightChecker() {

Map<QName, TRelationshipType> relationshipTypes = repository.getQNameToElementMapping(RelationshipTypeId.class);
Map<QName, TNodeType> nodeTypes = repository.getQNameToElementMapping(NodeTypeId.class);
Map<QName, EdmmType> typeMap = EdmmManager.forRepository(repository).getTypeMap();
Map<QName, EdmmType> oneToOneMap = EdmmManager.forRepository(repository).getOneToOneMap();

return new ToscaLightChecker(nodeTypes, relationshipTypes, typeMap, oneToOneMap);
return new ToscaLightChecker(nodeTypes, relationshipTypes, oneToOneMap);
}

public static Map<QName, TServiceTemplate> getAllToscaLightCompliantModels() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,40 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.eclipse.winery.common.json.JacksonProvider;
import org.eclipse.winery.edmm.model.EdmmMappingItem;

import org.eclipse.winery.edmm.model.EdmmType;

import io.github.edmm.model.component.Auth0;
import io.github.edmm.model.component.AwsAurora;
import io.github.edmm.model.component.AwsBeanstalk;
import io.github.edmm.model.component.Compute;
import io.github.edmm.model.component.Database;
import io.github.edmm.model.component.Dbaas;
import io.github.edmm.model.component.Dbms;
import io.github.edmm.model.component.Go;
import io.github.edmm.model.component.Mom;
import io.github.edmm.model.component.MongoDb;
import io.github.edmm.model.component.MongoDbSchema;
import io.github.edmm.model.component.MysqlDatabase;
import io.github.edmm.model.component.MysqlDbms;
import io.github.edmm.model.component.Paas;
import io.github.edmm.model.component.Platform;
import io.github.edmm.model.component.RabbitMq;
import io.github.edmm.model.component.RootComponent;
import io.github.edmm.model.component.Saas;
import io.github.edmm.model.component.SoftwareComponent;
import io.github.edmm.model.component.Tomcat;
import io.github.edmm.model.component.WebApplication;
import io.github.edmm.model.component.WebServer;
import io.github.edmm.model.relation.ConnectsTo;
import io.github.edmm.model.relation.DependsOn;
import io.github.edmm.model.relation.HostedOn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -31,45 +59,88 @@ public class JsonBasedEdmmManager implements EdmmManager {
private static final Logger LOGGER = LoggerFactory.getLogger(JsonBasedEdmmManager.class);

private final File file;
private final MappingsWrapper edmmMappings;
private final DataWrapper edmmTypes;

public JsonBasedEdmmManager(File file) {
Objects.requireNonNull(file);
this.file = file;
this.edmmMappings = this.loadMappingsFromFile();
this.edmmTypes = this.loadEdmmTypesFromFile();

// hopefully no race conditions occur :)
if (getEdmmTypes().isEmpty()) {
addDefaultEdmmTypes();
}
}

private void addDefaultEdmmTypes() {
List<EdmmType> defaultTypes = new ArrayList<>();
Arrays.stream(new Class[] {
Auth0.class,
AwsAurora.class,
AwsBeanstalk.class,
Compute.class,
Database.class,
Dbaas.class,
Dbms.class,
Go.class,
Mom.class,
MongoDb.class,
MongoDbSchema.class,
MysqlDatabase.class,
MysqlDbms.class,
Paas.class,
Platform.class,
RabbitMq.class,
RootComponent.class,
Saas.class,
SoftwareComponent.class,
Tomcat.class,
WebApplication.class,
WebServer.class,
DependsOn.class,
ConnectsTo.class,
HostedOn.class}).forEach(clazz -> defaultTypes.add(EdmmType.fromEntityClass(clazz)));
this.setEdmmTypes(defaultTypes);
}

@Override
public List<EdmmMappingItem> getOneToOneMappings() {
return this.edmmMappings.oneToOneMapping;
public List<EdmmType> getEdmmTypes() {
return this.edmmTypes.edmmTypes;
}

@Override
public void setOneToOneMappings(List<EdmmMappingItem> list) {
this.edmmMappings.oneToOneMapping = list;
public void setEdmmTypes(List<EdmmType> newTypes) {
this.edmmTypes.edmmTypes = newTypes;
this.save();
}

@Override
public List<EdmmMappingItem> getTypeMappings() {
return this.edmmMappings.edmmTypeMapping;
public List<EdmmMappingItem> getOneToOneMappings() {
return this.edmmTypes.oneToOneMapping;
}

@Override
public void setTypeMappings(List<EdmmMappingItem> list) {
this.edmmMappings.edmmTypeMapping = list;
public void setOneToOneMappings(List<EdmmMappingItem> list) {
Optional<EdmmMappingItem> mappingItem = list.stream().filter(i -> !getEdmmTypes().contains(i.edmmType)).findFirst();

if (mappingItem.isPresent()) {
throw new IllegalArgumentException("trying to add a mapping for a non-existing EDMM type: " +
mappingItem.get().edmmType.getValue());
}

this.edmmTypes.oneToOneMapping = list;
this.save();
}

private MappingsWrapper loadMappingsFromFile() {
MappingsWrapper edmmMappings = new MappingsWrapper();
private DataWrapper loadEdmmTypesFromFile() {
DataWrapper edmmMappings = new DataWrapper();

try {
if (this.file.exists()) {
edmmMappings = JacksonProvider.mapper.readValue(file, MappingsWrapper.class);
edmmMappings = JacksonProvider.mapper.readValue(file, DataWrapper.class);
}
} catch (IOException e) {
LOGGER.debug("Error while loading the namespace file.", e);
LOGGER.debug("Error while loading the edmm types file.", e);
throw new RuntimeException();
}

Expand All @@ -80,25 +151,25 @@ private void save() {
try {
if (!this.file.exists()) {
if (this.file.getParentFile().mkdirs() || this.file.createNewFile()) {
LOGGER.debug("Created new EDMM Mappings file at {}", this.file);
LOGGER.debug("Created new EDMM types file at {}", this.file);
} else {
LOGGER.error("Could not create EDMM Mappings file at {}", this.file);
LOGGER.error("Could not create EDMM types file at {}", this.file);
}
}

JacksonProvider.mapper.writeValue(this.file, this.edmmMappings);
JacksonProvider.mapper.writeValue(this.file, this.edmmTypes);
} catch (IOException e) {
LOGGER.debug("Could not save EDMM Mappings to json file!", e);
LOGGER.debug("Could not save EDMM types to json file!", e);
}
}

public static class MappingsWrapper {
public static class DataWrapper {
public List<EdmmMappingItem> oneToOneMapping;
public List<EdmmMappingItem> edmmTypeMapping;
public List<EdmmType> edmmTypes;

public MappingsWrapper() {
public DataWrapper() {
this.oneToOneMapping = new ArrayList<>();
this.edmmTypeMapping = new ArrayList<>();
this.edmmTypes = new ArrayList<>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.xml.namespace.QName;
Expand All @@ -44,7 +43,6 @@
import org.eclipse.winery.model.tosca.extensions.OTParticipant;
import org.eclipse.winery.model.tosca.utils.ModelUtilities;

import io.github.edmm.core.parser.Entity;
import io.github.edmm.core.parser.EntityGraph;
import io.github.edmm.core.parser.EntityId;
import io.github.edmm.core.parser.MappingEntity;
Expand All @@ -61,30 +59,28 @@ public class EdmmConverter {
private final Map<QName, TNodeTypeImplementation> nodeTypeImplementations;
private final Map<QName, TRelationshipTypeImplementation> relationshipTypeImplementations;
private final Map<QName, TArtifactTemplate> artifactTemplates;
private final Map<QName, EdmmType> edmmTypeMappings;
private final Map<QName, EdmmType> oneToOneMappings;
private final boolean useAbsolutePaths;

public EdmmConverter(Map<QName, TNodeType> nodeTypes, Map<QName, TRelationshipType> relationshipTypes,
Map<QName, TNodeTypeImplementation> nodeTypeImplementations,
Map<QName, TRelationshipTypeImplementation> relationshipTypeImplementations,
Map<QName, TArtifactTemplate> artifactTemplates,
Map<QName, EdmmType> edmmTypeMappings, Map<QName, EdmmType> oneToOneMappings) {
Map<QName, EdmmType> oneToOneMappings) {
this(nodeTypes, relationshipTypes, nodeTypeImplementations, relationshipTypeImplementations, artifactTemplates,
edmmTypeMappings, oneToOneMappings, true);
oneToOneMappings, true);
}

public EdmmConverter(Map<QName, TNodeType> nodeTypes, Map<QName, TRelationshipType> relationshipTypes,
Map<QName, TNodeTypeImplementation> nodeTypeImplementations,
Map<QName, TRelationshipTypeImplementation> relationshipTypeImplementations,
Map<QName, TArtifactTemplate> artifactTemplates, Map<QName, EdmmType> edmmTypeMappings,
Map<QName, TArtifactTemplate> artifactTemplates,
Map<QName, EdmmType> oneToOneMappings, boolean useAbsolutePaths) {
this.nodeTypes = nodeTypes;
this.relationshipTypes = relationshipTypes;
this.nodeTypeImplementations = nodeTypeImplementations;
this.relationshipTypeImplementations = relationshipTypeImplementations;
this.artifactTemplates = artifactTemplates;
this.edmmTypeMappings = edmmTypeMappings;
this.useAbsolutePaths = useAbsolutePaths;
this.oneToOneMappings = oneToOneMappings;
}
Expand Down Expand Up @@ -275,64 +271,41 @@ private void createProperties(TEntityTemplate toscaTemplate, EntityId componentN
entityGraph.addEntity(new ScalarEntity(name, propertyEntityId, entityGraph));
}

private EntityId createType(TEntityType toscaType, EntityId parentEntityId, EntityGraph entityGraph) {
if (!entityGraph.getEntity(parentEntityId).isPresent()) {
entityGraph.addEntity(new MappingEntity(parentEntityId, entityGraph));
private EntityId createType(TEntityType toscaType, EntityId typeRoot, EntityGraph entityGraph) {
if (!entityGraph.getEntity(typeRoot).isPresent()) {
entityGraph.addEntity(new MappingEntity(typeRoot, entityGraph));
}

EntityId typeEntityId = parentEntityId.extend(this.normalizeQName(toscaType.getQName()));
EntityId typeEntityId;
EdmmType edmmType = oneToOneMappings.get(toscaType.getQName());
typeEntityId = edmmType != null ?
typeRoot.extend(edmmType.getValue()) :
typeRoot.extend(this.normalizeQName(toscaType.getQName()));

if (edmmType != null) {
typeEntityId = parentEntityId.extend(edmmType.getValue());
entityGraph.addEntity(new MappingEntity(typeEntityId, entityGraph));
EdmmTypeProperties.getDefaultConfiguration(edmmType, entityGraph);

this.createPropertiesDefinition(toscaType, typeEntityId, entityGraph);
// the type we are trying to create is already there!
if (entityGraph.getEntity(typeEntityId).isPresent()) {
return typeEntityId;
}

if (Objects.nonNull(toscaType.getDerivedFrom())) {
QName inheritsFrom = toscaType.getDerivedFrom().getType();
TEntityType parent = toscaType instanceof TNodeType
? nodeTypes.get(inheritsFrom)
: relationshipTypes.get(inheritsFrom);
createType(parent, parentEntityId, entityGraph);
}
entityGraph.addEntity(new MappingEntity(typeEntityId, entityGraph));
EntityId parentEntityId;
String parentType;

if (Objects.nonNull(toscaType.getDerivedFrom())) {
QName inheritsFrom = toscaType.getDerivedFrom().getType();
TEntityType parent = toscaType instanceof TNodeType
? nodeTypes.get(inheritsFrom)
: relationshipTypes.get(inheritsFrom);
parentEntityId = createType(parent, typeRoot, entityGraph);
MappingEntity parentEntity = (MappingEntity) entityGraph.getEntity(parentEntityId).get();
parentType = parentEntity.getName();
} else {
Optional<Entity> entity = entityGraph.getEntity(typeEntityId);
if (!entity.isPresent()) {
entityGraph.addEntity(new MappingEntity(typeEntityId, entityGraph));

if (Objects.nonNull(toscaType.getDerivedFrom())) {
QName inheritsFrom = toscaType.getDerivedFrom().getType();
TEntityType parent = toscaType instanceof TNodeType
? nodeTypes.get(inheritsFrom)
: relationshipTypes.get(inheritsFrom);

EntityId baseTypeEntityId = createType(parent, parentEntityId, entityGraph);
entityGraph.addEntity(
new ScalarEntity(baseTypeEntityId.getName(), typeEntityId.extend(DefaultKeys.EXTENDS), entityGraph)
);
} else {
String parentElement = "base";

edmmType = edmmTypeMappings.get(toscaType.getQName());
if (edmmType != null) {
parentElement = edmmType.getValue();
EdmmTypeProperties.getDefaultConfiguration(edmmType, entityGraph);
} else if (toscaType instanceof TRelationshipType) {
parentElement = EdmmType.DEPENDS_ON.getValue();
EdmmTypeProperties.getDefaultConfiguration(EdmmType.DEPENDS_ON, entityGraph);
}

entityGraph.addEntity(
new ScalarEntity(parentElement, typeEntityId.extend(DefaultKeys.EXTENDS), entityGraph)
);
}

this.createPropertiesDefinition(toscaType, typeEntityId, entityGraph);
}
parentType = null;
}

entityGraph.addEntity(new ScalarEntity(parentType, typeEntityId.extend(DefaultKeys.EXTENDS), entityGraph));
this.createPropertiesDefinition(toscaType, typeEntityId, entityGraph);

return typeEntityId;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

package org.eclipse.winery.edmm.model;

import java.util.Objects;

import javax.xml.namespace.QName;

public class EdmmMappingItem {
Expand All @@ -28,4 +30,17 @@ public EdmmMappingItem(EdmmType edmmType, QName toscaType) {
this.edmmType = edmmType;
this.toscaType = toscaType;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EdmmMappingItem that = (EdmmMappingItem) o;
return Objects.equals(edmmType, that.edmmType) && Objects.equals(toscaType, that.toscaType);
}

@Override
public int hashCode() {
return Objects.hash(edmmType, toscaType);
}
}
Loading

0 comments on commit 86b6876

Please sign in to comment.