From e27886c3b615a5bf31615edaa4d20618bd73f5b4 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 25 Jan 2025 11:26:51 -0700 Subject: [PATCH 01/22] Change head to main --- core/src/main/resources/lib/cpp/reactor-cpp | 2 +- core/src/main/resources/lib/rs/reactor-rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/resources/lib/cpp/reactor-cpp b/core/src/main/resources/lib/cpp/reactor-cpp index e0df4349bb..d255a3da57 160000 --- a/core/src/main/resources/lib/cpp/reactor-cpp +++ b/core/src/main/resources/lib/cpp/reactor-cpp @@ -1 +1 @@ -Subproject commit e0df4349bb5726e659d5c6589fa948a18991e2b8 +Subproject commit d255a3da57d38db2988bcab68024b0a77ccc8657 diff --git a/core/src/main/resources/lib/rs/reactor-rs b/core/src/main/resources/lib/rs/reactor-rs index 10fee74e32..9fe7853ecd 160000 --- a/core/src/main/resources/lib/rs/reactor-rs +++ b/core/src/main/resources/lib/rs/reactor-rs @@ -1 +1 @@ -Subproject commit 10fee74e32a72f15ec3bc5605d61c27f63c8e037 +Subproject commit 9fe7853ecdbf6d33f6916ad5f822c6d9dd01609d From a2dd8a0858a0e5eedf442ad24ea9e4e8ffc9ff70 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 25 Jan 2025 11:28:48 -0700 Subject: [PATCH 02/22] Update runtime-version --- core/src/main/resources/lib/rs/runtime-version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/lib/rs/runtime-version.properties b/core/src/main/resources/lib/rs/runtime-version.properties index 2e9a7684bd..96314e5bac 100644 --- a/core/src/main/resources/lib/rs/runtime-version.properties +++ b/core/src/main/resources/lib/rs/runtime-version.properties @@ -1 +1 @@ -rs = bca71291d2b9547863bd42171872203336e9ec3f +rs = 9fe7853ecdbf6d33f6916ad5f822c6d9dd01609d From e76fc2b1ea346365f7209d350166bcf5a1082cc6 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 10:16:31 -0700 Subject: [PATCH 03/22] Make the arduino build to skip network files copied. --- core/src/main/java/org/lflang/generator/c/CGenerator.java | 3 +++ core/src/main/resources/lib/c/reactor-c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/lflang/generator/c/CGenerator.java b/core/src/main/java/org/lflang/generator/c/CGenerator.java index cb1ff1eace..f98ebe2e74 100644 --- a/core/src/main/java/org/lflang/generator/c/CGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CGenerator.java @@ -925,6 +925,9 @@ protected void copyTargetFiles() throws IOException { "logging", "platform", "low_level_platform", "trace", "version", "tag", "network")) { var entry = "/lib/c/reactor-c/" + directory; if (arduino) { + if ("network".equals(directory)) { + continue; // Skip processing for the "network" directory + } if (FileConfig.class.getResource(entry + "/api") != null) { FileUtil.copyFromClassPath( entry + "/api", diff --git a/core/src/main/resources/lib/c/reactor-c b/core/src/main/resources/lib/c/reactor-c index aca13882a4..bf557efa22 160000 --- a/core/src/main/resources/lib/c/reactor-c +++ b/core/src/main/resources/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit aca13882a4da7003f17224f014e4363e3977ece7 +Subproject commit bf557efa223db529be85b8f5d1bd9bde145b5a37 From ab9df64e55b8ef7bbd35d21361aab0f702030824 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 28 Jan 2025 10:45:10 -0700 Subject: [PATCH 04/22] Fix reactor-c --- core/src/main/resources/lib/c/reactor-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/lib/c/reactor-c b/core/src/main/resources/lib/c/reactor-c index bf557efa22..b4720bb0ce 160000 --- a/core/src/main/resources/lib/c/reactor-c +++ b/core/src/main/resources/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit bf557efa223db529be85b8f5d1bd9bde145b5a37 +Subproject commit b4720bb0ce367c673d39fe0b4dd516406c6e8d18 From df7902ca7845eaadbb2d7ed7e4096606f1bedf60 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 12:58:00 -0700 Subject: [PATCH 05/22] Fix file names. --- .../org/lflang/generator/c/CGenerator.java | 2 +- .../property/CommunicationModeProperty.java | 44 +++++++++++++++++++ .../property/CommunicationTypeProperty.java | 44 ------------------- ...peType.java => CommunicationModeType.java} | 20 ++++----- 4 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java delete mode 100644 core/src/main/java/org/lflang/target/property/CommunicationTypeProperty.java rename core/src/main/java/org/lflang/target/property/type/{CommunicationTypeType.java => CommunicationModeType.java} (53%) diff --git a/core/src/main/java/org/lflang/generator/c/CGenerator.java b/core/src/main/java/org/lflang/generator/c/CGenerator.java index f98ebe2e74..46507a06ce 100644 --- a/core/src/main/java/org/lflang/generator/c/CGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CGenerator.java @@ -926,7 +926,7 @@ protected void copyTargetFiles() throws IOException { var entry = "/lib/c/reactor-c/" + directory; if (arduino) { if ("network".equals(directory)) { - continue; // Skip processing for the "network" directory + continue; // Skip copying for the "network" directory } if (FileConfig.class.getResource(entry + "/api") != null) { FileUtil.copyFromClassPath( diff --git a/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java new file mode 100644 index 0000000000..caaeb44d82 --- /dev/null +++ b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java @@ -0,0 +1,44 @@ +package org.lflang.target.property; + +import org.lflang.MessageReporter; +import org.lflang.ast.ASTUtils; +import org.lflang.lf.Element; +import org.lflang.target.property.type.CommunicationModeType; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; + +/** Directive to specify the target communication type such as 'TCP', 'SST', or 'MQTT'. */ +public final class CommunicationModeProperty + extends TargetProperty { + + /** Singleton target property instance. */ + public static final CommunicationModeProperty INSTANCE = new CommunicationModeProperty(); + + private CommunicationModeProperty() { + super(new CommunicationModeType()); + } + + @Override + public Element toAstElement(CommunicationMode value) { + return ASTUtils.toElement(value.toString()); + } + + @Override + public CommunicationMode initialValue() { + return CommunicationMode.TCP; + } + + @Override + public CommunicationMode fromAst(Element node, MessageReporter reporter) { + return fromString(ASTUtils.elementToSingleString(node), reporter); + } + + @Override + protected CommunicationMode fromString(String string, MessageReporter reporter) { + return this.type.forName(string); + } + + @Override + public String name() { + return "comm-type"; + } +} diff --git a/core/src/main/java/org/lflang/target/property/CommunicationTypeProperty.java b/core/src/main/java/org/lflang/target/property/CommunicationTypeProperty.java deleted file mode 100644 index 47e7d29ac9..0000000000 --- a/core/src/main/java/org/lflang/target/property/CommunicationTypeProperty.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.lflang.target.property; - -import org.lflang.MessageReporter; -import org.lflang.ast.ASTUtils; -import org.lflang.lf.Element; -import org.lflang.target.property.type.CommunicationTypeType; -import org.lflang.target.property.type.CommunicationTypeType.CommunicationType; - -/** Directive to specify the target communication type such as 'TCP', 'SST', or 'MQTT'. */ -public final class CommunicationTypeProperty - extends TargetProperty { - - /** Singleton target property instance. */ - public static final CommunicationTypeProperty INSTANCE = new CommunicationTypeProperty(); - - private CommunicationTypeProperty() { - super(new CommunicationTypeType()); - } - - @Override - public Element toAstElement(CommunicationType value) { - return ASTUtils.toElement(value.toString()); - } - - @Override - public CommunicationType initialValue() { - return CommunicationType.TCP; - } - - @Override - public CommunicationType fromAst(Element node, MessageReporter reporter) { - return fromString(ASTUtils.elementToSingleString(node), reporter); - } - - @Override - protected CommunicationType fromString(String string, MessageReporter reporter) { - return this.type.forName(string); - } - - @Override - public String name() { - return "comm-type"; - } -} diff --git a/core/src/main/java/org/lflang/target/property/type/CommunicationTypeType.java b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java similarity index 53% rename from core/src/main/java/org/lflang/target/property/type/CommunicationTypeType.java rename to core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java index b2c146330e..0fd03e5baf 100644 --- a/core/src/main/java/org/lflang/target/property/type/CommunicationTypeType.java +++ b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java @@ -3,18 +3,18 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import org.lflang.target.property.type.CommunicationTypeType.CommunicationType; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; /** Enumeration of communication types */ -public class CommunicationTypeType extends OptionsType { +public class CommunicationModeType extends OptionsType { @Override - protected Class enumClass() { - return CommunicationType.class; + protected Class enumClass() { + return CommunicationMode.class; } /** Enumeration of communication types. */ - public enum CommunicationType { + public enum CommunicationMode { TCP("TCP"), SST("SST"), MQTT("MQTT"); @@ -23,7 +23,7 @@ public enum CommunicationType { private final String alias; /** Private constructor for Cmake build types. */ - CommunicationType(String alias) { + CommunicationMode(String alias) { this.alias = alias; } @@ -33,12 +33,12 @@ public String toString() { return this.alias; } - public static List optionsList() { - return Arrays.stream(CommunicationType.values()).collect(Collectors.toList()); + public static List optionsList() { + return Arrays.stream(CommunicationMode.values()).collect(Collectors.toList()); } - public static CommunicationType getDefault() { - return CommunicationType.TCP; + public static CommunicationMode getDefault() { + return CommunicationMode.TCP; } } } From f2713b0b976da8ab1d326cdfd2f28d7f2de4e924 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 12:59:14 -0700 Subject: [PATCH 06/22] Fix names --- .../org/lflang/federated/extensions/CExtensionUtils.java | 6 +++--- .../main/java/org/lflang/generator/c/CCmakeGenerator.java | 6 +++--- core/src/main/java/org/lflang/target/Target.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java b/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java index 044290de91..20878ee217 100644 --- a/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java +++ b/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java @@ -28,7 +28,7 @@ import org.lflang.target.property.ClockSyncOptionsProperty; import org.lflang.target.property.ClockSyncOptionsProperty.ClockSyncOptions; import org.lflang.target.property.CmakeIncludeProperty; -import org.lflang.target.property.CommunicationTypeProperty; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.CompileDefinitionsProperty; import org.lflang.target.property.CoordinationOptionsProperty; import org.lflang.target.property.CoordinationProperty; @@ -202,9 +202,9 @@ public static void handleCompileDefinitions( if (federate.targetConfig.get(AuthProperty.INSTANCE)) { definitions.put("FEDERATED_AUTHENTICATED", ""); } - if (federate.targetConfig.isSet(CommunicationTypeProperty.INSTANCE)) { + if (federate.targetConfig.isSet(CommunicationModeProperty.INSTANCE)) { definitions.put( - "COMM_TYPE", federate.targetConfig.get(CommunicationTypeProperty.INSTANCE).toString()); + "COMM_TYPE", federate.targetConfig.get(CommunicationModeProperty.INSTANCE).toString()); } definitions.put("NUMBER_OF_FEDERATES", String.valueOf(federateNames.size())); definitions.put("EXECUTABLE_PREAMBLE", ""); diff --git a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java index 8ae70cec44..281b9a203d 100644 --- a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java @@ -37,7 +37,7 @@ import org.lflang.target.property.AuthProperty; import org.lflang.target.property.BuildTypeProperty; import org.lflang.target.property.CmakeIncludeProperty; -import org.lflang.target.property.CommunicationTypeProperty; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.CompileDefinitionsProperty; import org.lflang.target.property.CompilerProperty; import org.lflang.target.property.PlatformProperty; @@ -427,8 +427,8 @@ CodeBuilder generateCMakeCode( cMakeCode.pr("target_link_libraries( ${LF_MAIN_TARGET} PRIVATE OpenSSL::SSL)"); cMakeCode.newLine(); } - if (targetConfig.isSet(CommunicationTypeProperty.INSTANCE)) { - cMakeCode.pr("set(COMM_TYPE " + targetConfig.get(CommunicationTypeProperty.INSTANCE) + ")"); + if (targetConfig.isSet(CommunicationModeProperty.INSTANCE)) { + cMakeCode.pr("set(COMM_TYPE " + targetConfig.get(CommunicationModeProperty.INSTANCE) + ")"); cMakeCode.newLine(); } diff --git a/core/src/main/java/org/lflang/target/Target.java b/core/src/main/java/org/lflang/target/Target.java index 1b8445abfd..f0dc63aef0 100644 --- a/core/src/main/java/org/lflang/target/Target.java +++ b/core/src/main/java/org/lflang/target/Target.java @@ -556,7 +556,7 @@ public void initialize(TargetConfig config) { ClockSyncModeProperty.INSTANCE, ClockSyncOptionsProperty.INSTANCE, CmakeIncludeProperty.INSTANCE, - CommunicationTypeProperty.INSTANCE, + CommunicationModeProperty.INSTANCE, CompileDefinitionsProperty.INSTANCE, CompilerProperty.INSTANCE, CoordinationOptionsProperty.INSTANCE, From d40f1393680cd59b48c06701c4c6105784537e30 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 13:22:27 -0700 Subject: [PATCH 07/22] Fix communication mode enum. --- .../lflang/target/property/CommunicationModeProperty.java | 1 - .../lflang/target/property/type/CommunicationModeType.java | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java index caaeb44d82..f4aade96c3 100644 --- a/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java +++ b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java @@ -6,7 +6,6 @@ import org.lflang.target.property.type.CommunicationModeType; import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; -/** Directive to specify the target communication type such as 'TCP', 'SST', or 'MQTT'. */ public final class CommunicationModeProperty extends TargetProperty { diff --git a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java index 0fd03e5baf..ce338c7170 100644 --- a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java +++ b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java @@ -15,9 +15,8 @@ protected Class enumClass() { /** Enumeration of communication types. */ public enum CommunicationMode { - TCP("TCP"), - SST("SST"), - MQTT("MQTT"); + TCP("TCP"); + // More communication modes will be added. /** Alias used in toString method. */ private final String alias; From ed05be87b69630b0617978385c9bc647bfbc30c5 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 29 Jan 2025 14:29:50 -0700 Subject: [PATCH 08/22] Formatting. --- .../org/lflang/target/property/type/CommunicationModeType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java index ce338c7170..c2a30f612b 100644 --- a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java +++ b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java @@ -16,6 +16,7 @@ protected Class enumClass() { /** Enumeration of communication types. */ public enum CommunicationMode { TCP("TCP"); + // More communication modes will be added. /** Alias used in toString method. */ From 259c2d0d5f722cb899cfacaf303ff8f98cfc66fb Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 17:48:40 -0700 Subject: [PATCH 09/22] Add SST property. --- .../lflang/target/property/type/CommunicationModeType.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java index c2a30f612b..4de1d16293 100644 --- a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java +++ b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java @@ -15,9 +15,8 @@ protected Class enumClass() { /** Enumeration of communication types. */ public enum CommunicationMode { - TCP("TCP"); - - // More communication modes will be added. + TCP("TCP"), + SST("SST"); /** Alias used in toString method. */ private final String alias; From af37f6ffff6860707f475856474324f24d76f899 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:11:20 -0700 Subject: [PATCH 10/22] Add to find sst library, when using communication mode sst. --- .../main/java/org/lflang/generator/c/CCmakeGenerator.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java index 281b9a203d..b6a33bc10f 100644 --- a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java @@ -46,6 +46,7 @@ import org.lflang.target.property.SingleThreadedProperty; import org.lflang.target.property.TracePluginProperty; import org.lflang.target.property.WorkersProperty; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; import org.lflang.target.property.type.PlatformType.Platform; import org.lflang.util.FileUtil; @@ -431,6 +432,13 @@ CodeBuilder generateCMakeCode( cMakeCode.pr("set(COMM_TYPE " + targetConfig.get(CommunicationModeProperty.INSTANCE) + ")"); cMakeCode.newLine(); } + if (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) { + // If communication mode is SST, find sst package. + cMakeCode.pr("# Find sst-c-api and link to it."); + cMakeCode.pr("find_package(sst-lib REQUIRED)"); + cMakeCode.pr("target_link_libraries(${LF_MAIN_TARGET} PRIVATE sst-lib::sst-c-api)"); + cMakeCode.newLine(); + } if (!targetConfig.get(SingleThreadedProperty.INSTANCE) && platformOptions.platform() != Platform.ZEPHYR From f90a89cdf9b0dd1da6f2124363d5cdfb177e7555 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:56:29 -0700 Subject: [PATCH 11/22] Add SST Path property, with get functions. --- .../generator/FederationFileConfig.java | 20 +++++++++++++++++++ .../main/java/org/lflang/target/Target.java | 1 + .../target/property/SSTPathProperty.java | 17 ++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 core/src/main/java/org/lflang/target/property/SSTPathProperty.java diff --git a/core/src/main/java/org/lflang/federated/generator/FederationFileConfig.java b/core/src/main/java/org/lflang/federated/generator/FederationFileConfig.java index c714c0586a..5ebe4ef34d 100644 --- a/core/src/main/java/org/lflang/federated/generator/FederationFileConfig.java +++ b/core/src/main/java/org/lflang/federated/generator/FederationFileConfig.java @@ -91,6 +91,26 @@ public Path getFedBinPath() { return getFedGenPath().resolve("bin"); } + public Path getSSTPath() { + return getGenPath().resolve("sst"); + } + + public Path getSSTConfigPath() { + return getSSTPath().resolve("configs"); + } + + public Path getSSTCredentialsPath() { + return getSSTPath().resolve("credentials"); + } + + public Path getSSTGraphsPath() { + return getSSTPath().resolve("graphs"); + } + + public Path getSSTAuthPath() { + return getSSTPath().resolve("auth"); + } + @Override public void doClean() throws IOException { super.doClean(); diff --git a/core/src/main/java/org/lflang/target/Target.java b/core/src/main/java/org/lflang/target/Target.java index f0dc63aef0..6102a7cc20 100644 --- a/core/src/main/java/org/lflang/target/Target.java +++ b/core/src/main/java/org/lflang/target/Target.java @@ -557,6 +557,7 @@ public void initialize(TargetConfig config) { ClockSyncOptionsProperty.INSTANCE, CmakeIncludeProperty.INSTANCE, CommunicationModeProperty.INSTANCE, + SSTPathProperty.INSTANCE, CompileDefinitionsProperty.INSTANCE, CompilerProperty.INSTANCE, CoordinationOptionsProperty.INSTANCE, diff --git a/core/src/main/java/org/lflang/target/property/SSTPathProperty.java b/core/src/main/java/org/lflang/target/property/SSTPathProperty.java new file mode 100644 index 0000000000..721cc492ea --- /dev/null +++ b/core/src/main/java/org/lflang/target/property/SSTPathProperty.java @@ -0,0 +1,17 @@ +package org.lflang.target.property; + +/** The compiler to invoke, unless a build command has been specified. */ +public final class SSTPathProperty extends StringProperty { + + /** Singleton target property instance. */ + public static final SSTPathProperty INSTANCE = new SSTPathProperty(); + + private SSTPathProperty() { + super(); + } + + @Override + public String name() { + return "sst-root-path"; + } +} From 929f598d072af18d8e9d1c4895cbc6b7ae4ec344 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:56:53 -0700 Subject: [PATCH 12/22] Add SSTGenerator. --- .../federated/generator/SSTGenerator.java | 372 ++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 core/src/main/java/org/lflang/federated/generator/SSTGenerator.java diff --git a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java new file mode 100644 index 0000000000..2c9402abd7 --- /dev/null +++ b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java @@ -0,0 +1,372 @@ +package org.lflang.federated.generator; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import org.lflang.MessageReporter; +import org.lflang.generator.LFGeneratorContext; +import org.lflang.target.property.SSTPathProperty; +import org.lflang.util.FileUtil; + +/** + * SST related methods. + * + * @author Dongha Kim + */ +public class SSTGenerator { + public static void setupSST( + FederationFileConfig fileConfig, + List federates, + MessageReporter messageReporter, + LFGeneratorContext context) { + if (context.getTargetConfig().get(SSTPathProperty.INSTANCE).isEmpty()) { + context + .getErrorReporter() + .nowhere() + .error( + "Target property `sst-root-path:` has not been defined. `comm-type: SST` requires" + + " `sst-root-path`"); + return; + } + + FileUtil.createDirectoryIfDoesNotExist(fileConfig.getSSTConfigPath().toFile()); + FileUtil.createDirectoryIfDoesNotExist(fileConfig.getSSTCredentialsPath().toFile()); + FileUtil.createDirectoryIfDoesNotExist(fileConfig.getSSTGraphsPath().toFile()); + + // Create graph used when creating credentials. + // Set graph path. + Path graphPath = fileConfig.getSSTGraphsPath().resolve(fileConfig.name + ".graph"); + // Generate the graph file content + JsonObject graphObject = SSTGenerator.generateGraphFile(federates); + // Write the graph object to a JSON file + try (FileWriter fileWriter = new FileWriter(graphPath.toString())) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + gson.toJson(graphObject, fileWriter); + messageReporter + .nowhere() + .info("Graph file generated successfully into: " + graphPath.toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // Set root path to execute commands. + Path sstRepoRootPath = Paths.get(context.getTargetConfig().get(SSTPathProperty.INSTANCE)); + ProcessBuilder processBuilder = new ProcessBuilder(); + + // Set the working directory to the specified path + processBuilder.directory(sstRepoRootPath.resolve("examples").toFile()); + + // Clean the old credentials & generate new credentials. + // processBuilder.command("bash", "-c", "echo" + graphPath); + + processBuilder.command("bash", "-c", "./cleanAll.sh ; ./generateAll.sh -g " + graphPath); + + // Start the process + try { + Process process = processBuilder.start(); + + // Wait for the process to complete + int exitCode = process.waitFor(); + + // Output the result + if (exitCode == 0) { + messageReporter.nowhere().info("Credential generation script execution successed."); + } else { + String errorOutput = new String(process.getErrorStream().readAllBytes()); + context + .getErrorReporter() + .nowhere() + .error( + "Script execution failed with exit code: " + + exitCode + + "\nError Output: " + + errorOutput); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + + // Copy credentials. + try { + SSTGenerator.copyCredentials(fileConfig, sstRepoRootPath); + messageReporter + .nowhere() + .info("Credentials copied into: " + fileConfig.getSSTCredentialsPath().toString()); + SSTGenerator.copyAuthNecessary(fileConfig, sstRepoRootPath); + messageReporter + .nowhere() + .info("Auth necessary files copied into: " + fileConfig.getSSTAuthPath().toString()); + SSTGenerator.updatePropertiesFile(fileConfig); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // Generate SST config for the rti. + SSTGenerator.generateSSTConfig(fileConfig, "rti"); + messageReporter + .nowhere() + .info( + "Federate generated SST config into: " + + SSTGenerator.getSSTConfig(fileConfig, "rti").toString()); + + // Generate SST config for the federates. + for (FederateInstance federate : federates) { + SSTGenerator.generateSSTConfig(fileConfig, federate.name); + messageReporter + .nowhere() + .info( + "Federate generated SST config into: " + + SSTGenerator.getSSTConfig(fileConfig, federate.name).toString()); + } + } + + public static Path getSSTConfig(FederationFileConfig fileConfig, String name) { + return fileConfig.getSSTConfigPath().resolve(name + ".config"); + } + + private static void generateSSTConfig(FederationFileConfig fileConfig, String name) { + // Values to fill in + String entityName = "net1." + name; + String pubkeyRoot = + fileConfig.getSSTCredentialsPath().resolve("auth_certs").toString() + + File.separator + + "Auth101EntityCert.pem"; + String privkeyRoot = + fileConfig.getSSTCredentialsPath().resolve("keys").resolve("net1").toString() + + File.separator + + "Net1." + + name + + "Key.pem"; + String authIpAddress = "127.0.0.1"; + int authPortNumber = 21900; + String entityServerIpAddress = "127.0.0.1"; + int entityServerPortNumber = 15045; + String networkProtocol = "TCP"; + + // Create the configuration content + StringBuilder configContent = new StringBuilder(); + configContent + .append("entityInfo.name=") + .append(entityName) + .append("\n") + .append("entityInfo.purpose={\"group\":\"Servers\"}\n") + .append("entityInfo.number_key=1\n") + .append("authInfo.pubkey.path=") + .append(pubkeyRoot) + .append("\n") + .append("entityInfo.privkey.path=") + .append(privkeyRoot) + .append("\n") + .append("auth.ip.address=") + .append(authIpAddress) + .append("\n") + .append("auth.port.number=") + .append(authPortNumber) + .append("\n") + .append("entity.server.ip.address=") + .append(entityServerIpAddress) + .append("\n") + .append("entity.server.port.number=") + .append(entityServerPortNumber) + .append("\n") + .append("network.protocol=") + .append(networkProtocol) + .append("\n"); + + try { + // Create the new file and write the modified content + Path newFilePath; + newFilePath = fileConfig.getSSTConfigPath().resolve(name + ".config"); + // Create /SST directories if necessary + Files.createDirectories(newFilePath.getParent().getParent()); + // Create /SST/configs directories if necessary + Files.createDirectories(newFilePath.getParent()); // Create parent directories if necessary + BufferedWriter writer = new BufferedWriter(new FileWriter(newFilePath.toFile(), false)); + writer.write(configContent.toString()); + writer.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static JsonObject generateGraphFile(List federateInstances) { + JsonObject graphObject = new JsonObject(); + + // Auth list + JsonArray authList = new JsonArray(); + authList.add( + createAuthEntry(101, "localhost", "localhost", 21900, 21902, 21901, 21903, 1, false, true)); + authList.add( + createAuthEntry(102, "localhost", "localhost", 21900, 21902, 21901, 21903, 1, false, true)); + graphObject.add("authList", authList); + + // Auth trusts + JsonArray authTrusts = new JsonArray(); + JsonObject trustRelation = new JsonObject(); + trustRelation.addProperty("id1", 101); + trustRelation.addProperty("id2", 102); + authTrusts.add(trustRelation); + graphObject.add("authTrusts", authTrusts); + + // Assignments section + JsonObject assignments = new JsonObject(); + assignments.addProperty("net1.rti", 101); + for (FederateInstance federate : federateInstances) { + assignments.addProperty("net1." + federate.name, 101); // Assuming "101" is a placeholder + } + graphObject.add("assignments", assignments); + + // Entity list section + JsonArray entityList = createEntityList(federateInstances); + graphObject.add("entityList", entityList); + + // File sharing lists (empty for this example) + graphObject.add("filesharingLists", new JsonArray()); + + return graphObject; + } + + private static JsonObject createAuthEntry( + int id, + String entityHost, + String authHost, + int tcpPort, + int udpPort, + int authPort, + int callbackPort, + int dbProtectionMethod, + boolean backupEnabled, + boolean contextualCallbackEnabled) { + JsonObject authEntry = new JsonObject(); + authEntry.addProperty("id", id); + authEntry.addProperty("entityHost", entityHost); + authEntry.addProperty("authHost", authHost); + authEntry.addProperty("tcpPort", tcpPort); + authEntry.addProperty("udpPort", udpPort); + authEntry.addProperty("authPort", authPort); + authEntry.addProperty("callbackPort", callbackPort); + authEntry.addProperty("dbProtectionMethod", dbProtectionMethod); + authEntry.addProperty("backupEnabled", backupEnabled); + authEntry.addProperty("contextualCallbackEnabled", contextualCallbackEnabled); + return authEntry; + } + + private static JsonArray createEntityList(List federateInstances) { + JsonArray entityList = new JsonArray(); + + // RTI entity + JsonObject rti = createEntity("Servers", "net1.rti", "Net1.rti"); + // TODO: Make the two below work on future. + rti.addProperty("port", 15045); + rti.addProperty("host", "localhost"); + entityList.add(rti); + + // Federate entities + for (FederateInstance federate : federateInstances) { + String federateName = federate.name; + JsonObject entity = createEntity("Clients", "net1." + federateName, "Net1." + federateName); + entityList.add(entity); + } + return entityList; + } + + private static JsonObject createEntity(String group, String name, String credentialPrefix) { + JsonObject entity = new JsonObject(); + entity.addProperty("group", group); + entity.addProperty("name", name); + entity.addProperty("distProtocol", "TCP"); + entity.addProperty("usePermanentDistKey", false); + entity.addProperty("distKeyValidityPeriod", "1*hour"); + entity.addProperty("maxSessionKeysPerRequest", 1); + entity.addProperty("netName", "net1"); + entity.addProperty("credentialPrefix", credentialPrefix); + entity.add("backupToAuthIds", new JsonArray()); // Empty array for backupToAuthIds + return entity; + } + + private static void copyCredentials(FederationFileConfig fileConfig, Path sstRepoRootPath) + throws IOException { + // Copy auth_certs. + Path source1 = sstRepoRootPath.resolve("entity").resolve("auth_certs"); + Path destination1 = fileConfig.getSSTCredentialsPath().resolve("auth_certs"); + + // Copy keys. + Path source2 = sstRepoRootPath.resolve("entity").resolve("credentials").resolve("keys"); + Path destination2 = fileConfig.getSSTCredentialsPath().resolve("keys"); + FileUtil.copyDirectoryContents(source1, destination1, false); + FileUtil.copyDirectoryContents(source2, destination2, false); + } + + private static void copyAuthNecessary(FederationFileConfig fileConfig, Path sstRepoRootPath) + throws IOException { + // Copy Auth credentials. + Path source1 = sstRepoRootPath.resolve("auth").resolve("credentials").resolve("ca"); + Path destination1 = fileConfig.getSSTAuthPath().resolve("credentials").resolve("ca"); + + // Copy Auth databases. + Path source2 = sstRepoRootPath.resolve("auth").resolve("databases"); + Path destination2 = fileConfig.getSSTAuthPath().resolve("databases"); + + // Copy Auth properties. + Path source3 = sstRepoRootPath.resolve("auth").resolve("properties"); + Path destination3 = fileConfig.getSSTAuthPath().resolve("properties"); + + FileUtil.copyDirectoryContents(source1, destination1, false); + FileUtil.copyDirectoryContents(source2, destination2, false); + FileUtil.copyDirectoryContents(source3, destination3, false); + } + + private static void updatePropertiesFile(FederationFileConfig fileConfig) throws IOException { + File file = + Paths.get( + fileConfig.getSSTAuthPath().resolve("properties").toString(), + "exampleAuth101.properties") + .toFile(); + List updatedLines = new ArrayList<>(); + String sstAuthPathStr = fileConfig.getSSTAuthPath().toString(); + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith("entity_key_store_path=")) { + line = updatePath(line, sstAuthPathStr); + } else if (line.startsWith("internet_key_store_path=")) { + line = updatePath(line, sstAuthPathStr); + } else if (line.startsWith("database_key_store_path=")) { + line = updatePath(line, sstAuthPathStr); + } else if (line.startsWith("database_encryption_key_path=")) { + line = updatePath(line, sstAuthPathStr); + } else if (line.startsWith("trusted_ca_cert_paths=")) { + line = updatePath(line, sstAuthPathStr); + } else if (line.startsWith("auth_database_dir=")) { + line = updatePath(line, sstAuthPathStr); + } + updatedLines.add(line); + } + } + + // Write the updated lines back to the file + try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { + for (String updatedLine : updatedLines) { + writer.write(updatedLine); + writer.newLine(); + } + } + } + + private static String updatePath(String line, String sstAuthPathStr) { + return line.replace("../", sstAuthPathStr + "/"); + } +} From 77fa68cd6365de7a9e83e30b282695520f557ff2 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:57:20 -0700 Subject: [PATCH 13/22] Add sst generator to start generate. --- .../java/org/lflang/federated/generator/FedGenerator.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/org/lflang/federated/generator/FedGenerator.java b/core/src/main/java/org/lflang/federated/generator/FedGenerator.java index e9379dd108..262442e1f7 100644 --- a/core/src/main/java/org/lflang/federated/generator/FedGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/FedGenerator.java @@ -59,12 +59,14 @@ import org.lflang.lf.VarRef; import org.lflang.target.Target; import org.lflang.target.TargetConfig; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.CoordinationProperty; import org.lflang.target.property.DockerProperty; import org.lflang.target.property.DockerProperty.DockerOptions; import org.lflang.target.property.KeepaliveProperty; import org.lflang.target.property.NoCompileProperty; import org.lflang.target.property.PlatformProperty; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; import org.lflang.target.property.type.CoordinationModeType.CoordinationMode; import org.lflang.util.Averager; import org.lflang.util.FileUtil; @@ -159,6 +161,12 @@ public boolean doGenerate(Resource resource, LFGeneratorContext context) throws // for logical connections. replaceFederateConnectionsWithProxies(federation, main, resource); + // Generate Credentials for SST. + if (context.getTargetConfig().get(CommunicationModeProperty.INSTANCE) + == CommunicationMode.SST) { + SSTGenerator.setupSST(fileConfig, federates, messageReporter, context); + } + FedEmitter fedEmitter = new FedEmitter( fileConfig, From a058388c6b14da46c3172a9690c4fb9ce961647f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:57:55 -0700 Subject: [PATCH 14/22] Add auth execution script and rti execution script with -sst --- .../launcher/FedLauncherGenerator.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java index 192dcef334..5f8c7f0c26 100644 --- a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java +++ b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java @@ -36,13 +36,17 @@ import org.lflang.MessageReporter; import org.lflang.federated.generator.FederateInstance; import org.lflang.federated.generator.FederationFileConfig; +import org.lflang.federated.generator.SSTGenerator; import org.lflang.target.TargetConfig; import org.lflang.target.property.AuthProperty; import org.lflang.target.property.ClockSyncModeProperty; import org.lflang.target.property.ClockSyncOptionsProperty; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.DNETProperty; +import org.lflang.target.property.SSTPathProperty; import org.lflang.target.property.TracingProperty; import org.lflang.target.property.type.ClockSyncModeType.ClockSyncMode; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; /** * Utility class that can be used to create a launcher for federated LF programs. @@ -302,6 +306,20 @@ private String getSetupCode() { "# Launch the federates:"); } + private String getSSTSetup() { + return String.join( + "\n\n", + "# Prompt for the password before starting SST Auth", + "echo \"Enter password for Auth.\"", + "read -s PASSWORD", + "# Launch the SST Auth.", + "java -jar " + + targetConfig.get(SSTPathProperty.INSTANCE) + + "/auth/auth-server/target/auth-server-jar-with-dependencies.jar -p " + + fileConfig.getSSTAuthPath().toString() + + "/properties/exampleAuth101.properties --password=$PASSWORD &"); + } + private String getDistHeader() { return String.join( "\n", @@ -324,6 +342,12 @@ private String getRtiCommand(List federates, boolean isRemote) if (targetConfig.getOrDefault(TracingProperty.INSTANCE).isEnabled()) { commands.add(" -t \\"); } + if (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) { + commands.add( + " -sst " + + SSTGenerator.getSSTConfig(fileConfig, "rti").toString() + + " \\"); + } if (!targetConfig.getOrDefault(DNETProperty.INSTANCE)) { commands.add(" -d \\"); } From 3c1b26182563b354d7843c48bfa9ad86af1022a7 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 19:58:34 -0700 Subject: [PATCH 15/22] Add federate generate script to execute with -sst option, getting the config. --- .../org/lflang/federated/launcher/CBuildConfig.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/lflang/federated/launcher/CBuildConfig.java b/core/src/main/java/org/lflang/federated/launcher/CBuildConfig.java index f2211577ac..edf0ad8eb8 100644 --- a/core/src/main/java/org/lflang/federated/launcher/CBuildConfig.java +++ b/core/src/main/java/org/lflang/federated/launcher/CBuildConfig.java @@ -28,7 +28,10 @@ import org.lflang.MessageReporter; import org.lflang.federated.generator.FederateInstance; import org.lflang.federated.generator.FederationFileConfig; +import org.lflang.federated.generator.SSTGenerator; import org.lflang.generator.c.CCompiler; +import org.lflang.target.property.CommunicationModeProperty; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; /** * Utility class that can be used to create a launcher for federated LF programs that are written in @@ -55,6 +58,14 @@ public String compileCommand() { @Override public String localExecuteCommand() { - return fileConfig.getFedBinPath().resolve(federate.name) + " -i $FEDERATION_ID"; + String commandToReturn = + fileConfig.getFedBinPath().resolve(federate.name) + " -i $FEDERATION_ID"; + if (federate.targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) { + commandToReturn = + commandToReturn + + " -sst " + + SSTGenerator.getSSTConfig(fileConfig, federate.name).toString(); + } + return commandToReturn; } } From 83a7b5981434469adb400f92e3d5119fa5ed8772 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sat, 1 Feb 2025 20:14:25 -0700 Subject: [PATCH 16/22] Add some error checking thread. --- .../federated/generator/SSTGenerator.java | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java index 2c9402abd7..2b0cef8cfb 100644 --- a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java @@ -10,6 +10,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -74,29 +75,47 @@ public static void setupSST( processBuilder.command("bash", "-c", "./cleanAll.sh ; ./generateAll.sh -g " + graphPath); // Start the process - try { - Process process = processBuilder.start(); - - // Wait for the process to complete - int exitCode = process.waitFor(); - - // Output the result - if (exitCode == 0) { - messageReporter.nowhere().info("Credential generation script execution successed."); - } else { - String errorOutput = new String(process.getErrorStream().readAllBytes()); - context - .getErrorReporter() - .nowhere() - .error( - "Script execution failed with exit code: " - + exitCode - + "\nError Output: " - + errorOutput); - } - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); +try { + Process process = processBuilder.start(); + + // Create threads to capture output and error streams + Thread outputThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + messageReporter.nowhere().info("[SST Script] " + line); + } + } catch (IOException e) { + e.printStackTrace(); + } + }); + + Thread errorThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = reader.readLine()) != null) { + context.getErrorReporter().nowhere().error("[SST Script Error] " + line); + } + } catch (IOException e) { + e.printStackTrace(); + } + }); + + outputThread.start(); + errorThread.start(); + + int exitCode = process.waitFor(); // Wait for process to finish + outputThread.join(); + errorThread.join(); + + if (exitCode == 0) { + messageReporter.nowhere().info("Credential generation script execution succeeded."); + } else { + messageReporter.nowhere().error("Script execution failed with exit code: " + exitCode); } +} catch (IOException | InterruptedException e) { + throw new RuntimeException(e); +} // Copy credentials. try { @@ -136,6 +155,7 @@ public static Path getSSTConfig(FederationFileConfig fileConfig, String name) { return fileConfig.getSSTConfigPath().resolve(name + ".config"); } + // TODO: FIX HERE!!!!!!!!!!!!!!! private static void generateSSTConfig(FederationFileConfig fileConfig, String name) { // Values to fill in String entityName = "net1." + name; From 349dd0477aea2cf935a38e48a138fd6136141ec0 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Sun, 2 Feb 2025 19:51:58 -0700 Subject: [PATCH 17/22] Fix SST generator. --- .../federated/generator/SSTGenerator.java | 95 +++++++++++-------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java index 2b0cef8cfb..9e46bbd9a8 100644 --- a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java @@ -75,47 +75,53 @@ public static void setupSST( processBuilder.command("bash", "-c", "./cleanAll.sh ; ./generateAll.sh -g " + graphPath); // Start the process -try { - Process process = processBuilder.start(); - - // Create threads to capture output and error streams - Thread outputThread = new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - messageReporter.nowhere().info("[SST Script] " + line); - } - } catch (IOException e) { - e.printStackTrace(); - } - }); - - Thread errorThread = new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String line; - while ((line = reader.readLine()) != null) { - context.getErrorReporter().nowhere().error("[SST Script Error] " + line); - } - } catch (IOException e) { - e.printStackTrace(); - } - }); - - outputThread.start(); - errorThread.start(); - - int exitCode = process.waitFor(); // Wait for process to finish - outputThread.join(); - errorThread.join(); - - if (exitCode == 0) { + try { + Process process = processBuilder.start(); + + // Create threads to capture output and error streams + Thread outputThread = + new Thread( + () -> { + try (BufferedReader reader = + new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + messageReporter.nowhere().info("[SST Script] " + line); + } + } catch (IOException e) { + e.printStackTrace(); + } + }); + + Thread errorThread = + new Thread( + () -> { + try (BufferedReader reader = + new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = reader.readLine()) != null) { + context.getErrorReporter().nowhere().error("[SST Script Error] " + line); + } + } catch (IOException e) { + e.printStackTrace(); + } + }); + + outputThread.start(); + errorThread.start(); + + int exitCode = process.waitFor(); // Wait for process to finish + outputThread.join(); + errorThread.join(); + + if (exitCode == 0) { messageReporter.nowhere().info("Credential generation script execution succeeded."); - } else { + } else { messageReporter.nowhere().error("Script execution failed with exit code: " + exitCode); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); } -} catch (IOException | InterruptedException e) { - throw new RuntimeException(e); -} // Copy credentials. try { @@ -312,6 +318,19 @@ private static JsonObject createEntity(String group, String name, String credent entity.addProperty("maxSessionKeysPerRequest", 1); entity.addProperty("netName", "net1"); entity.addProperty("credentialPrefix", credentialPrefix); + // Add distributionCryptoSpec + JsonObject distributionCryptoSpec = new JsonObject(); + distributionCryptoSpec.addProperty("cipher", "AES-128-CBC"); + distributionCryptoSpec.addProperty("mac", "SHA256"); + entity.add("distributionCryptoSpec", distributionCryptoSpec); + + // Add sessionCryptoSpec + JsonObject sessionCryptoSpec = new JsonObject(); + sessionCryptoSpec.addProperty("cipher", "AES-128-CBC"); + sessionCryptoSpec.addProperty("mac", "SHA256"); + entity.add("sessionCryptoSpec", sessionCryptoSpec); + + entity.addProperty("host", "localhost"); entity.add("backupToAuthIds", new JsonArray()); // Empty array for backupToAuthIds return entity; } From 23f000ccd562b280bd94cade5606e67d53cc38bb Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Feb 2025 12:33:08 -0700 Subject: [PATCH 18/22] Add to get RTI's port and host name. --- .../federated/generator/SSTGenerator.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java index 9e46bbd9a8..1636412aa5 100644 --- a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java @@ -20,6 +20,7 @@ import org.lflang.generator.LFGeneratorContext; import org.lflang.target.property.SSTPathProperty; import org.lflang.util.FileUtil; +import org.lflang.federated.launcher.RtiConfig; /** * SST related methods. @@ -31,7 +32,8 @@ public static void setupSST( FederationFileConfig fileConfig, List federates, MessageReporter messageReporter, - LFGeneratorContext context) { + LFGeneratorContext context, + RtiConfig rtiConfig) { if (context.getTargetConfig().get(SSTPathProperty.INSTANCE).isEmpty()) { context .getErrorReporter() @@ -50,7 +52,7 @@ public static void setupSST( // Set graph path. Path graphPath = fileConfig.getSSTGraphsPath().resolve(fileConfig.name + ".graph"); // Generate the graph file content - JsonObject graphObject = SSTGenerator.generateGraphFile(federates); + JsonObject graphObject = SSTGenerator.generateGraphFile(federates, rtiConfig); // Write the graph object to a JSON file try (FileWriter fileWriter = new FileWriter(graphPath.toString())) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); @@ -143,7 +145,7 @@ public static void setupSST( messageReporter .nowhere() .info( - "Federate generated SST config into: " + "Generated RTI's SST config into: " + SSTGenerator.getSSTConfig(fileConfig, "rti").toString()); // Generate SST config for the federates. @@ -161,7 +163,6 @@ public static Path getSSTConfig(FederationFileConfig fileConfig, String name) { return fileConfig.getSSTConfigPath().resolve(name + ".config"); } - // TODO: FIX HERE!!!!!!!!!!!!!!! private static void generateSSTConfig(FederationFileConfig fileConfig, String name) { // Values to fill in String entityName = "net1." + name; @@ -227,7 +228,7 @@ private static void generateSSTConfig(FederationFileConfig fileConfig, String na } } - private static JsonObject generateGraphFile(List federateInstances) { + private static JsonObject generateGraphFile(List federateInstances, RtiConfig rtiConfig) { JsonObject graphObject = new JsonObject(); // Auth list @@ -255,7 +256,7 @@ private static JsonObject generateGraphFile(List federateInsta graphObject.add("assignments", assignments); // Entity list section - JsonArray entityList = createEntityList(federateInstances); + JsonArray entityList = createEntityList(federateInstances, rtiConfig); graphObject.add("entityList", entityList); // File sharing lists (empty for this example) @@ -289,14 +290,14 @@ private static JsonObject createAuthEntry( return authEntry; } - private static JsonArray createEntityList(List federateInstances) { + private static JsonArray createEntityList(List federateInstances, RtiConfig rtiConfig) { JsonArray entityList = new JsonArray(); // RTI entity JsonObject rti = createEntity("Servers", "net1.rti", "Net1.rti"); // TODO: Make the two below work on future. - rti.addProperty("port", 15045); - rti.addProperty("host", "localhost"); + rti.addProperty("port", rtiConfig.getPort()); + rti.addProperty("host", rtiConfig.getHost()); entityList.add(rti); // Federate entities From c912410bd92c80a8a44432a7291450ab46ad7a5b Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Feb 2025 12:34:01 -0700 Subject: [PATCH 19/22] Add to get RTI config for sstGenerator. --- .../java/org/lflang/federated/generator/FedGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/generator/FedGenerator.java b/core/src/main/java/org/lflang/federated/generator/FedGenerator.java index 262442e1f7..632860d20e 100644 --- a/core/src/main/java/org/lflang/federated/generator/FedGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/FedGenerator.java @@ -161,10 +161,10 @@ public boolean doGenerate(Resource resource, LFGeneratorContext context) throws // for logical connections. replaceFederateConnectionsWithProxies(federation, main, resource); - // Generate Credentials for SST. + // If communication mode is SST, generate configurations for SST. if (context.getTargetConfig().get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) { - SSTGenerator.setupSST(fileConfig, federates, messageReporter, context); + SSTGenerator.setupSST(fileConfig, federates, messageReporter, context, rtiConfig); } FedEmitter fedEmitter = From a27778523b9348d5688c851b7758d03e514e50ba Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Feb 2025 13:20:22 -0700 Subject: [PATCH 20/22] Add generated script to run Auth, and generate Auth with password as main reactor name. --- .../federated/generator/SSTGenerator.java | 40 +++++++++---------- .../launcher/FedLauncherGenerator.java | 21 +++++++--- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java index 1636412aa5..ccad0d971c 100644 --- a/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java +++ b/core/src/main/java/org/lflang/federated/generator/SSTGenerator.java @@ -17,10 +17,10 @@ import java.util.ArrayList; import java.util.List; import org.lflang.MessageReporter; +import org.lflang.federated.launcher.RtiConfig; import org.lflang.generator.LFGeneratorContext; import org.lflang.target.property.SSTPathProperty; import org.lflang.util.FileUtil; -import org.lflang.federated.launcher.RtiConfig; /** * SST related methods. @@ -74,7 +74,20 @@ public static void setupSST( // Clean the old credentials & generate new credentials. // processBuilder.command("bash", "-c", "echo" + graphPath); - processBuilder.command("bash", "-c", "./cleanAll.sh ; ./generateAll.sh -g " + graphPath); + processBuilder.command( + "bash", + "-c", + "echo \"Executing: ./cleanAll.sh ; ./generateAll.sh -g " + + graphPath + + " -p " + + fileConfig.name + + "\" && " + + "./cleanAll.sh ; ./generateAll.sh -g " + + graphPath + + " -p " + + fileConfig.name + + " && " + + "echo \"generateAll.sh finished successfully.\""); // Start the process try { @@ -95,26 +108,10 @@ public static void setupSST( } }); - Thread errorThread = - new Thread( - () -> { - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String line; - while ((line = reader.readLine()) != null) { - context.getErrorReporter().nowhere().error("[SST Script Error] " + line); - } - } catch (IOException e) { - e.printStackTrace(); - } - }); - outputThread.start(); - errorThread.start(); int exitCode = process.waitFor(); // Wait for process to finish outputThread.join(); - errorThread.join(); if (exitCode == 0) { messageReporter.nowhere().info("Credential generation script execution succeeded."); @@ -228,7 +225,8 @@ private static void generateSSTConfig(FederationFileConfig fileConfig, String na } } - private static JsonObject generateGraphFile(List federateInstances, RtiConfig rtiConfig) { + private static JsonObject generateGraphFile( + List federateInstances, RtiConfig rtiConfig) { JsonObject graphObject = new JsonObject(); // Auth list @@ -290,12 +288,12 @@ private static JsonObject createAuthEntry( return authEntry; } - private static JsonArray createEntityList(List federateInstances, RtiConfig rtiConfig) { + private static JsonArray createEntityList( + List federateInstances, RtiConfig rtiConfig) { JsonArray entityList = new JsonArray(); // RTI entity JsonObject rti = createEntity("Servers", "net1.rti", "Net1.rti"); - // TODO: Make the two below work on future. rti.addProperty("port", rtiConfig.getPort()); rti.addProperty("host", rtiConfig.getHost()); entityList.add(rti); diff --git a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java index 5f8c7f0c26..a0107317b2 100644 --- a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java +++ b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java @@ -121,6 +121,9 @@ public void doGenerate(List federates, RtiConfig rtiConfig) { StringBuilder distCode = new StringBuilder(); shCode.append(getSetupCode()).append("\n"); String distHeader = getDistHeader(); + if (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) { + shCode.append(getSSTAuthExecutionCode()).append("\n"); + } String host = rtiConfig.getHost(); String target = host; @@ -293,6 +296,9 @@ private String getSetupCode() { " kill ${pids[@]} || true", " printf \"#### Killing RTI %s.\\n\" ${RTI}", " kill ${RTI} || true", + (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) + ? " printf \"#### Killing Auth %s.\\n\" ${AUTH}\n kill ${AUTH} || true" + : "", " exit 1", " fi", "}", @@ -306,18 +312,21 @@ private String getSetupCode() { "# Launch the federates:"); } - private String getSSTSetup() { + private String getSSTAuthExecutionCode() { return String.join( - "\n\n", - "# Prompt for the password before starting SST Auth", - "echo \"Enter password for Auth.\"", - "read -s PASSWORD", + "\n", + "\n# Prompt for the password before starting SST Auth", + "echo \"Executing Auth.\"", "# Launch the SST Auth.", "java -jar " + targetConfig.get(SSTPathProperty.INSTANCE) + "/auth/auth-server/target/auth-server-jar-with-dependencies.jar -p " + fileConfig.getSSTAuthPath().toString() - + "/properties/exampleAuth101.properties --password=$PASSWORD &"); + + "/properties/exampleAuth101.properties --password=" + + fileConfig.name + + ">& auth.log" + + "&\n", + "AUTH=$!"); } private String getDistHeader() { From 5bea11bd51475d517dd8c33615e2ac9808caf08f Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Tue, 4 Feb 2025 15:17:45 -0700 Subject: [PATCH 21/22] Fix auth launcher with logging. --- .../launcher/FedLauncherGenerator.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java index a0107317b2..7a71c677d4 100644 --- a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java +++ b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java @@ -291,14 +291,14 @@ private String getSetupCode() { " if [ \"$EXITED_SUCCESSFULLY\" = true ] ; then", " exit 0", " else", + (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) + ? " printf \"#### Killing Auth %s.\\n\" ${AUTH}\n kill ${AUTH} || true" + : "", " printf \"Killing federate %s.\\n\" ${pids[*]}", " # The || true clause means this is not an error if kill fails.", " kill ${pids[@]} || true", " printf \"#### Killing RTI %s.\\n\" ${RTI}", " kill ${RTI} || true", - (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) - ? " printf \"#### Killing Auth %s.\\n\" ${AUTH}\n kill ${AUTH} || true" - : "", " exit 1", " fi", "}", @@ -313,19 +313,28 @@ private String getSetupCode() { } private String getSSTAuthExecutionCode() { - return String.join( - "\n", - "\n# Prompt for the password before starting SST Auth", - "echo \"Executing Auth.\"", - "# Launch the SST Auth.", + String authLaunchCode = "java -jar " + targetConfig.get(SSTPathProperty.INSTANCE) + "/auth/auth-server/target/auth-server-jar-with-dependencies.jar -p " + fileConfig.getSSTAuthPath().toString() + "/properties/exampleAuth101.properties --password=" - + fileConfig.name - + ">& auth.log" - + "&\n", + + fileConfig.name; + + String launchCodeWithLogging = String.join(" ", authLaunchCode, ">& auth.log &"); + String launchCodeWithoutLogging = String.join(" ", authLaunchCode, "&"); + + return String.join( + "\n", + "\n# Prompt for the password before starting SST Auth", + "echo \"Executing Auth.\"", + "# Launch the SST Auth.", + "if [ \"$1\" = \"-l\" ]; then", + launchCodeWithLogging, + "else", + launchCodeWithoutLogging, + "fi", + "# Store the PID of the Auth", "AUTH=$!"); } From 72560308fb90fb4d1f89c99ddd3a7b2370bef5d8 Mon Sep 17 00:00:00 2001 From: Dongha Kim Date: Wed, 5 Feb 2025 14:47:52 -0700 Subject: [PATCH 22/22] Fix to not make empty line. --- .../lflang/federated/launcher/FedLauncherGenerator.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java index 7a71c677d4..e9441ad830 100644 --- a/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java +++ b/core/src/main/java/org/lflang/federated/launcher/FedLauncherGenerator.java @@ -274,6 +274,10 @@ public void doGenerate(List federates, RtiConfig rtiConfig) { } private String getSetupCode() { + String killAuthCommand = + (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) + ? " printf \"#### Killing Auth %s.\\n\" ${AUTH}\n kill ${AUTH} || true\n" + : ""; return String.join( "\n", "#!/bin/bash -l", @@ -291,10 +295,7 @@ private String getSetupCode() { " if [ \"$EXITED_SUCCESSFULLY\" = true ] ; then", " exit 0", " else", - (targetConfig.get(CommunicationModeProperty.INSTANCE) == CommunicationMode.SST) - ? " printf \"#### Killing Auth %s.\\n\" ${AUTH}\n kill ${AUTH} || true" - : "", - " printf \"Killing federate %s.\\n\" ${pids[*]}", + killAuthCommand + " printf \"Killing federate %s.\\n\" ${pids[*]}", " # The || true clause means this is not an error if kill fails.", " kill ${pids[@]} || true", " printf \"#### Killing RTI %s.\\n\" ${RTI}",