diff --git a/build.gradle b/build.gradle index 98f190c52cb32fb043dde1bfd598afcc3a2f1893..78213ff5772eb2a9d7e0a4bc297aa8ce0d15131f 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,11 @@ repositories { dependencies { // AMAK (Only one of the next two lines should be uncommented. Also, settings.gradle file should also be modified) - implementation 'com.github.alexandreprl:amak:3.0.4'// Uncomment this line to get AMAK from git repository (The last part matches a tag, a commit hash or the last commit of a branch : branchName-SNAPSHOT + implementation 'com.github.alexandreprl:amak:3.1.0' +// Uncomment this line to get AMAK from git repository (The last part matches a tag, a commit hash or the last commit of a branch : branchName-SNAPSHOT // implementation project(':amak') // Uncomment this line to get AMAK from local + + testImplementation platform('org.junit:junit-bom:5.9.1') testImplementation 'org.junit.jupiter:junit-jupiter' diff --git a/src/main/java/fr/irit/smac/clumate/CluMATE.java b/src/main/java/fr/irit/smac/clumate/CluMATE.java index d1c1d421559e1e16439b34c4e81d960b1d4033b2..8dfbabf4d57ab48f5d0c6e00b90e1c6c5b5cf769 100644 --- a/src/main/java/fr/irit/smac/clumate/CluMATE.java +++ b/src/main/java/fr/irit/smac/clumate/CluMATE.java @@ -1,11 +1,13 @@ package fr.irit.smac.clumate; +import fr.irit.smac.amak.event.EventStore; import fr.irit.smac.clumate.amas.MASSettings; import fr.irit.smac.clumate.amas.controller.CluMATEController; import fr.irit.smac.clumate.amas.controller.command.NewDataPointCommand; import fr.irit.smac.clumate.amas.controller.command.SolveCommand; import fr.irit.smac.clumate.amas.controller.query.Result; import fr.irit.smac.clumate.amas.controller.query.RetrieveClustersResultQuery; +import fr.irit.smac.clumate.cluster.Cluster; import fr.irit.smac.clumate.cluster.DataPoint; import java.util.List; diff --git a/src/main/java/fr/irit/smac/clumate/amas/ClusterAMAS.java b/src/main/java/fr/irit/smac/clumate/amas/ClusterAMAS.java index ed241f05daf6b210094de354d3e6d5ba23ed71e7..e127ef61e643595a52456e4c1246e63675ff149b 100644 --- a/src/main/java/fr/irit/smac/clumate/amas/ClusterAMAS.java +++ b/src/main/java/fr/irit/smac/clumate/amas/ClusterAMAS.java @@ -1,6 +1,8 @@ package fr.irit.smac.clumate.amas; import fr.irit.smac.amak.Amas; +import fr.irit.smac.amak.event.EventStore; +import fr.irit.smac.clumate.cluster.Cluster; import fr.irit.smac.clumate.cluster.DataPoint; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/fr/irit/smac/clumate/amas/ClusterAgent.java b/src/main/java/fr/irit/smac/clumate/amas/ClusterAgent.java index 5fccb7db6a6fda10262b0b4ecd42bde05fb24eb3..7255ce5e32cbfb74aa01077fc50612e9473a3bc0 100644 --- a/src/main/java/fr/irit/smac/clumate/amas/ClusterAgent.java +++ b/src/main/java/fr/irit/smac/clumate/amas/ClusterAgent.java @@ -1,10 +1,13 @@ package fr.irit.smac.clumate.amas; import fr.irit.smac.amak.Agent; +import fr.irit.smac.amak.event.EventStore; import fr.irit.smac.clumate.amas.messages.EvaluatedScoreMessage; import fr.irit.smac.clumate.amas.messages.RequestSimilarityMessage; import fr.irit.smac.clumate.cluster.Cluster; import fr.irit.smac.clumate.cluster.DataPoint; +import fr.irit.smac.clumate.event.NewClusterEvent; +import fr.irit.smac.clumate.event.RemoveClusterEvent; import lombok.Getter; import java.text.MessageFormat; @@ -245,11 +248,23 @@ public class ClusterAgent<T extends DataPoint> extends Agent<ClusterAMAS<T>, Clu } private void setCluster(Cluster<T> newCluster) { - if (cluster != null) + if (cluster != null) { getAmas().getEnvironment().removeFromBucket(cluster.getRepresentative().getBucketId(), this); + if (getAmas().getMasSettings().eventStore() != null) + getAmas().getMasSettings().eventStore().add(new RemoveClusterEvent(cluster)); + } cluster = newCluster; getAmas().getEnvironment().assignToBucket(cluster.getRepresentative().getBucketId(), this); + if (getAmas().getMasSettings().eventStore() != null) + getAmas().getMasSettings().eventStore().add(new NewClusterEvent(cluster)); + } + + @Override + protected void onDestroy() { + if (cluster != null) + if (getAmas().getMasSettings().eventStore() != null) + getAmas().getMasSettings().eventStore().add(new RemoveClusterEvent(cluster)); } private Cluster<T> fuse(Cluster<T> other) { diff --git a/src/main/java/fr/irit/smac/clumate/amas/MASSettings.java b/src/main/java/fr/irit/smac/clumate/amas/MASSettings.java index c8721cf3be17cbb63788f2136c85524a63141084..9adf5359a75872e749a78c84dcf99137a6ea8884 100644 --- a/src/main/java/fr/irit/smac/clumate/amas/MASSettings.java +++ b/src/main/java/fr/irit/smac/clumate/amas/MASSettings.java @@ -1,11 +1,21 @@ package fr.irit.smac.clumate.amas; +import fr.irit.smac.amak.event.EventStore; +import fr.irit.smac.clumate.cluster.Cluster; import fr.irit.smac.clumate.cluster.DataPoint; import fr.irit.smac.clumate.cluster.DataPointFuser; import fr.irit.smac.clumate.cluster.SimilarityScoreMethod; import java.util.EnumSet; -public record MASSettings<T extends DataPoint>(SimilarityScoreMethod<T> similarityScoreMethod, float fusionThreshold, EnumSet<AMASOption> amasOptions, DataPointFuser<T> dataPointFuser) { - +public record MASSettings<T extends DataPoint>( + SimilarityScoreMethod<T> similarityScoreMethod, + float fusionThreshold, + EnumSet<AMASOption> amasOptions, + DataPointFuser<T> dataPointFuser, + EventStore<Cluster<T>> eventStore +) { + public MASSettings(SimilarityScoreMethod<T> similarityScoreMethod, float fusionThreshold, EnumSet<AMASOption> amasOptions, DataPointFuser<T> dataPointFuser) { + this(similarityScoreMethod, fusionThreshold, amasOptions, dataPointFuser, null); + } } diff --git a/src/main/java/fr/irit/smac/clumate/amas/controller/CluMATEController.java b/src/main/java/fr/irit/smac/clumate/amas/controller/CluMATEController.java index 64bcb2bd0e9295e012fa54c0986778ff9bc919a7..7f14015c434ea16995b8c53ccf899218a97f12fe 100644 --- a/src/main/java/fr/irit/smac/clumate/amas/controller/CluMATEController.java +++ b/src/main/java/fr/irit/smac/clumate/amas/controller/CluMATEController.java @@ -1,5 +1,6 @@ package fr.irit.smac.clumate.amas.controller; +import fr.irit.smac.amak.event.EventStore; import fr.irit.smac.amak.scheduling.Scheduler; import fr.irit.smac.clumate.amas.controller.command.NewDataPointCommand; import fr.irit.smac.clumate.amas.controller.command.ShutdownCommand; @@ -10,6 +11,7 @@ import fr.irit.smac.clumate.amas.ClusterAMAS; import fr.irit.smac.clumate.amas.ClusterAgent; import fr.irit.smac.clumate.amas.ClusterEnvironment; import fr.irit.smac.clumate.amas.MASSettings; +import fr.irit.smac.clumate.cluster.Cluster; import fr.irit.smac.clumate.cluster.DataPoint; import lombok.Getter; diff --git a/src/main/java/fr/irit/smac/clumate/cluster/Cluster.java b/src/main/java/fr/irit/smac/clumate/cluster/Cluster.java index 3c3576aabf35c73483732c18a4ccb5c90b28a3e6..bf5eb79b62168c1331b0e6a1f29d8634b3263989 100644 --- a/src/main/java/fr/irit/smac/clumate/cluster/Cluster.java +++ b/src/main/java/fr/irit/smac/clumate/cluster/Cluster.java @@ -3,8 +3,12 @@ package fr.irit.smac.clumate.cluster; import lombok.Getter; import lombok.ToString; +import java.util.UUID; + @ToString public class Cluster<T extends DataPoint> { + @Getter + private final String id = UUID.randomUUID().toString(); @Getter private final T representative; @Getter diff --git a/src/main/java/fr/irit/smac/clumate/cluster/DataPoint.java b/src/main/java/fr/irit/smac/clumate/cluster/DataPoint.java index b6e11c09cd49ce4d2a057e9e36e89ba2257d1fe5..923b8b17491b3d3e1c36d40a8e793c0366fbdb7d 100644 --- a/src/main/java/fr/irit/smac/clumate/cluster/DataPoint.java +++ b/src/main/java/fr/irit/smac/clumate/cluster/DataPoint.java @@ -1,5 +1,7 @@ package fr.irit.smac.clumate.cluster; public interface DataPoint { - int getBucketId(); + default int getBucketId() { + return 0; + } } diff --git a/src/main/java/fr/irit/smac/clumate/event/NewClusterEvent.java b/src/main/java/fr/irit/smac/clumate/event/NewClusterEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..2ef7580c464cde43d50f40e5d2aa0837ba8a00b6 --- /dev/null +++ b/src/main/java/fr/irit/smac/clumate/event/NewClusterEvent.java @@ -0,0 +1,8 @@ +package fr.irit.smac.clumate.event; + +import fr.irit.smac.amak.event.Event; +import fr.irit.smac.clumate.cluster.Cluster; +import fr.irit.smac.clumate.cluster.DataPoint; + +public record NewClusterEvent<T extends DataPoint>(Cluster<T> cluster) implements Event { +} diff --git a/src/main/java/fr/irit/smac/clumate/event/RemoveClusterEvent.java b/src/main/java/fr/irit/smac/clumate/event/RemoveClusterEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..6137a81cc5f11fc1a609f951fa8697da25dee27e --- /dev/null +++ b/src/main/java/fr/irit/smac/clumate/event/RemoveClusterEvent.java @@ -0,0 +1,8 @@ +package fr.irit.smac.clumate.event; + +import fr.irit.smac.amak.event.Event; +import fr.irit.smac.clumate.cluster.Cluster; +import fr.irit.smac.clumate.cluster.DataPoint; + +public record RemoveClusterEvent<T extends DataPoint>(Cluster<T> cluster) implements Event { +} diff --git a/src/test/groovy/SimpleClusteringIT.groovy b/src/test/groovy/SimpleClusteringIT.groovy index f77a4ba36e63b1d016f9e8ad6b6abc9a8ad36b92..a27cd58c67dec12643b6c0ed9f0840e72d82965c 100644 --- a/src/test/groovy/SimpleClusteringIT.groovy +++ b/src/test/groovy/SimpleClusteringIT.groovy @@ -1,6 +1,8 @@ +import fr.irit.smac.amak.event.EventStore import fr.irit.smac.clumate.CluMATE import fr.irit.smac.clumate.amas.AMASOption import fr.irit.smac.clumate.amas.MASSettings +import fr.irit.smac.clumate.cluster.Cluster import fr.irit.smac.clumate.cluster.DataPoint import fr.irit.smac.clumate.cluster.SimilarityScoreMethod import spock.lang.Specification diff --git a/src/test/groovy/fr/irit/smac/clumate/amas/ClusterAgentTest.groovy b/src/test/groovy/fr/irit/smac/clumate/amas/ClusterAgentTest.groovy index 473cbe623bb3c3214bd8c7a564efead32d1bf5fd..699e79bbdbd4a30cff20a5eecc963f737f55b5be 100644 --- a/src/test/groovy/fr/irit/smac/clumate/amas/ClusterAgentTest.groovy +++ b/src/test/groovy/fr/irit/smac/clumate/amas/ClusterAgentTest.groovy @@ -1,6 +1,6 @@ package fr.irit.smac.clumate.amas - +import fr.irit.smac.amak.event.EventStore import fr.irit.smac.amak.messaging.Mailbox import fr.irit.smac.amak.messaging.Message import fr.irit.smac.clumate.amas.messages.EvaluatedScoreMessage @@ -22,6 +22,7 @@ class ClusterAgentTest extends Specification { def amasMock = Mock(ClusterAMAS<DataPoint>) amasMock.getMasSettings() >> new MASSettings(similarityScoreMethodMock, 0.5f, EnumSet.noneOf(AMASOption), Mock(DataPointFuser)) + amasMock.getEnvironment() >> Mock(ClusterEnvironment) def agent = new ClusterAgent(amasMock, Mock(DataPoint)) agent.state = ClusterAgent.State.DORMANT