Skip to content

Commit

Permalink
feat: add support for REST API
Browse files Browse the repository at this point in the history
  • Loading branch information
npepinpe committed Dec 29, 2024
1 parent 398b618 commit 89ba7a3
Show file tree
Hide file tree
Showing 19 changed files with 249 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@
*
* <pre>{@code
* ZeebeClient.newClientBuilder()
* .brokerContainerPoint(container.getExternalGatewayAddress())
* .grpcAddress(container.getGrpcAddress())
* .restAddress(container.getRestAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* <p>Note that if your client is also a container within the same network, you can and should use
* the {@link #getInternalGatewayAddress()}.
* the {@link #getInternalGrpcAddress()} and {@link #getInternalRestAddress()} variants.
*/
@API(status = Status.STABLE)
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue"})
Expand Down
189 changes: 182 additions & 7 deletions core/src/main/java/io/zeebe/containers/ZeebeGatewayNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
import org.apiguardian.api.API.Status;
import org.testcontainers.containers.GenericContainer;

import java.net.URI;

/**
* Represents common properties of nodes which can act as a gateway for a Zeebe cluster, e.g. {@link
* ZeebeContainer} or {@link ZeebeGatewayContainer}.
*
* <p>You can use {@link #getExternalGatewayAddress()} for clients which are not part of the gateway
* container's network; this is most likely what you want to use, so when in doubt use this.
*
* <p>You can use {@link #getInternalGatewayAddress()} for clients which are within the gateway
* container's network.
* <p>You should typically use {@link #getGrpcAddress()} and {@link #getRestAddress()} to wire your
* clients with this gateway. If your client happens to be running in the same network as the Docker
* container, then you may want to use {@link #getInternalGrpcAddress()} or {@link
* #getInternalRestAddress()} instead.
*
* @param <T> the concrete type of the underlying container
*/
Expand Down Expand Up @@ -73,13 +74,16 @@ public interface ZeebeGatewayNode<T extends GenericContainer<T> & ZeebeGatewayNo
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .withBrokerContactPoint(container.getExternalGatewayAddress())
* .gatewayAddress(container.getExternalGatewayAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* @return the gateway address visible from outside the docker network
* @deprecated Use the protocol specific variants from now on, {@link #getGrpcAddress()} or {@link
* #getRestAddress()}
*/
@Deprecated
default String getExternalGatewayAddress() {
return getExternalAddress(ZeebePort.GATEWAY.getPort());
}
Expand All @@ -91,14 +95,185 @@ default String getExternalGatewayAddress() {
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .withBrokerContactPoint(container.getInternalGatewayAddress())
* .gatewayAddress(container.getInternalGatewayAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* @return the gateway address visible from within the docker network
* @deprecated Use the protocol specific variants from now on, {@link #getInternalGrpcAddress()}
* or {@link #getInternalRestAddress()}
*/
@Deprecated
default String getInternalGatewayAddress() {
return getInternalAddress(ZeebePort.GATEWAY.getPort());
}

/**
* Returns an address accessible from within the container's network for the REST API. Primarily
* meant to be used by clients.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .restAddress(container.getInternalRestUrl())
* .usePlaintext()
* .build();
* }</pre>
*
* @return internally accessible REST API address
*/
default URI getInternalRestAddress() {
return getInternalRestAddress("http");
}

/**
* Returns an address accessible from within the container's network for the REST API. Primarily
* meant to be used by clients.
*
* <p>Use this variant if you need to specify a different scheme, e.g. HTTPS.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .restAddress(container.getInternalRestUrl("https"))
* .build();
* }</pre>
*
* @param scheme the expected scheme (e.g. HTTP, HTTPS)
* @return internally accessible REST API address
*/
default URI getInternalRestAddress(final String scheme) {
final int port = ZeebePort.GATEWAY_REST.getPort();
return URI.create(String.format("%s://%s:%d", scheme, getInternalHost(), port));
}

/**
* Returns the address of the REST API a client which is not part of the container's network
* should use. If you want an address accessible from within the container's own network, use *
* {@link #getInternalRestAddress()}
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .restAddress(container.getRestAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* @return externally accessible REST API address
*/
default URI getRestAddress() {
return getRestAddress("http");
}

/**
* Returns the address of the REST API a client which is not part of the container's network
* should use. If you want an address accessible from within the container's own network, use
* {@link #getInternalRestAddress(String)}.
*
* <p>Use this method if you need to specify a different connection scheme, e.g. HTTPS.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .restAddress(container.getExternalRestAddress("https"))
* .build();
* }</pre>
*
* @param scheme the expected scheme (e.g. HTTP, HTTPS)
* @return externally accessible REST API address
*/
default URI getRestAddress(final String scheme) {
final int port = getMappedPort(ZeebePort.GATEWAY_REST.getPort());
return URI.create(String.format("%s://%s:%d", scheme, getExternalHost(), port));
}

/**
* Returns an address accessible from within the container's network for the gRPC API. Primarily
* meant to be used by clients.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .grpcAddress(container.getInternalGrpcAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* @return internally accessible REST API address
*/
default URI getInternalGrpcAddress() {
return getInternalGrpcAddress("http");
}

/**
* Returns an address accessible from within the container's network for the REST API. Primarily
* meant to be used by clients.
*
* <p>Use this variant if you need to specify a different scheme, e.g. HTTPS.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .grpcAddress(container.getInternalGrpcAddress("https"))
* .build();
* }</pre>
*
* @param scheme the expected scheme (e.g. HTTP, HTTPS)
* @return internally accessible REST API address
*/
default URI getInternalGrpcAddress(final String scheme) {
final int port = ZeebePort.GATEWAY_REST.getPort();
return URI.create(String.format("%s://%s:%d", scheme, getInternalHost(), port));
}

/**
* Returns the address of the gRPC API a client which is not part of the container's network
* should use. If you want an address accessible from within the container's own network, use
* {@link #getInternalGrpcAddress()}.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .grpcAddress(container.getGrpcAddress())
* .usePlaintext()
* .build();
* }</pre>
*
* @return externally accessible gRPC API address
*/
default URI getGrpcAddress() {
return getGrpcAddress("http");
}

/**
* Returns the address of the gRPC API a client which is not part of the container's network
* should use. If you want an address accessible from within the container's own network, use
* {@link #getInternalGrpcAddress(String)}.
*
* <p>Use this method if you need to specify a different connection scheme, e.g. HTTPS.
*
* <p>You can build your client like this:
*
* <pre>@{code
* ZeebeClient.newClientBuilder()
* .grpcAddress(container.getGrpcAddress("https"))
* .build();
* }</pre>
*
* @param scheme the expected scheme (e.g. HTTP, HTTPS)
* @return externally accessible gRPC API address
*/
default URI getGrpcAddress(final String scheme) {
final int port = getMappedPort(ZeebePort.GATEWAY_GRPC.getPort());
return URI.create(String.format("%s://%s:%d", scheme, getExternalHost(), port));
}
}
1 change: 1 addition & 0 deletions core/src/main/java/io/zeebe/containers/ZeebeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.time.Duration;
import java.util.List;

import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;
import org.testcontainers.containers.Container;
Expand Down
16 changes: 14 additions & 2 deletions core/src/main/java/io/zeebe/containers/ZeebePort.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@
public enum ZeebePort {
/** Port of the command API, i.e. the port used by the gateway to communicate with the broker */
COMMAND(26501),
/** Port of the gateway API, i.e. the port used by the client to communicate with any gateway */
/**
* Deprecated reference to the old GATEWAY port, which is the gRPC port; use {@link #GATEWAY_REST}
* or {@link #GATEWAY_GRPC} in the future
*/
@Deprecated
GATEWAY(26500),
/** Port for internal communication, i.e. what all nodes use to communicate for clustering */
INTERNAL(26502),
/** Port for the management server, i.e. actuators, metrics, etc. */
MONITORING(9600);
MONITORING(9600),
/**
* Port of the gateway REST API, i.e. the port used by the client to communicate with any gateway
*/
GATEWAY_REST(8080),
/**
* Port of the gateway gRPC API, i.e. the port used by the client to communicate with any gateway
*/
GATEWAY_GRPC(26500);

private final int port;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ public ZeebeClientBuilder newClientBuilder() {
final ZeebeGatewayNode<?> gateway = getAvailableGateway();

return ZeebeClient.newClientBuilder()
.gatewayAddress(gateway.getExternalGatewayAddress())
.grpcAddress(gateway.getGrpcAddress())
.restAddress(gateway.getRestAddress())
.usePlaintext();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ void shouldStartClusterWithEmbeddedGateways() {
for (final ZeebeGatewayNode<?> gateway : cluster.getGateways().values()) {
final Topology topology;
try (final ZeebeClient client =
cluster.newClientBuilder().gatewayAddress(gateway.getExternalGatewayAddress()).build()) {
cluster
.newClientBuilder()
.grpcAddress(gateway.getGrpcAddress())
.restAddress(gateway.getRestAddress())
.build()) {
topology = client.newTopologyRequest().send().join();
}

Expand Down Expand Up @@ -154,7 +158,8 @@ void shouldStartClusterWithMixedGateways() {
try (final ZeebeClient client =
ZeebeClient.newClientBuilder()
.usePlaintext()
.gatewayAddress(gateway.getExternalGatewayAddress())
.grpcAddress(gateway.getGrpcAddress())
.restAddress(gateway.getRestAddress())
.build()) {
final Topology topology = client.newTopologyRequest().send().join();
assertThat(topology.getPartitionsCount())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ private ZeebeContainer getConfiguredClusterBroker(

private ZeebeClient newZeebeClient(final ZeebeContainer node) {
return ZeebeClient.newClientBuilder()
.gatewayAddress(node.getExternalGatewayAddress())
.grpcAddress(node.getGrpcAddress())
.restAddress(node.getRestAddress())
.usePlaintext()
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ private ZeebeBrokerContainer getConfiguredClusterBroker(

private ZeebeClient newZeebeClient(final ZeebeGatewayContainer node) {
return ZeebeClient.newClientBuilder()
.gatewayAddress(node.getExternalGatewayAddress())
.grpcAddress(node.getGrpcAddress())
.restAddress(node.getRestAddress())
.usePlaintext()
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import io.zeebe.containers.ZeebeContainer;
import io.zeebe.containers.ZeebeVolume;
import java.util.concurrent.TimeUnit;

import io.zeebe.containers.util.TestSupport;
import org.junit.jupiter.api.AutoClose;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
Expand Down Expand Up @@ -56,7 +58,7 @@ void shouldReuseVolume() {
Bpmn.createExecutableProcess("process").startEvent().endEvent().done();

// when
try (final ZeebeClient client = newZeebeClient(zeebeContainer)) {
try (final ZeebeClient client = TestSupport.newZeebeClient(zeebeContainer)) {
client.newDeployResourceCommand().addProcessModel(process, "process.bpmn").send().join();
}

Expand All @@ -67,7 +69,7 @@ void shouldReuseVolume() {
// create a process instance from the one we previously deployed - this would fail if we hadn't
// previously deployed our process model
final ProcessInstanceEvent processInstance;
try (final ZeebeClient client = newZeebeClient(zeebeContainer)) {
try (final ZeebeClient client = TestSupport.newZeebeClient(zeebeContainer)) {
processInstance =
client.newCreateInstanceCommand().bpmnProcessId("process").latestVersion().send().join();
}
Expand All @@ -77,11 +79,4 @@ void shouldReuseVolume() {
.as("a process instance was successfully created")
.isPositive();
}

private ZeebeClient newZeebeClient(final ZeebeContainer node) {
return ZeebeClient.newClientBuilder()
.gatewayAddress(node.getExternalGatewayAddress())
.usePlaintext()
.build();
}
}
Loading

0 comments on commit 89ba7a3

Please sign in to comment.