Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add supporting structure for TeaStore project-specific rules #92

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,13 @@
class="org.palladiosimulator.retriever.extraction.discoverers.EcmaScriptDiscoverer">
</discoverer>
</extension>
<extension
id="org.palladiosimulator.retriever.extraction.discoverers.docker"
name="Dockerfile Discoverer"
point="org.palladiosimulator.retriever.services.discoverer">
<discoverer
class="org.palladiosimulator.retriever.extraction.discoverers.DockerfileDiscoverer">
</discoverer>
</extension>

</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.palladiosimulator.retriever.extraction.discoverers;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.CommonPlugin;
import org.palladiosimulator.retriever.services.Discoverer;
import org.palladiosimulator.retriever.services.RetrieverConfiguration;
import org.palladiosimulator.retriever.services.blackboard.RetrieverBlackboard;

import de.uka.ipd.sdq.workflow.jobs.AbstractBlackboardInteractingJob;
import de.uka.ipd.sdq.workflow.jobs.CleanupFailedException;
import de.uka.ipd.sdq.workflow.jobs.IBlackboardInteractingJob;
import de.uka.ipd.sdq.workflow.jobs.JobFailedException;
import de.uka.ipd.sdq.workflow.jobs.UserCanceledException;

public class DockerfileDiscoverer implements Discoverer {

private static final String DISCOVERER_ID = "org.palladiosimulator.retriever.extraction.discoverers.docker";

@Override
public IBlackboardInteractingJob<RetrieverBlackboard> create(final RetrieverConfiguration configuration,
final RetrieverBlackboard blackboard) {
return new AbstractBlackboardInteractingJob<>() {

@Override
public void cleanup(final IProgressMonitor monitor) throws CleanupFailedException {
}

@Override
public void execute(final IProgressMonitor monitor) throws JobFailedException, UserCanceledException {
final Path root = Paths.get(CommonPlugin.asLocalURI(configuration.getInputFolder())
.devicePath());
this.setBlackboard(Objects.requireNonNull(blackboard));
final Map<Path, Object> dockerfiles = new HashMap<>();
Discoverer.find(root, "Dockerfile", this.logger)
.forEach(p -> dockerfiles.put(p, null));
this.getBlackboard()
.putDiscoveredFiles(DISCOVERER_ID, dockerfiles);
}

@Override
public String getName() {
return "Dockerfile Discoverer Job";
}
};
}

@Override
public Set<String> getConfigurationKeys() {
return Collections.emptySet();
}

@Override
public String getID() {
return DISCOVERER_ID;
}

@Override
public String getName() {
return "Dockerfile Discoverer";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ public class Component {
private final CompUnitOrName compUnitOrName;
private final Requirements requirements;
private final Provisions provisions;
private final Optional<String> separatingIdentifier;

public Component(final CompUnitOrName compUnitOrName, final Requirements requirements,
final Provisions provisions) {
public Component(final CompUnitOrName compUnitOrName, final Requirements requirements, final Provisions provisions,
final Optional<String> separatingIdentifier) {
this.compUnitOrName = compUnitOrName;
this.requirements = requirements;
this.provisions = provisions;
this.separatingIdentifier = separatingIdentifier;
}

public Requirements requirements() {
Expand All @@ -43,6 +45,10 @@ public CompUnitOrName identifier() {
return this.compUnitOrName;
}

public Optional<String> separatingIdentifier() {
return this.separatingIdentifier;
}

@Override
public int hashCode() {
return Objects.hash(this.compUnitOrName, this.provisions, this.requirements);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

/**
* Used to build {@code Component}s.
Expand All @@ -13,11 +14,13 @@ public class ComponentBuilder {
private final CompUnitOrName compUnitOrName;
private final RequirementsBuilder requirements;
private final ProvisionsBuilder provisions;
private Optional<String> separatingIdentifier;

public ComponentBuilder(final CompUnitOrName compUnitOrName) {
this.compUnitOrName = compUnitOrName;
this.requirements = new RequirementsBuilder();
this.provisions = new ProvisionsBuilder();
this.separatingIdentifier = Optional.empty();
}

public CompUnitOrName identifier() {
Expand All @@ -32,10 +35,14 @@ public ProvisionsBuilder provisions() {
return this.provisions;
}

public void setSeparatingIdentifier(final String separatingIdentifier) {
this.separatingIdentifier = Optional.of(separatingIdentifier);
}

public Component create(final Collection<OperationInterface> allDependencies,
final Collection<OperationInterface> visibleProvisions) {
return new Component(this.compUnitOrName, this.requirements.create(allDependencies, visibleProvisions),
this.provisions.create(allDependencies));
this.provisions.create(allDependencies), this.separatingIdentifier);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
Expand Down Expand Up @@ -215,13 +216,19 @@ private static List<OperationInterface> findRequiringComponents(final Set<Compon
.filter(x -> !compositeProvisions.containsEntire(x))
.forEach(provisions::add);

final Optional<String> separatingIdentifier = providingComponent.separatingIdentifier();

final List<OperationInterface> traversedOperations = new ArrayList<>();
while (!provisions.isEmpty()) {
final OperationInterface provision = provisions.pop();
final Set<Component> requiringComponents = remainingComponents.stream()
.filter(x -> x.requirements()
.containsPartOf(provision))
.filter(x -> !providingComponent.equals(x))
.filter(x -> x.separatingIdentifier()
.isEmpty() || separatingIdentifier.isEmpty()
|| x.separatingIdentifier()
.equals(separatingIdentifier))
.collect(Collectors.toSet());

// Skip this provision if no unit requires it.
Expand Down Expand Up @@ -250,13 +257,19 @@ private static List<OperationInterface> findProvidingComponents(final Set<Compon
.filter(x -> !compositeProvisions.containsEntire(x))
.forEach(requirements::add);

final Optional<String> separatingIdentifier = requiringComponent.separatingIdentifier();

final List<OperationInterface> traversedOperations = new ArrayList<>();
while (!requirements.isEmpty()) {
final OperationInterface requirement = requirements.pop();
final Set<Component> providingComponents = remainingComponents.stream()
.filter(x -> x.provisions()
.containsPartOf(requirement))
.filter(x -> !requiringComponent.equals(x))
.filter(x -> x.separatingIdentifier()
.isEmpty() || separatingIdentifier.isEmpty()
|| x.separatingIdentifier()
.equals(separatingIdentifier))
.collect(Collectors.toSet());

// Skip this requirement if no unit provides it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -93,27 +94,63 @@ private static Set<Composite> createCompositeComponents(final Set<Component> fre
final Set<Composite> redundantComposites = new HashSet<>();
final Set<Composite> remainingComposites = new HashSet<>();

for (int i = 0; i < allComposites.size(); ++i) {
final Composite subject = allComposites.get(i);
final long subsetCount = allComposites.subList(i + 1, allComposites.size())
.stream()
for (final Composite subject : allComposites) {
final Optional<Composite> other = allComposites.stream()
.filter(x -> !subject.equals(x))
.filter(x -> !redundantComposites.contains(x))
.filter(x -> subject.isSubsetOf(x) || x.isSubsetOf(subject))
.count();
.filter(x -> subject.isSubsetOf(x))
.findFirst();

// Any composite is guaranteed to be the subset of at least one composite in the
// list, namely itself. If it is the subset of any composites other than itself, it is
// redundant.
if (subsetCount > 0) {
if (other.isPresent()) {
redundantComposites.add(subject);
continue;
} else {
// TODO: Is there any merging necessary, like adapting the redundant composite's
// requirements to its peer?
remainingComposites.add(subject);
}
}

// Remove composite components contained in multiple other composites, according to a
// conservative heuristic.
// TODO: A comprehensive solution would require e.g. graph traversal and tie-breaking in
// cycles.

final Set<Composite> collectivelyContainedComposites = new HashSet<>();
for (final Composite subject : remainingComposites) {
final Set<Component> allOtherParts = remainingComposites.stream()
.filter(x -> !subject.equals(x))
.map(Composite::parts)
.flatMap(Set::stream)
.collect(Collectors.toSet());
final boolean isContainedInOthers = subject.parts()
.stream()
.allMatch(allOtherParts::contains);
if (isContainedInOthers) {
collectivelyContainedComposites.add(subject);
}
}

final Set<Composite> actuallyContainedComposites = new HashSet<>();
for (final Composite subject : collectivelyContainedComposites) {
final Set<Component> allOtherParts = remainingComposites.stream()
.filter(x -> !subject.equals(x))
.filter(x -> !collectivelyContainedComposites.contains(x))
.map(Composite::parts)
.flatMap(Set::stream)
.collect(Collectors.toSet());
final boolean isContainedInOthers = subject.parts()
.stream()
.allMatch(allOtherParts::contains);
if (isContainedInOthers) {
actuallyContainedComposites.add(subject);
}
}

remainingComposites.removeAll(actuallyContainedComposites);

return remainingComposites;

}

private static Set<OperationInterface> collectVisibleProvisions(final Set<Component> components,
Expand Down
Loading
Loading