use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Splitting method resolveTopologyTemplate.
/**
*/
public void resolveTopologyTemplate(ServiceTemplateId serviceTemplateId) throws SplittingException, IOException {
IRepository repository = RepositoryFactory.getRepository();
TServiceTemplate serviceTemplate = repository.getElement(serviceTemplateId);
TTopologyTemplate topologyTemplate = serviceTemplate.getTopologyTemplate();
List<TRequirement> openRequirements = getOpenRequirements(topologyTemplate);
for (TRequirement requirement : openRequirements) {
QName requiredCapTypeQName = getRequiredCapabilityTypeQNameOfRequirement(requirement);
List<TNodeTemplate> nodesWithMatchingCapability = topologyTemplate.getNodeTemplates().stream().filter(nt -> nt.getCapabilities() != null).filter(nt -> nt.getCapabilities().stream().anyMatch(c -> c.getType().equals(requiredCapTypeQName))).collect(Collectors.toList());
if (!nodesWithMatchingCapability.isEmpty() && nodesWithMatchingCapability.size() == 1) {
TCapability matchingCapability = nodesWithMatchingCapability.get(0).getCapabilities().stream().filter(c -> c.getType().equals(requiredCapTypeQName)).findFirst().get();
TRelationshipType matchingRelationshipType = getMatchingRelationshipType(requirement, matchingCapability);
if (matchingRelationshipType != null) {
addMatchingRelationshipTemplateToTopologyTemplate(topologyTemplate, matchingRelationshipType, requirement, matchingCapability);
} else {
throw new SplittingException("No suitable relationship type found for matching");
}
}
}
repository.setElement(serviceTemplateId, serviceTemplate);
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Splitting method injectNodeTemplates.
/**
* Replaces the host of each key by the value of the map. Adds new relationships between the nodes and their new
* hosts
*
* @param topologyTemplate original topology for which the Node Templates shall be replaced
* @param injectNodes map with the Nodes to replace as key and the replacement as value
* @param removal remove nothing, only replaced nt or replaced nt and all successors
* @return modified topology with the replaced Node Templates
*/
public TTopologyTemplate injectNodeTemplates(TTopologyTemplate topologyTemplate, Map<String, TTopologyTemplate> injectNodes, InjectRemoval removal) throws SplittingException {
String id;
// Matching contains all cloud provider nodes matched to the topology
List<TNodeTemplate> matching = new ArrayList<>();
matching.clear();
LOGGER.debug("Start Matching Method");
Set<TNodeTemplate> replacedNodeTemplatesToDelete = new HashSet<>();
for (String predecessorOfNewHostId : injectNodes.keySet()) {
TNodeTemplate predecessorOfNewHost = topologyTemplate.getNodeTemplates().stream().filter(nt -> nt.getId().equals(predecessorOfNewHostId)).findFirst().orElse(null);
LOGGER.debug("Predecessor which get a new host " + predecessorOfNewHost.getId());
List<TNodeTemplate> originHostSuccessors = new ArrayList<>();
originHostSuccessors.clear();
originHostSuccessors = getHostedOnSuccessorsOfNodeTemplate(topologyTemplate, predecessorOfNewHost);
TRequirement openHostedOnRequirement = predecessorOfNewHost.getRequirements().stream().filter(req -> getBasisCapabilityType(getRequiredCapabilityTypeQNameOfRequirement(req)).getName().equals("Container")).findAny().get();
TNodeTemplate newMatchingNodeTemplate;
TTopologyTemplate matchingTopologyFragment = injectNodes.get(predecessorOfNewHostId);
// Highest Node Template to which the HostedOn Relationship has to be connected
TNodeTemplate newHostNodeTemplate = matchingTopologyFragment.getNodeTemplates().stream().filter(nt -> nt.getCapabilities() != null).filter(nt -> nt.getCapabilities().stream().anyMatch(cap -> cap.getType().equals(getRequiredCapabilityTypeQNameOfRequirement(openHostedOnRequirement)))).findFirst().get();
LOGGER.debug("New host NodeTemplate: {}", newHostNodeTemplate.getId());
// Check if the chosen replace node is already in the matching
if (topologyTemplate.getNodeTemplates().stream().anyMatch(nt -> equalsWithDifferentId(nt, newHostNodeTemplate))) {
newMatchingNodeTemplate = topologyTemplate.getNodeTemplates().stream().filter(nt -> equalsWithDifferentId(nt, newHostNodeTemplate)).findAny().get();
} else {
newMatchingNodeTemplate = newHostNodeTemplate;
matchingTopologyFragment.getNodeTemplateOrRelationshipTemplate().stream().filter(et -> topologyTemplate.getNodeTemplateOrRelationshipTemplate().stream().anyMatch(tet -> tet.getId().equals(et.getId()))).forEach(et -> et.setId(et.getId() + "_" + IdCounter++));
// rename capabilities and requirements
matchingTopologyFragment.getNodeTemplates().forEach(node -> {
List<TCapability> caps = node.getCapabilities();
if (Objects.nonNull(caps)) {
caps.stream().filter(et -> topologyTemplate.getNodeTemplates().stream().filter(nt -> Objects.nonNull(nt.getCapabilities())).flatMap(nt -> nt.getCapabilities().stream()).anyMatch(cap -> cap.getId().equals(et.getId()))).forEach(et -> et.setId(et.getId() + "_" + IdCounter++));
}
if (listIsNotNullOrEmpty(node.getRequirements())) {
node.getRequirements().stream().filter(et -> topologyTemplate.getNodeTemplates().stream().filter(nt -> Objects.nonNull(nt.getRequirements())).flatMap(nt -> nt.getRequirements().stream()).anyMatch(req -> req.getId().equals(et.getId()))).forEach(et -> et.setId(et.getId() + "_" + IdCounter++));
}
});
LOGGER.debug("Add {} NodeTemplate(s)", matchingTopologyFragment.getNodeTemplateOrRelationshipTemplate().size());
topologyTemplate.getNodeTemplateOrRelationshipTemplate().addAll(matchingTopologyFragment.getNodeTemplateOrRelationshipTemplate());
matching.add(newMatchingNodeTemplate);
}
// In case the predecessor was a lowest node a new hostedOn relationship has to be added
if (originHostSuccessors.isEmpty()) {
TRelationshipTemplate newHostedOnRelationship = new TRelationshipTemplate();
List<String> ids = new ArrayList<>();
List<TRelationshipTemplate> tRelationshipTemplates = ModelUtilities.getAllRelationshipTemplates(topologyTemplate);
tRelationshipTemplates.forEach(rt -> ids.add(rt.getId()));
// Check if counter is already set in another Id, if yes -> increase newRelationshipCounter +1
boolean uniqueID = false;
id = "0";
while (!uniqueID) {
if (!ids.contains("con" + newRelationshipIdCounter)) {
id = "con_" + newRelationshipIdCounter;
newRelationshipIdCounter++;
uniqueID = true;
} else {
newRelationshipIdCounter++;
}
}
newHostedOnRelationship.setId(id);
newHostedOnRelationship.setName(id);
TRelationshipTemplate.SourceOrTargetElement sourceElement = new TRelationshipTemplate.SourceOrTargetElement();
TRelationshipTemplate.SourceOrTargetElement targetElement = new TRelationshipTemplate.SourceOrTargetElement();
sourceElement.setRef(predecessorOfNewHost);
targetElement.setRef(newMatchingNodeTemplate);
newHostedOnRelationship.setSourceElement(sourceElement);
newHostedOnRelationship.setTargetElement(targetElement);
TRequirement requiredRequirement = null;
List<TRequirement> openRequirements = predecessorOfNewHost.getRequirements();
for (TRequirement requirement : openRequirements) {
QName requiredCapabilityTypeQName = getRequiredCapabilityTypeQNameOfRequirement(requirement);
TCapabilityType matchingBasisCapabilityType = getBasisCapabilityType(requiredCapabilityTypeQName);
if (matchingBasisCapabilityType.getName().equalsIgnoreCase("Container")) {
requiredRequirement = requirement;
}
}
TCapability requiredCapability = null;
List<TCapability> openCapabilities = newMatchingNodeTemplate.getCapabilities();
for (TCapability capability : openCapabilities) {
TCapabilityType basisCapabilityType = getBasisCapabilityType(capability.getType());
if (basisCapabilityType.getName().equalsIgnoreCase("Container")) {
requiredCapability = capability;
}
}
if (requiredRequirement == null || requiredCapability == null) {
throw new SplittingException("The predecessor or new host node has matching which requires a hostedOn relationship");
} else {
TRelationshipType relationshipType = getMatchingRelationshipType(requiredRequirement, requiredCapability);
if (relationshipType != null) {
QName relationshipTypeQName = new QName(relationshipType.getTargetNamespace(), relationshipType.getName());
newHostedOnRelationship.setType(relationshipTypeQName);
} else {
throw new SplittingException("No suitable relationship type available for hosting the node template with the ID " + predecessorOfNewHost.getId());
}
}
topologyTemplate.getNodeTemplateOrRelationshipTemplate().add(newHostedOnRelationship);
} else {
LOGGER.debug("Predecessor has successor NodeTemplates...");
// Assupmtion: Only one hostedOn Successor possible
TNodeTemplate originHost = originHostSuccessors.get(0);
List<TRelationshipTemplate> incomingRelationshipsOfReplacementCandidate = ModelUtilities.getIncomingRelationshipTemplates(topologyTemplate, originHost);
// The incoming Relationships not from the predecessors have to be copied
List<TRelationshipTemplate> incomingRelationshipsNotHostedOn = incomingRelationshipsOfReplacementCandidate.stream().filter(r -> !getHostedOnPredecessorsOfNodeTemplate(topologyTemplate, originHost).contains(ModelUtilities.getSourceNodeTemplateOfRelationshipTemplate(topologyTemplate, r))).collect(Collectors.toList());
topologyTemplate.getNodeTemplateOrRelationshipTemplate().addAll(reassignIncomingRelationships(incomingRelationshipsNotHostedOn, newMatchingNodeTemplate));
// The incoming Relationships from the currently considered predecessor should be switched
incomingRelationshipsOfReplacementCandidate.stream().filter(rt -> rt.getSourceElement().getRef().equals(predecessorOfNewHost)).forEach(rt -> rt.getTargetElement().setRef(newMatchingNodeTemplate));
// All outgoing rel of the origin hosts are copied and reassigned to the new host as source
List<TRelationshipTemplate> outgoingRelationshipsOfReplacementCandidateNotHostedOn = ModelUtilities.getOutgoingRelationshipTemplates(topologyTemplate, originHost).stream().filter(r -> !getHostedOnSuccessorsOfNodeTemplate(topologyTemplate, originHost).contains(r.getTargetElement().getRef())).collect(Collectors.toList());
topologyTemplate.getNodeTemplateOrRelationshipTemplate().addAll(reassignOutgoingRelationships(outgoingRelationshipsOfReplacementCandidateNotHostedOn, newMatchingNodeTemplate));
replacedNodeTemplatesToDelete.add(originHost);
}
}
switch(removal) {
case REMOVE_NOTHING:
return topologyTemplate;
case REMOVE_REPLACED:
for (TNodeTemplate deleteOriginNode : replacedNodeTemplatesToDelete) {
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getIncomingRelationshipTemplates(topologyTemplate, deleteOriginNode));
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getOutgoingRelationshipTemplates(topologyTemplate, deleteOriginNode));
}
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(replacedNodeTemplatesToDelete);
return topologyTemplate;
default:
break;
}
Map<TNodeTemplate, Set<TNodeTemplate>> transitiveAndDirectSuccessors = computeTransitiveClosure(topologyTemplate);
// Delete all replaced Nodes and their direct and transitive hostedOn successors
for (TNodeTemplate deleteOriginNode : replacedNodeTemplatesToDelete) {
if (!transitiveAndDirectSuccessors.get(deleteOriginNode).isEmpty()) {
for (TNodeTemplate successor : transitiveAndDirectSuccessors.get(deleteOriginNode)) {
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getIncomingRelationshipTemplates(topologyTemplate, successor));
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getOutgoingRelationshipTemplates(topologyTemplate, successor));
}
}
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(transitiveAndDirectSuccessors.get(deleteOriginNode));
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getIncomingRelationshipTemplates(topologyTemplate, deleteOriginNode));
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(ModelUtilities.getOutgoingRelationshipTemplates(topologyTemplate, deleteOriginNode));
}
topologyTemplate.getNodeTemplateOrRelationshipTemplate().removeAll(replacedNodeTemplatesToDelete);
LOGGER.debug("Resulting topology has {} NodeTemplates...", topologyTemplate.getNodeTemplates().size());
return topologyTemplate;
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Splitting method getConnectionInjectionOptions.
/**
*/
public Map<String, List<TTopologyTemplate>> getConnectionInjectionOptions(TTopologyTemplate topologyTemplate) throws SplittingException {
ProviderRepository providerRepository = new ProviderRepository();
Map<String, List<TTopologyTemplate>> connectionInjectionOptions = new HashMap<>();
List<TNodeTemplate> nodeTemplates = ModelUtilities.getAllNodeTemplates(topologyTemplate);
List<TNodeTemplate> nodeTemplatesWithConnectionRequirement = nodeTemplates.stream().filter(nt -> nt.getRequirements() != null).filter(nt -> nt.getRequirements().stream().anyMatch(req -> getBasisCapabilityType(getRequiredCapabilityTypeQNameOfRequirement(req)).getName().equalsIgnoreCase("Endpoint"))).collect(Collectors.toList());
if (!nodeTemplatesWithConnectionRequirement.isEmpty()) {
for (TNodeTemplate nodeWithOpenConnectionRequirement : nodeTemplatesWithConnectionRequirement) {
List<TRequirement> requirements = nodeWithOpenConnectionRequirement.getRequirements().stream().filter(req -> getBasisCapabilityType(getRequiredCapabilityTypeQNameOfRequirement(req)).getName().equalsIgnoreCase("Endpoint")).filter(req -> getOpenRequirementsAndMatchingBasisCapabilityTypeNames(topologyTemplate).keySet().contains(req)).collect(Collectors.toList());
for (TRequirement openRequirement : requirements) {
List<TTopologyTemplate> matchingTopologyFragments = providerRepository.getAllTopologyFragmentsForLocationAndOfferingCapability("*", openRequirement);
if (!matchingTopologyFragments.isEmpty()) {
// instead of the Node Template ID the Requirement ID is added because one Node Template can occur multiple times for connection injection
connectionInjectionOptions.put(openRequirement.getId(), matchingTopologyFragments);
} else {
throw new SplittingException("No matching found");
}
}
}
} else {
connectionInjectionOptions = null;
LOGGER.debug("No open requirements found");
}
return connectionInjectionOptions;
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class Allocation method createServiceTemplate.
private TServiceTemplate createServiceTemplate(TopologyWrapper topology) {
TServiceTemplate serviceTemplate = new TServiceTemplate();
TTopologyTemplate topologyTemplate = topology.getTopology();
// reset names for better visual representation
topologyTemplate.getNodeTemplateOrRelationshipTemplate().forEach(et -> et.setName(et.getType().getLocalPart()));
// all target labels to lower case for consistency
for (TNodeTemplate nodeTemplate : topologyTemplate.getNodeTemplates()) {
Optional<String> targetLabel = ModelUtilities.getTargetLabel(nodeTemplate);
targetLabel.ifPresent(s -> ModelUtilities.setTargetLabel(nodeTemplate, s));
}
serviceTemplate.setTopologyTemplate(topologyTemplate);
return serviceTemplate;
}
use of org.eclipse.winery.model.tosca.TTopologyTemplate in project winery by eclipse.
the class PoliciesFilter method toTopologies.
private List<List<TopologyWrapper>> toTopologies(List<List<TTopologyTemplate>> fragmentsByPolicies) {
List<List<TopologyWrapper>> topologiesByPolicies = new ArrayList<>();
for (List<TTopologyTemplate> fragments : fragmentsByPolicies) {
List<TopologyWrapper> toTopologies = new ArrayList<>();
for (TTopologyTemplate topologyTemplate : fragments) {
// nts uniquely identifiable because of cloneNotEquals
toTopologies.add(topologiesByFragments.get(topologyTemplate.getNodeTemplates().get(0)));
}
topologiesByPolicies.add(toTopologies);
}
return topologiesByPolicies;
}
Aggregations