use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class PlacementUtils method assignToProviders.
/**
* Assigns a provider to each component of the given TopologyTemplate based on requirements like privacy. As many
* components as possible are assigned to the same provider in a location to profit from fast connections in the
* same data center or possible discounts.
*
* @param topology the incomplete TopologyTemplate to assign providers to the components
* @param blackList the black list containing the NodeTemplates with the providers that are not usable for them
*/
private static void assignToProviders(TTopologyTemplate topology, Map<String, List<String>> blackList) {
Set<String> locations = getAllLocations(topology);
for (String location : locations) {
LOGGER.debug("Trying to assign components for location {} to suited provider.", location);
// maps providers to the NodeTemplates that are supported
HashMap<String, List<TNodeTemplate>> providers = new HashMap<>();
// all nodes that are assigned to the current location and are not yet assigned to a provider
List<TNodeTemplate> nodesForLocation = getNodeTemplatesWithLocation(topology).stream().filter(node -> getLocation(node).equalsIgnoreCase(location)).filter(node -> Objects.isNull(getProvider(node))).collect(Collectors.toList());
for (TNodeTemplate node : nodesForLocation) {
LOGGER.debug("Trying to assign NodeTemplate {} to provider in location {}", node.getId(), location);
List<String> viableProviders = getViableProviders(node, location, blackList);
if (viableProviders.isEmpty()) {
throw new InvalidParameterException("No viable provider found for NodeTemplate " + node.getId() + ". Aborting placement!");
}
// add NodeTemplate to the list of supported components of all viable providers
for (String provider : viableProviders) {
List<TNodeTemplate> supportedComps;
if (providers.containsKey(provider)) {
supportedComps = providers.get(provider);
} else {
supportedComps = new ArrayList<>();
}
supportedComps.add(node);
providers.put(provider, supportedComps);
}
}
// add the data sources to the providers to which they are already assigned
List<TNodeTemplate> dataSourcesForLocation = getNodeTemplatesWithLocation(topology).stream().filter(node -> getLocation(node).equalsIgnoreCase(location)).filter(node -> Objects.nonNull(getProvider(node))).collect(Collectors.toList());
for (TNodeTemplate dataSource : dataSourcesForLocation) {
String provider = getProvider(dataSource);
if (providers.containsKey(provider)) {
List<TNodeTemplate> supportedComps = providers.get(provider);
supportedComps.add(dataSource);
providers.put(provider, supportedComps);
}
}
// assign all NodeTemplates with the current location to one of the providers
while (!nodesForLocation.isEmpty()) {
// get the next provider that supports most of the unassigned NodeTemplates
String nextProv = getNextProvider(providers);
LOGGER.debug("Assigning {} NodeTemplates to next provider: {}", providers.get(nextProv).size(), nextProv);
for (TNodeTemplate node : providers.get(nextProv)) {
// assign the component to the provider and remove it from the set of to be assigned NodeTemplates
node.getOtherAttributes().put(ModelUtilities.NODE_TEMPLATE_PROVIDER, nextProv);
nodesForLocation.remove(node);
providers.remove(nextProv);
// remove assigned NodeTemplate from the list of all supporting providers
for (String provider : providers.keySet()) {
providers.get(provider).remove(node);
}
}
}
}
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Substitution method substituteTopologyOfServiceTemplate.
public ServiceTemplateId substituteTopologyOfServiceTemplate(final ServiceTemplateId serviceTemplateId) {
// 0. Create a new version of the Service Template
ServiceTemplateId substitutedServiceTemplateId = getSubstitutionServiceTemplateId(serviceTemplateId);
TServiceTemplate serviceTemplate = repository.getElement(substitutedServiceTemplateId);
TTopologyTemplate topology = Objects.requireNonNull(serviceTemplate.getTopologyTemplate());
loadAllRequiredDefinitionsForTopologySubstitution();
// 1. Step: retrieve all Node Templates which must be substituted
Map<TNodeTemplate, List<Subtypes<TNodeType>>> substitutableNodeTemplates = SubstitutionUtils.collectSubstitutableTemplates(topology.getNodeTemplates(), this.nodeTypes);
// 2. Step: retrieve all Relationship Templates which must be substituted
Map<TRelationshipTemplate, List<Subtypes<TRelationshipType>>> substitutableRelationshipTemplates = SubstitutionUtils.collectSubstitutableTemplates(topology.getRelationshipTemplates(), this.relationshipTypes);
// 3. Step: select concrete type to be substituted
Map<TNodeTemplate, TNodeType> nodeTemplateReplacementMap = new FindFirstSubstitutionStrategy<TNodeTemplate, TNodeType>().getReplacementMap(substitutableNodeTemplates);
Map<TRelationshipTemplate, TRelationshipType> relationshipTemplateReplacementMap = new FindFirstSubstitutionStrategy<TRelationshipTemplate, TRelationshipType>().getReplacementMap(substitutableRelationshipTemplates);
// 4. Step: update the topology
updateTopology(topology, nodeTemplateReplacementMap, relationshipTemplateReplacementMap);
try {
BackendUtils.persist(repository, substitutedServiceTemplateId, serviceTemplate);
} catch (IOException e) {
LOGGER.debug("Could not persist Service Template", e);
}
return substitutedServiceTemplateId;
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Substitution method replaceNodeTemplateWithServiceTemplate.
private void replaceNodeTemplateWithServiceTemplate(TTopologyTemplate topologyTemplate, Map<TNodeTemplate, TServiceTemplate> nodeTemplateToBeSubstitutedWithTopology) {
nodeTemplateToBeSubstitutedWithTopology.forEach((substitutableNodeTemplate, stSubstitutingTheNodeTemplate) -> {
if (Objects.nonNull(stSubstitutingTheNodeTemplate.getBoundaryDefinitions())) {
TTopologyTemplate topologyToImport = stSubstitutingTheNodeTemplate.getTopologyTemplate();
// 1. get all references of the Node Template
// 1.1 Relationships
// TODO 1.2 Boundary definitions
List<TRelationshipTemplate> ingoingRelations = new ArrayList<>();
List<TRelationshipTemplate> outgoingRelations = new ArrayList<>();
topologyTemplate.getRelationshipTemplates().forEach(tRelationshipTemplate -> {
if (substitutableNodeTemplate.getId().equals(tRelationshipTemplate.getSourceElement().getRef().getId())) {
outgoingRelations.add(tRelationshipTemplate);
}
if (substitutableNodeTemplate.getId().equals(tRelationshipTemplate.getTargetElement().getRef().getId())) {
ingoingRelations.add(tRelationshipTemplate);
}
});
// 2. import the topology in the Service Template
BackendUtils.mergeTopologyTemplateAinTopologyTemplateB(topologyToImport, topologyTemplate);
// 3. update the references accordingly
if (topologyToImport != null && ingoingRelations.size() > 0) {
if (Objects.nonNull(stSubstitutingTheNodeTemplate.getBoundaryDefinitions().getCapabilities())) {
List<TCapabilityRef> capabilities = stSubstitutingTheNodeTemplate.getBoundaryDefinitions().getCapabilities();
ingoingRelations.forEach(ingoing -> capabilities.forEach(tCapabilityRef -> topologyToImport.getNodeTemplates().stream().filter(tNodeTemplate -> Objects.nonNull(tNodeTemplate.getCapabilities())).filter(tNodeTemplate -> tNodeTemplate.getCapabilities().stream().anyMatch(tCapability -> tCapability.equals(tCapabilityRef.getRef()))).findFirst().ifPresent(tNodeTemplate -> ingoing.getTargetElement().setRef(tNodeTemplate))));
} else {
throw new UnsupportedOperationException("Mapping without Reqs/Caps is currently not supported");
}
}
if (topologyToImport != null && outgoingRelations.size() > 0) {
if (Objects.nonNull(stSubstitutingTheNodeTemplate.getBoundaryDefinitions().getRequirements())) {
List<TRequirementRef> requirements = stSubstitutingTheNodeTemplate.getBoundaryDefinitions().getRequirements();
outgoingRelations.forEach(outgoing -> requirements.forEach(requirementRef -> topologyToImport.getNodeTemplates().stream().filter(tNodeTemplate -> Objects.nonNull(tNodeTemplate.getRequirements()) && tNodeTemplate.getRequirements().stream().anyMatch(tRequirement -> tRequirement.equals(requirementRef.getRef()))).findFirst().ifPresent(tNodeTemplate -> outgoing.getSourceElement().setRef(tNodeTemplate))));
} else {
throw new UnsupportedOperationException("Mapping without Reqs/Caps is currently not supported");
}
}
// TODO: propagate property mappings
topologyTemplate.getNodeTemplateOrRelationshipTemplate().remove(substitutableNodeTemplate);
}
});
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class InstanceModelRefinementTest method completeRoundTripTest.
@Test
void completeRoundTripTest() throws Exception {
this.setRevisionTo("origin/plain");
// region ***** setup *****
InstanceModelRefinement modelRefinement = new InstanceModelRefinement(// simply iterate over all plugins and execute it once
new InstanceModelPluginChooser() {
private final String[] pluginOrder = { "Tomcat", "SpringWebApplication", "MySQL-DB", "MySQL-DBMS", "PetClinic" };
private int nextPlugin = 0;
@Override
public InstanceModelRefinementPlugin selectPlugin(TTopologyTemplate template, List<InstanceModelRefinementPlugin> plugins) {
if (nextPlugin < pluginOrder.length) {
String pluginId = pluginOrder[nextPlugin++];
Optional<InstanceModelRefinementPlugin> first = plugins.stream().filter(plugin -> plugin.getId().equals(pluginId)).findFirst();
if (first.isPresent()) {
InstanceModelRefinementPlugin plugin = first.get();
plugin.setSelectedMatchId(0);
if (plugin.getSubGraphs() != null && plugin.getSubGraphs().size() > 0 && plugin.getSubGraphs().get(0).additionalInputs != null) {
Map<String, String> inputs = new HashMap<>();
plugin.getSubGraphs().get(0).additionalInputs.forEach(input -> {
if (input.equals(InstanceModelUtils.vmIP)) {
inputs.put(InstanceModelUtils.vmIP, "localhost");
} else if (input.equals(InstanceModelUtils.vmPrivateKey)) {
InputStream resourceAsStream = Objects.requireNonNull(ClassLoader.getSystemClassLoader().getResourceAsStream("winery.test"));
try {
inputs.put(InstanceModelUtils.vmPrivateKey, IOUtils.toString(resourceAsStream));
} catch (IOException e) {
logger.error("Error while retrieving private key", e);
}
} else if (input.equals(InstanceModelUtils.vmUser)) {
inputs.put(InstanceModelUtils.vmUser, "test");
} else if (input.equals(InstanceModelUtils.vmSshPort)) {
inputs.put(InstanceModelUtils.vmSshPort, Integer.toString(sshPort));
}
});
inputs.put(InstanceModelUtils.vmSshPort, Integer.toString(sshPort));
plugin.setUserInputs(inputs, template, 0);
}
return plugin;
}
}
return null;
}
});
String expectedMySqlPort = "3306";
String expectedTomcatPort = "8080";
String expectedDatabaseUser = "dbTestUser";
String expectedDatabaseName = "testDatabase";
String expectedPetClinicContext = "petClinicTest";
sshd.setCommandFactory((channel, command) -> new SupportSuccessCommand(command) {
@Override
public String getReturnValue() {
if (this.getCommand().startsWith("sudo /usr/bin/mysql --help | grep Distrib")) {
return "5.7";
}
if (this.getCommand().startsWith("sudo netstat -tulpen | grep mysqld")) {
return expectedMySqlPort;
}
if (this.getCommand().startsWith("sudo -i mysql -sN -e \"SELECT schema_name from INFORMATION_SCHEMA.SCHEMATA") || (this.getCommand().startsWith("sudo cat /opt/tomcat/latest/webapps/") && this.getCommand().endsWith("| sed -r 's/USE (.*);$/\\1/'"))) {
return expectedDatabaseName;
}
if (this.getCommand().startsWith("sudo find /opt/tomcat/latest/webapps/") && this.getCommand().endsWith("| sed -r 's/database=(.*)$/\\1/'")) {
return "mysql";
}
if (this.getCommand().startsWith("sudo cat /opt/tomcat/latest/webapps/") && this.getCommand().endsWith("IDENTIFIED BY (.*);$/\\2/'")) {
return expectedDatabaseUser;
}
if (this.getCommand().startsWith("sudo find /opt/tomcat/latest/webapps -name *.war")) {
return expectedPetClinicContext;
}
if (this.getCommand().startsWith("sudo cat /opt/tomcat/latest/RELEASE-NOTES | grep 'Apache Tomcat")) {
return "9";
}
if (this.getCommand().startsWith("sudo cat /opt/tomcat/latest/conf/server.xml | grep '<Connector port=\".*\"")) {
return expectedTomcatPort;
}
return null;
}
});
// endregion
TTopologyTemplate topologyTemplate = modelRefinement.refine(new ServiceTemplateId("http://opentosca.org/servicetemplates", "InstancePluginsTest_w1-wip1", false));
// region ***** assertions *****
assertNotNull(topologyTemplate);
assertEquals(5, topologyTemplate.getNodeTemplates().size());
TNodeTemplate petClinic = topologyTemplate.getNodeTemplate("Pet_Clinic_w1_0");
assertNotNull(petClinic);
TEntityTemplate.Properties petClinicProperties = petClinic.getProperties();
assertNotNull(petClinicProperties);
assertTrue(petClinicProperties instanceof TEntityTemplate.WineryKVProperties);
assertEquals(expectedPetClinicContext, ((TEntityTemplate.WineryKVProperties) petClinicProperties).getKVProperties().get("context"));
TNodeTemplate mySqlDb = topologyTemplate.getNodeTemplate("MySQL-DB_0");
assertNotNull(mySqlDb);
TEntityTemplate.Properties mySqlDbProperties = mySqlDb.getProperties();
assertNotNull(mySqlDbProperties);
assertTrue(mySqlDbProperties instanceof TEntityTemplate.WineryKVProperties);
assertEquals(expectedDatabaseName, ((TEntityTemplate.WineryKVProperties) mySqlDbProperties).getKVProperties().get("DBName"));
assertEquals(expectedDatabaseUser, ((TEntityTemplate.WineryKVProperties) mySqlDbProperties).getKVProperties().get("DBUser"));
TNodeTemplate tomcat = topologyTemplate.getNodeTemplate("Tomcat_0");
assertNotNull(tomcat);
TEntityTemplate.Properties tomcatProperties = tomcat.getProperties();
assertNotNull(tomcatProperties);
assertEquals(QName.valueOf("{http://opentosca.org/nodetypes}Tomcat_9-w1"), tomcat.getType());
assertTrue(tomcatProperties instanceof TEntityTemplate.WineryKVProperties);
assertEquals(expectedTomcatPort, ((TEntityTemplate.WineryKVProperties) tomcatProperties).getKVProperties().get("Port"));
TNodeTemplate dbms = topologyTemplate.getNodeTemplate("MySQL-DBMS_0");
assertNotNull(dbms);
TEntityTemplate.Properties dbmsProperties = dbms.getProperties();
assertNotNull(dbmsProperties);
assertEquals(QName.valueOf("{http://opentosca.org/nodetypes}MySQL-DBMS_5.7-w1"), dbms.getType());
assertTrue(dbmsProperties instanceof TEntityTemplate.WineryKVProperties);
assertEquals(expectedMySqlPort, ((TEntityTemplate.WineryKVProperties) dbmsProperties).getKVProperties().get("DBMSPort"));
// endregion
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class InstanceModelRefinementTest method refineEmpty.
@Test
void refineEmpty() {
InstanceModelRefinement modelRefinement = new InstanceModelRefinement((template, plugins) -> null);
TTopologyTemplate topologyTemplate = modelRefinement.refine(new ServiceTemplateId("http://opentosca.org/servicetemplates", "myCoolNotExistingServiceTemplate", false));
assertNull(topologyTemplate);
}
Aggregations