diff --git a/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/Broadcaster.java b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/Broadcaster.java new file mode 100644 index 000000000..7fbf4eb11 --- /dev/null +++ b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/Broadcaster.java @@ -0,0 +1,84 @@ +package de.wuespace.telestion.services.connection; + +import com.fasterxml.jackson.annotation.JsonProperty; +import de.wuespace.telestion.api.config.Config; +import de.wuespace.telestion.api.message.JsonMessage; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.Promise; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class Broadcaster extends AbstractVerticle { + + public final static int DEFAULT_ID = 0; + + public final record Configuration(@JsonProperty + String inAddress, + @JsonProperty + int id) implements JsonMessage { + public Configuration() { + this(null, DEFAULT_ID); + } + } + + @Override + public void start(Promise startPromise) { + this.config = Config.get(this.config, new Configuration(), this.config(), Configuration.class); + + if (broadcasterMap.containsKey(this.config.id())) { + startPromise.fail("The broadcasters id #%d is already taken!".formatted(this.config.id())); + return; + } + + startPromise.complete(); + } + + @Override + public void stop(Promise stopPromise) { + stopPromise.complete(); + } + + public static boolean register(int broadcasterId, String address) { + if (!broadcasterMap.containsKey(broadcasterId)) { + return false; + } + + var broadcaster = broadcasterMap.get(broadcasterId); + broadcaster.addressList.add(address); + + broadcaster.getVertx().eventBus() + .consumer(broadcaster.config.inAddress(), raw -> { + if (!JsonMessage.on(RawMessage.class, raw, broadcaster::send)) { + if (!JsonMessage.on(SenderData.class, raw, broadcaster::send)) { + JsonMessage.on(ConnectionData.class, raw, broadcaster::send); + } + } + }); + return true; + } + + public String[] getAddresses() { + return addressList.toArray(String[]::new); + } + + public Broadcaster() { + this(null); + } + + public Broadcaster(Configuration config) { + this.config = config; + this.addressList = new HashSet<>(); + } + + private void send(JsonMessage msg) { + addressList.forEach(addr -> vertx.eventBus().publish(addr, msg.json())); + } + + private Configuration config; + private final Set addressList; + + private static final Map broadcasterMap = new HashMap<>(); +} diff --git a/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/legacy/package-info.java b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/legacy/package-info.java index 6fdcbbff0..de0c9dce1 100644 --- a/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/legacy/package-info.java +++ b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/legacy/package-info.java @@ -3,11 +3,11 @@ *

* Classes from the old connection api.
* The old connection api contains the following network interfaces: - *

    - *
  • Serial ({@link de.wuespace.telestion.services.connection.legacy.SerialConn})
  • - *
  • Tcp ({@link de.wuespace.telestion.services.connection.legacy.TcpConn})
  • - *
*

+ *
    + *
  • Serial ({@link de.wuespace.telestion.services.connection.legacy.SerialConn})
  • + *
  • Tcp ({@link de.wuespace.telestion.services.connection.legacy.TcpConn})
  • + *
*

* Disclaimer:
* Classes within this package are all marked as deprecated and will be removed soon. diff --git a/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/package-info.java b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/package-info.java new file mode 100644 index 000000000..ee5725e00 --- /dev/null +++ b/modules/telestion-services/src/main/java/de/wuespace/telestion/services/connection/package-info.java @@ -0,0 +1,91 @@ +/** + *

Connection API

+ * + *

Short description:

+ *

+ * This module contains the connection api.
+ * It provides a simplified interface for the most commonly used network interfaces in ground-stations and is + * optimized for the VertX framework. + *

+ * + *

Supported network interfaces:

+ *
    + *
  • TCP
  • + *
  • UDP
  • + *
  • Serial connection (e.g. UART)
  • + *
+ * + *

General Concepts:

+ *

+ * The general concept of the connection api is to allow verticles to implement networking code without knowing the + * specifics of the interface itself. This is achieved by the following concepts: + *

+ *
    + *
  • Sender-Api
  • + *
  • Receiver-Api
  • + *
  • Static-Sending
  • + *
  • Special Concepts
  • + *
  • Manual Mode
  • + *
+ * + *

{@link de.wuespace.telestion.services.connection.Sender Sender-Api}:

+ *

+ * {@link de.wuespace.telestion.services.connection.ConnectionData} or + * {@link de.wuespace.telestion.services.connection.SenderData} sent to this class will be rerouted to the + * designated network interface or their dispatchers. If a connection is not, yet, established the default + * behaviour is to try to create a new connection to the target. + *

+ *

+ * + * Note:
+ * This can fail and the package can be dropped if the targeted network interface controller does not support + * informing about failed packet delivery! + *
+ *

+ * + *

{@link de.wuespace.telestion.services.connection.Receiver Receiver-Api}:

+ *

+ * If this interface is used all incoming {@link de.wuespace.telestion.services.connection.ConnectionData packages} + * will be routed to its output address.
+ * This allows parsers to listen on multiple network connections at once. Answers then can be sent to the + *
Sender-Api again. + *

+ * + *

{@link de.wuespace.telestion.services.connection.StaticSender Static-Sending}:

+ *

+ * In cases where the receiver is already known at start-up, the + * {@link de.wuespace.telestion.services.connection.StaticSender} which can be fed with + * {@link de.wuespace.telestion.services.connection.RawMessage RawMessages} which do not require network interface + * information.
+ * The static sender will automatically send the packages to the connection specified in its config. + *

+ * + *

Special Concepts:

+ *

+ * There are more complex concepts than the previously described ones. This allows for more advanced or network + * specific structures. + *

+ *
Connection established:
+ *

+ * There are cases when one needs to know when a new connection has been established. In this case the XXXX will + * yield the {@link de.wuespace.telestion.services.connection.ConnectionDetails} specifying the connection. + *

+ * + *
{@link de.wuespace.telestion.services.connection.Broadcaster Broadcasting}:
+ *

+ * To send information to all active network interfaces (which support broadcasting), a + * {@link de.wuespace.telestion.services.connection.Broadcaster} verticle needs to be added. + *

+ * + *

Manual Mode:

+ *

+ * In rare cases where the previously described abstractions cannot be applied, + * there is still the possibility to use the network interfaces + * directly. For this refer to the package descriptions of the designated packages. + *

+ * + * @since 0.2.0 + * @version 1.0 + * @author Cedric Boes (cb0s) + */ +package de.wuespace.telestion.services.connection;