From f571f2c02f919b54d4bb94679f3e1aefb8c127fd Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Tue, 13 Feb 2024 23:12:16 +0530 Subject: [PATCH 1/8] messagechannel.send() implementation --- .../varadhi/core/cluster/ClusterManager.java | 2 +- .../varadhi/core/cluster/ClusterMessage.java | 11 ++ .../varadhi/core/cluster/MessageChannel.java | 26 +++++ .../varadhi/core/cluster/MessageHandler.java | 12 ++ .../varadhi/core/cluster/NodeConnection.java | 32 ----- .../varadhi/core/cluster/ResponseMessage.java | 6 + server/build.gradle | 2 + .../varadhi/cluster/MessageChannelImpl.java | 110 ++++++++++++++++++ .../cluster/MessageChannelImplTest.java | 105 +++++++++++++++++ 9 files changed, 273 insertions(+), 33 deletions(-) create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java delete mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/NodeConnection.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java create mode 100644 server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java index 19bd6688..5cf15713 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java @@ -16,7 +16,7 @@ public interface ClusterManager { void addMembershipListener(MembershipListener listener); - NodeConnection connect(String nodeId); + MessageChannel connect(String nodeId); // TODO: Any publish to all methods? diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java new file mode 100644 index 00000000..adc3f828 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java @@ -0,0 +1,11 @@ +package com.flipkart.varadhi.core.cluster; + + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Data; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@messageType") +@Data +public class ClusterMessage { + String id; +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java new file mode 100644 index 00000000..caf535c1 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java @@ -0,0 +1,26 @@ +package com.flipkart.varadhi.core.cluster; + +import java.util.concurrent.CompletableFuture; + +/** + * This is subset of methods from vertx.EventBus which are node specific. Instead of using address concept, we will + * rely on path concept from http. address is not needed as this class is meant to represent a message channel to a specific + * node. + * publish methods are fire & forget. + * send methods don't have any response, but their delivery can be tracked using the future. + * request methods are for traditional request-response pattern. + * + * TODO: whether to use the ClusterMessage class. It is unlikely we will use reply-to-reply feature. + */ +public interface MessageChannel { + + void publish(String path, ClusterMessage msg); + + CompletableFuture send(String path, ClusterMessage msg); + + CompletableFuture request(String path, ClusterMessage msg); + + void addMessageHandler(String path, MessageHandler messageHandler); + + void removeMessageHandler(String path); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java new file mode 100644 index 00000000..036e7441 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java @@ -0,0 +1,12 @@ +package com.flipkart.varadhi.core.cluster; + +import java.util.concurrent.CompletableFuture; + +public interface MessageHandler { + + // handle will be used for messages sent via channel.send() and channel.publish(). + CompletableFuture handle(E message); + + // request will be used for messages sent via channel.request(). + CompletableFuture request(E message); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeConnection.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeConnection.java deleted file mode 100644 index a27de691..00000000 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeConnection.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.flipkart.varadhi.core.cluster; - -import io.vertx.core.Future; -import io.vertx.core.eventbus.DeliveryOptions; -import io.vertx.core.eventbus.Message; - -/** - * This is subset of methods from vertx.EventBus which are node specific. Instead of using address concept, we will - * rely on path concept from http. address is not needed as this class is meant to represent a connection to a specific - * node. - * publish methods are fire & forget. - * send methods don't have any response, but their delivery can be tracked using the future. - * request methods are for traditional request-response pattern. - * - * TODO: whether to use the Message class. It is unlikely we will use reply-to-reply feature. - */ -public interface NodeConnection { - - NodeInfo getNodeInfo(); - - void publish(String path, Object msg); - - void publish(String path, Object msg, DeliveryOptions options); - - Future send(String path, Object msg); - - Future send(String path, Object msg, DeliveryOptions options); - - Future> request(String path, Object msg); - - Future> request(String path, Object msg, DeliveryOptions options); -} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java new file mode 100644 index 00000000..79dca57b --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java @@ -0,0 +1,6 @@ +package com.flipkart.varadhi.core.cluster; + +public class ResponseMessage extends ClusterMessage { + // indicates a response to a request message. + // should contain the reference to original request (e.g. request id). +} diff --git a/server/build.gradle b/server/build.gradle index 5388ba6a..fae6741f 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -48,6 +48,8 @@ dependencies { implementation("org.apache.curator:curator-framework") runtimeOnly(project(":pulsar")) + testImplementation("io.vertx:vertx-zookeeper:4.5.1") + testImplementation(project(":pulsar")) testImplementation(testFixtures(project(":spi"))) testImplementation(testFixtures(project(":entities"))) diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java new file mode 100644 index 00000000..b637972f --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java @@ -0,0 +1,110 @@ +package com.flipkart.varadhi.cluster; + +import com.flipkart.varadhi.core.cluster.*; +import com.flipkart.varadhi.exceptions.NotImplementedException; +import com.flipkart.varadhi.utils.JsonMapper; +import io.vertx.core.Vertx; +import io.vertx.core.eventbus.DeliveryOptions; +import io.vertx.core.eventbus.EventBus; +import io.vertx.core.eventbus.MessageConsumer; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +@Slf4j +public class MessageChannelImpl implements MessageChannel { + + public static final String DELIVERY_KIND_HEADER = "DeliveryKind"; + public static final String DELIVERY_KIND_SEND = "Send"; + public static final String DELIVERY_KIND_REQUEST = "Request"; + public static final String DELIVERY_KIND_PUBLISH = "Publish"; + + private final EventBus vertxEventBus; + private final DeliveryOptions deliveryOptions; + private final Map> registerdConsumers; + + //TODO:: Add config details to DeliveryOptions e.g. timeouts, tracing etc as part of cluster manager changes. + public MessageChannelImpl(Vertx vertx) { + this.vertxEventBus = vertx.eventBus(); + this.deliveryOptions = new DeliveryOptions(); + this.registerdConsumers = new HashMap<>(); + } + + @Override + public void publish(String address, ClusterMessage msg) { + throw new NotImplementedException("publish not implemented"); + } + + @Override + public CompletableFuture send(String address, ClusterMessage msg) { + CompletableFuture future = new CompletableFuture<>(); + DeliveryOptions deliveryOptions = getDeliveryOptions(DELIVERY_KIND_SEND); + vertxEventBus.request(address, JsonMapper.jsonSerialize(msg), deliveryOptions, ar -> { + if (ar.succeeded()) { + log.info("Received reply: " + ar.result().body()); + future.complete(null); + } else { + log.info("send failure: " + ar.cause().getMessage()); + future.completeExceptionally(ar.cause()); + } + }); + return future; + } + + private DeliveryOptions getDeliveryOptions(String deliveryKind) { + // Add other static config options like timeout etc. + return new DeliveryOptions(deliveryOptions).addHeader(DELIVERY_KIND_HEADER, deliveryKind); + } + + @Override + public CompletableFuture request(String address, ClusterMessage msg) { + throw new NotImplementedException("request not implemented"); + } + + @Override + public void removeMessageHandler(String address) { + MessageConsumer consumer = registerdConsumers.get(address); + if (null != consumer) { + consumer.unregister(); + registerdConsumers.remove(address); + } + } + + @Override + public void addMessageHandler(String address, MessageHandler messageHandler) { + //TODO:: Evaluate if dispatcher mechanism is needed to control the execution parallelism. + MessageConsumer consumer = vertxEventBus.consumer(address, message -> { + ClusterMessage clusterMessage = JsonMapper.jsonDeserialize(message.body(), ClusterMessage.class); + if (null == message.replyAddress()) { + // received via publish message + messageHandler.handle(clusterMessage); + log.info("publish({}) message processed.", clusterMessage.getId()); + } else { + String deliveryKind = message.headers().get(DELIVERY_KIND_HEADER); + if (DELIVERY_KIND_SEND.equals(deliveryKind)) { + // received via send message + // acknowledge to indicate that message is delivered, processing is async. + message.reply("Received"); + messageHandler.handle(clusterMessage); + log.info("send({}) message processed.", clusterMessage.getId()); + } else { + // received via request message + messageHandler.request(clusterMessage).handle((response, failure) -> { + if (null != failure) { + message.fail(500, failure.getMessage()); + log.error("request({}) processing failed. {}", clusterMessage.getId(), failure.getMessage()); + } else { + message.reply(JsonMapper.jsonSerialize(response)); + log.info("request({}) processed with response({})", clusterMessage.getId(), response.getId()); + } + return null; + }); + } + } + }); + // not expected to be registered multiple times. + registerdConsumers.put(address, consumer); + } +} diff --git a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java new file mode 100644 index 00000000..bf0fdef0 --- /dev/null +++ b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java @@ -0,0 +1,105 @@ +package com.flipkart.varadhi.cluster; + +import com.fasterxml.jackson.databind.jsontype.NamedType; +import com.flipkart.varadhi.core.cluster.ClusterMessage; +import com.flipkart.varadhi.core.cluster.MessageHandler; +import com.flipkart.varadhi.core.cluster.ResponseMessage; +import com.flipkart.varadhi.utils.JsonMapper; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.spi.cluster.ClusterManager; +import io.vertx.junit5.Checkpoint; +import io.vertx.junit5.VertxExtension; +import io.vertx.junit5.VertxTestContext; +import io.vertx.spi.cluster.zookeeper.ZookeeperClusterManager; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.test.TestingServer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.concurrent.CompletableFuture; + +import static org.mockito.Mockito.spy; + + +@ExtendWith(VertxExtension.class) +public class MessageChannelImplTest { + + CuratorFramework zkCuratorFramework; + + // TODO:: Tests needs to be added, so this will go under refactor + @BeforeEach + public void setup(){ + JsonMapper.getMapper().registerSubtypes(new NamedType(TestClusterMessage.class, "TestClusterMessage")); + JsonMapper.getMapper().registerSubtypes(new NamedType(ExtendedTestClusterMessage.class, "ExtendedTestClusterMessage")); + } + + private Vertx createClusteredVertx() throws Exception { + TestingServer zkCuratorTestingServer = new TestingServer(); + zkCuratorFramework = spy( + CuratorFrameworkFactory.newClient( + zkCuratorTestingServer.getConnectString(), new ExponentialBackoffRetry(1000, 1))); + zkCuratorFramework.start(); + VertxOptions vertxOptions = new VertxOptions(); + ClusterManager cm = new ZookeeperClusterManager(zkCuratorFramework, "foo"); + vertxOptions.setClusterManager(cm); + return Vertx.clusteredVertx(vertxOptions).toCompletionStage().toCompletableFuture().get(); + } + @Test + public void sendMessageNoConsumer(VertxTestContext testContext) throws Exception { + Checkpoint checkpoint = testContext.checkpoint(1); + Vertx vertx = createClusteredVertx(); + MessageChannelImpl c = new MessageChannelImpl(vertx); + ClusterMessage cm = getClusterMessage("foo"); + Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.failing(v -> { + checkpoint.flag(); + })); + } + + @Test + public void testSendMessageConsumerColocated(VertxTestContext testContext) throws Exception{ + Checkpoint checkpoint = testContext.checkpoint(2); + Vertx vertx = createClusteredVertx(); + MessageChannelImpl c = new MessageChannelImpl(vertx); + c.addMessageHandler("foo", new MessageHandler() { + @Override + public CompletableFuture handle(E message) { + if (message instanceof ExtendedTestClusterMessage) { + checkpoint.flag(); + } + return CompletableFuture.completedFuture(null); + } + + @Override + public CompletableFuture request(E message) { + return null; + } + }); + + ClusterMessage cm = getClusterMessage("foo"); + Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.succeeding(v -> { + checkpoint.flag(); + })); + } + + public static class TestClusterMessage extends ClusterMessage { + String data1; + } + + public static class ExtendedTestClusterMessage extends TestClusterMessage { + String data2; + } + + ClusterMessage getClusterMessage(String data) { + ExtendedTestClusterMessage dm = new ExtendedTestClusterMessage(); + dm.data1 = data; + dm.data2 = data; + return dm; + } + + +} From b02141205757ff730e291f16cc36089436d6f60a Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Tue, 27 Feb 2024 23:21:30 +0530 Subject: [PATCH 2/8] moving cluster related details to server module --- .../java/com/flipkart/varadhi}/cluster/ClusterManager.java | 2 +- .../java/com/flipkart/varadhi}/cluster/ClusterMessage.java | 2 +- .../java/com/flipkart/varadhi}/cluster/MembershipListener.java | 2 +- .../java/com/flipkart/varadhi}/cluster/MessageChannel.java | 2 +- .../java/com/flipkart/varadhi/cluster/MessageChannelImpl.java | 1 - .../java/com/flipkart/varadhi}/cluster/MessageHandler.java | 2 +- .../src/main/java/com/flipkart/varadhi}/cluster/NodeInfo.java | 2 +- .../main/java/com/flipkart/varadhi}/cluster/NodeResources.java | 2 +- .../java/com/flipkart/varadhi}/cluster/ResponseMessage.java | 2 +- .../com/flipkart/varadhi/web/RequestTraceAndLogHandler.java | 2 +- .../com/flipkart/varadhi/cluster/MessageChannelImplTest.java | 3 --- 11 files changed, 9 insertions(+), 13 deletions(-) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/ClusterManager.java (93%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/ClusterMessage.java (82%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/MembershipListener.java (72%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/MessageChannel.java (95%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/MessageHandler.java (90%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/NodeInfo.java (89%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/NodeResources.java (62%) rename {core/src/main/java/com/flipkart/varadhi/core => server/src/main/java/com/flipkart/varadhi}/cluster/ResponseMessage.java (80%) diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java similarity index 93% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java rename to server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java index 5cf15713..72db40e5 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterManager.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; import java.util.List; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java similarity index 82% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java rename to server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java index adc3f828..ac3edb4b 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/ClusterMessage.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MembershipListener.java b/server/src/main/java/com/flipkart/varadhi/cluster/MembershipListener.java similarity index 72% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/MembershipListener.java rename to server/src/main/java/com/flipkart/varadhi/cluster/MembershipListener.java index e84928fa..b62edacb 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MembershipListener.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MembershipListener.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; public interface MembershipListener { void joined(NodeInfo nodeInfo); diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java similarity index 95% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java rename to server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java index caf535c1..ceb14e16 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; import java.util.concurrent.CompletableFuture; diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java index b637972f..18eb718c 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java @@ -1,6 +1,5 @@ package com.flipkart.varadhi.cluster; -import com.flipkart.varadhi.core.cluster.*; import com.flipkart.varadhi.exceptions.NotImplementedException; import com.flipkart.varadhi.utils.JsonMapper; import io.vertx.core.Vertx; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java similarity index 90% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java rename to server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java index 036e7441..b90a1079 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeInfo.java b/server/src/main/java/com/flipkart/varadhi/cluster/NodeInfo.java similarity index 89% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/NodeInfo.java rename to server/src/main/java/com/flipkart/varadhi/cluster/NodeInfo.java index fa4c3066..3f7d307f 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeInfo.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/NodeInfo.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; /** * TODO: need to see if the id needs to be separate from the 'ip' & 'hostname'. Implementer needs to address this. diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeResources.java b/server/src/main/java/com/flipkart/varadhi/cluster/NodeResources.java similarity index 62% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/NodeResources.java rename to server/src/main/java/com/flipkart/varadhi/cluster/NodeResources.java index a2a00f20..af222309 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/NodeResources.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/NodeResources.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; public record NodeResources(int cpuCount, int networkBandwidthMBps) { } diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java b/server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java similarity index 80% rename from core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java rename to server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java index 79dca57b..14ec4036 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/ResponseMessage.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.core.cluster; +package com.flipkart.varadhi.cluster; public class ResponseMessage extends ClusterMessage { // indicates a response to a request message. diff --git a/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java b/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java index b23b67fa..8b6d7c19 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java @@ -86,7 +86,7 @@ private String getIdentity(RoutingContext ctx) { private String getResourceHierarchy(RoutingContext ctx) { ResourceHierarchy resourceHierarchy = ctx.get(CONTEXT_KEY_RESOURCE_HIERARCHY); - return null != resourceHierarchy ? resourceHierarchy.getResourcePath() : "Unknown Resource Specification."; + return null != resourceHierarchy ? resourceHierarchy.getResourcePath() : String.format("(%s) - unresolved path.", ctx.request().path()); } private String getMessageInfo(RoutingContext ctx) { diff --git a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java index bf0fdef0..dd7a6de6 100644 --- a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java +++ b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java @@ -1,9 +1,6 @@ package com.flipkart.varadhi.cluster; import com.fasterxml.jackson.databind.jsontype.NamedType; -import com.flipkart.varadhi.core.cluster.ClusterMessage; -import com.flipkart.varadhi.core.cluster.MessageHandler; -import com.flipkart.varadhi.core.cluster.ResponseMessage; import com.flipkart.varadhi.utils.JsonMapper; import io.vertx.core.Future; import io.vertx.core.Vertx; From edcd60065975766cc8aa07b80ce372d6a2324d8a Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Wed, 28 Feb 2024 09:48:29 +0530 Subject: [PATCH 3/8] merge --- controller/build.gradle | 10 + .../controller/ControllerMessageHandler.java | 35 +++ .../varadhi/controller/ControllerMgr.java | 47 ++++ .../varadhi/controller/Orchestrator.java | 33 +++ server/build.gradle | 1 + .../com/flipkart/varadhi/CoreServices.java | 8 +- .../java/com/flipkart/varadhi/Server.java | 118 ---------- .../flipkart/varadhi/VaradhiApplication.java | 122 +++++++++++ .../flipkart/varadhi/VerticleDeployer.java | 36 ++-- .../varadhi/cluster/ClusterMessage.java | 9 +- .../varadhi/cluster/CreateSubscription.java | 13 ++ .../varadhi/cluster/DeleteSubscription.java | 13 ++ .../varadhi/cluster/MessageChannel.java | 1 + .../varadhi/cluster/MessageHandler.java | 1 + .../varadhi/cluster/StartSubscription.java | 12 ++ .../varadhi/cluster/StopSubscription.java | 13 ++ .../varadhi/cluster/SubscriptionMessage.java | 16 ++ .../varadhi/components/Component.java | 11 + .../varadhi/components/ComponentKind.java | 12 ++ .../varadhi/components/Controller.java | 28 +++ .../flipkart/varadhi/components/Server.java | 88 ++++++++ ...nfiguration.java => AppConfiguration.java} | 10 +- .../FullDeploymentVerticleDeployer.java | 4 +- .../LeanDeploymentVerticleDeployer.java | 21 +- .../flipkart/varadhi/web/AuthnHandler.java | 4 +- .../flipkart/varadhi/web/AuthzHandler.java | 8 +- server/src/main/resources/configuration.yml | 3 + .../LeanDeploymentVerticleDeployerTest.java | 201 ++++++++++-------- settings.gradle | 3 +- setup/docker/Dockerfile | 2 +- 30 files changed, 635 insertions(+), 248 deletions(-) create mode 100644 controller/build.gradle create mode 100644 controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java create mode 100644 controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java create mode 100644 controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/Server.java create mode 100644 server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java create mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/Component.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/Controller.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/Server.java rename server/src/main/java/com/flipkart/varadhi/config/{ServerConfiguration.java => AppConfiguration.java} (82%) diff --git a/controller/build.gradle b/controller/build.gradle new file mode 100644 index 00000000..17596a93 --- /dev/null +++ b/controller/build.gradle @@ -0,0 +1,10 @@ +plugins { + id 'com.flipkart.varadhi.java-library-conventions' +} + +dependencies { + api(project(":spi")) + api(project(":core")) + + implementation("io.vertx:vertx-micrometer-metrics") +} diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java new file mode 100644 index 00000000..72ae99fe --- /dev/null +++ b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java @@ -0,0 +1,35 @@ +package com.flipkart.varadhi.controller; + + +import com.flipkart.varadhi.exceptions.NotImplementedException; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.CompletableFuture; + +@Slf4j +public class ControllerMessageHandler { +//public class ControllerMessageHandler implements MessageHandler { +// +// private final Orchestrator orchestrator; +// +// public ControllerMessageHandler(Orchestrator orchestrator) { +// this.orchestrator = orchestrator; +// } +// +// @Override +// public CompletableFuture handle(E message) { +// log.info("Received message {} ", message); +// if (message instanceof SubscriptionMessage) { +// return orchestrator.handleSubscriptionMessage((SubscriptionMessage) message); +// }else{ +// log.error("Unknown message type {}", message); +// return CompletableFuture.failedFuture(new NotImplementedException("Unknown message type")); +// } +// } +// +// @Override +// public CompletableFuture request(E message) { +// log.error("Received message {} ", message); +// return CompletableFuture.failedFuture(new NotImplementedException("Request not implemented")); +// } +} diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java new file mode 100644 index 00000000..e907e916 --- /dev/null +++ b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java @@ -0,0 +1,47 @@ +package com.flipkart.varadhi.controller; + +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.MessageHandler; +import com.flipkart.varadhi.spi.db.MetaStoreProvider; +import com.flipkart.varadhi.spi.services.MessagingStackProvider; +import io.micrometer.core.instrument.MeterRegistry; +import io.vertx.core.Future; + +public class ControllerMgr { + public final String CONTROLLER_ADDRESS = "Controller" ; + + private final MetaStoreProvider metaStoreProvider; + private final MessagingStackProvider messagingStackProvider; + private final MeterRegistry meterRegistry; + private final MessageHandler controllerHandler; + private final Orchestrator orchestrator; + + private final MessageChannel channel; + public ControllerMgr(MessagingStackProvider messagingStackProvider, + MetaStoreProvider metaStoreProvider, + MessageChannel channel, + MeterRegistry meterRegistry + ) { + this.messagingStackProvider = messagingStackProvider; + this.metaStoreProvider = metaStoreProvider; + this.meterRegistry = meterRegistry; + this.channel = channel; + this.orchestrator = new Orchestrator(); + this.controllerHandler = new ControllerMessageHandler(this.orchestrator); + } + + public Future start() { + // leader election and on elected as leader + + // register message handler +// channel.addMessageHandler(CONTROLLER_ADDRESS, controllerHandler); + + // initiate recovery + return Future.succeededFuture(); + } + + public Future shutdown() { + channel.removeMessageHandler(CONTROLLER_ADDRESS); + return Future.succeededFuture(); + } +} diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java b/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java new file mode 100644 index 00000000..d80b15a3 --- /dev/null +++ b/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java @@ -0,0 +1,33 @@ +package com.flipkart.varadhi.controller; + +import com.flipkart.varadhi.core.cluster.messages.StartSubscription; +import com.flipkart.varadhi.core.cluster.messages.StopSubscription; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.CompletableFuture; + +@Slf4j +public class Orchestrator { + + public CompletableFuture handleSubscriptionMessage(SubscriptionMessage subscriptionMessage) { + if (subscriptionMessage instanceof StartSubscription) { + return startSubscription((StartSubscription) subscriptionMessage); + } else if (subscriptionMessage instanceof StopSubscription) { + return stopSubscription((StopSubscription) subscriptionMessage); + } + return CompletableFuture.failedFuture(new IllegalArgumentException("Unknown SubscriptionMessage type")); + } + + + private CompletableFuture startSubscription(StartSubscription startSubscription) { + log.info("Starting subscription for {}", startSubscription.getSubscriptionId()); + return CompletableFuture.completedFuture(null); + } + + private CompletableFuture stopSubscription(StopSubscription stopSubscription) { + log.info("Stopping subscription for {}", stopSubscription.getSubscriptionId()); + return CompletableFuture.completedFuture(null); + } +} + diff --git a/server/build.gradle b/server/build.gradle index fae6741f..5a9c5fa9 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -14,6 +14,7 @@ dependencies { implementation(project(":messaging")) implementation(project(":entities")) implementation(project(":authz")) + implementation(project(":controller")) implementation("org.apache.logging.log4j:log4j-slf4j2-impl") implementation("org.apache.logging.log4j:log4j-core") diff --git a/server/src/main/java/com/flipkart/varadhi/CoreServices.java b/server/src/main/java/com/flipkart/varadhi/CoreServices.java index f3549f46..c4682003 100644 --- a/server/src/main/java/com/flipkart/varadhi/CoreServices.java +++ b/server/src/main/java/com/flipkart/varadhi/CoreServices.java @@ -1,7 +1,7 @@ package com.flipkart.varadhi; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.spi.db.MetaStoreOptions; import com.flipkart.varadhi.spi.db.MetaStoreProvider; import com.flipkart.varadhi.spi.services.MessagingStackOptions; @@ -39,7 +39,7 @@ public class CoreServices { private final MessagingStackProvider messagingStackProvider; private final MetaStoreProvider metaStoreProvider; - public CoreServices(ServerConfiguration configuration) { + public CoreServices(AppConfiguration configuration) { this.observabilityStack = setupObservabilityStack(configuration); this.messagingStackProvider = setupMessagingStackProvider(configuration.getMessagingStackOptions()); this.metaStoreProvider = setupMetaStoreProvider(configuration.getMetaStoreOptions()); @@ -50,7 +50,7 @@ public Tracer getTracer(String instrumentationScope) { return this.observabilityStack.getOpenTelemetry().getTracer(instrumentationScope); } - public MeterRegistry getMetricsRegistry() { + public MeterRegistry getMeterRegistry() { return this.observabilityStack.getMeterRegistry(); } @@ -76,7 +76,7 @@ private MessagingStackProvider setupMessagingStackProvider(MessagingStackOptions return provider; } - private ObservabilityStack setupObservabilityStack(ServerConfiguration configuration) { + private ObservabilityStack setupObservabilityStack(AppConfiguration configuration) { Resource resource = Resource.getDefault() .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "com.flipkart.varadhi"))); diff --git a/server/src/main/java/com/flipkart/varadhi/Server.java b/server/src/main/java/com/flipkart/varadhi/Server.java deleted file mode 100644 index b3038221..00000000 --- a/server/src/main/java/com/flipkart/varadhi/Server.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.flipkart.varadhi; - -import com.flipkart.varadhi.config.ServerConfiguration; -import com.flipkart.varadhi.deployment.FullDeploymentVerticleDeployer; -import com.flipkart.varadhi.deployment.LeanDeploymentVerticleDeployer; -import com.flipkart.varadhi.exceptions.InvalidConfigException; -import com.flipkart.varadhi.utils.HostUtils; -import io.opentelemetry.api.trace.Tracer; -import io.vertx.config.ConfigRetriever; -import io.vertx.config.ConfigRetrieverOptions; -import io.vertx.config.ConfigStoreOptions; -import io.vertx.core.Vertx; -import io.vertx.core.VertxOptions; -import io.vertx.core.json.JsonObject; -import io.vertx.micrometer.MicrometerMetricsOptions; -import io.vertx.tracing.opentelemetry.OpenTelemetryOptions; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class Server { - - public static void main(String[] args) { - - try { - String hostName = HostUtils.getHostName(); - log.info("Server Starting on {}.", hostName); - ServerConfiguration configuration = readConfiguration(args); - CoreServices services = new CoreServices(configuration); - Vertx vertx = createVertex(configuration, services); - deployVerticle(hostName, configuration, services, vertx); - log.info("Server Started on {}.", hostName); - } catch (Exception e) { - log.error("Failed to initialise the server.", e); - System.exit(-1); - } - // TODO: check need for shutdown hook - } - - private static Vertx createVertex(ServerConfiguration configuration, CoreServices services) { - log.debug("Creating Vertex"); - VertxOptions vertxOptions = configuration.getVertxOptions() - .setTracingOptions(new OpenTelemetryOptions(services.getOpenTelemetry())) - .setMetricsOptions(new MicrometerMetricsOptions() - .setMicrometerRegistry(services.getMetricsRegistry()) - .setRegistryName("default") - .setJvmMetricsEnabled(true) - .setEnabled(true)); - Vertx vertx = Vertx.vertx(vertxOptions); - log.debug("Created Vertex"); - return vertx; - } - - private static void deployVerticle( - String hostName, ServerConfiguration configuration, CoreServices services, Vertx vertx - ) { - log.debug("Verticle deployment started."); - Tracer tracer = services.getTracer("varadhi"); - VerticleDeployer verticleDeployer; - if (configuration.getFeatureFlags().isLeanDeployment()) { - verticleDeployer = new LeanDeploymentVerticleDeployer( - hostName, - vertx, - configuration, - services.getMessagingStackProvider(), - services.getMetaStoreProvider(), - services.getMetricsRegistry(), - tracer - - ); - } else { - verticleDeployer = new FullDeploymentVerticleDeployer( - hostName, - vertx, - configuration, - services.getMessagingStackProvider(), - services.getMetaStoreProvider(), - services.getMetricsRegistry(), - tracer - ); - } - - verticleDeployer.deployVerticle(vertx, configuration); - log.debug("Verticle deployment completed."); - } - - - public static ServerConfiguration readConfiguration(String[] args) { - if (args.length < 1) { - log.error("Usage: java com.flipkart.varadhi.Server configuration.yml"); - System.exit(-1); - } - return readConfigFromFile(args[0]); - } - - public static ServerConfiguration readConfigFromFile(String filePath) throws InvalidConfigException { - log.info("Loading Configuration."); - Vertx vertx = Vertx.vertx(); - - ConfigStoreOptions fileStore = new ConfigStoreOptions() - .setType("file") - .setOptional(false) - .setFormat("yaml") - .setConfig(new JsonObject().put("path", filePath)); - - ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore); - ConfigRetriever retriever = ConfigRetriever.create(vertx, options); - - try { - JsonObject content = retriever.getConfig().toCompletionStage().toCompletableFuture().join(); - return content.mapTo(ServerConfiguration.class); - } catch (Exception e) { - throw new InvalidConfigException("Failed to load Application Configuration", e); - } finally { - retriever.close(); - vertx.close(); - } - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java new file mode 100644 index 00000000..8210d877 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java @@ -0,0 +1,122 @@ +package com.flipkart.varadhi; + +import com.flipkart.varadhi.components.Component; +import com.flipkart.varadhi.components.ComponentKind; +import com.flipkart.varadhi.components.Controller; +import com.flipkart.varadhi.components.Server; +import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.exceptions.InvalidConfigException; +import com.flipkart.varadhi.utils.HostUtils; +import io.vertx.config.ConfigRetriever; +import io.vertx.config.ConfigRetrieverOptions; +import io.vertx.config.ConfigStoreOptions; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.json.JsonObject; +import io.vertx.micrometer.MicrometerMetricsOptions; +import io.vertx.tracing.opentelemetry.OpenTelemetryOptions; +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +public class VaradhiApplication { + + public static void main(String[] args) { + + try { + String hostName = HostUtils.getHostName(); + log.info("VaradhiApplication Starting on {}.", hostName); + AppConfiguration configuration = readConfiguration(args); + CoreServices services = new CoreServices(configuration); + Vertx vertx = createVertex(configuration, services); + Map components = getComponents(configuration, services); + + Future.all(components.entrySet().stream().map(e -> e.getValue().start(vertx).onComplete(ar -> { + if (ar.succeeded()) { + log.info("Component({}) started.", e.getKey()); + } else { + log.error("Component({}) failed to start.", e.getKey(), ar.cause()); + } + })).collect(Collectors.toList())).onComplete(ar -> { + if (ar.succeeded()) { + log.info("VaradhiApplication Started on {}.", hostName); + } else { + log.error("VaradhiApplication failed to start.", ar.cause()); + } + }); + } catch (Exception e) { + log.error("Failed to initialise the VaradhiApplication.", e); + System.exit(-1); + } + + // TODO: check need for shutdown hook +// Runtime.getRuntime().addShutdownHook(); + } + + private static Vertx createVertex(AppConfiguration configuration, CoreServices services) { + log.debug("Creating Vertex"); + VertxOptions vertxOptions = configuration.getVertxOptions() + .setTracingOptions(new OpenTelemetryOptions(services.getOpenTelemetry())) + .setMetricsOptions(new MicrometerMetricsOptions() + .setMicrometerRegistry(services.getMeterRegistry()) + .setRegistryName("default") + .setJvmMetricsEnabled(true) + .setEnabled(true)); + Vertx vertx = Vertx.vertx(vertxOptions); + log.debug("Created Vertex"); + return vertx; + } + + public static AppConfiguration readConfiguration(String[] args) { + if (args.length < 1) { + log.error("Usage: java com.flipkart.varadhi.VaradhiApplication configuration.yml"); + System.exit(-1); + } + return readConfigFromFile(args[0]); + } + + public static AppConfiguration readConfigFromFile(String filePath) throws InvalidConfigException { + log.info("Loading Configuration."); + Vertx vertx = Vertx.vertx(); + + ConfigStoreOptions fileStore = new ConfigStoreOptions() + .setType("file") + .setOptional(false) + .setFormat("yaml") + .setConfig(new JsonObject().put("path", filePath)); + + ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore); + ConfigRetriever retriever = ConfigRetriever.create(vertx, options); + + try { + JsonObject content = retriever.getConfig().toCompletionStage().toCompletableFuture().join(); + return content.mapTo(AppConfiguration.class); + } catch (Exception e) { + throw new InvalidConfigException("Failed to load Application Configuration", e); + } finally { + retriever.close(); + vertx.close(); + } + } + + private static Map getComponents( + AppConfiguration configuration, CoreServices coreServices + ) { + //TODO:: check if there is need for ordered sequence of component. + return Arrays.stream(ComponentKind.values()) + .filter(kind -> !kind.equals(ComponentKind.All) && ( + configuration.getComponents().contains(ComponentKind.All) || + configuration.getComponents().contains(kind) + )) + .collect(Collectors.toMap(Function.identity(), kind -> switch (kind) { + case Server -> new Server("hostName", configuration, coreServices); + case Controller -> new Controller(configuration, coreServices); + default -> throw new IllegalArgumentException("Unknown Component Kind: " + kind); + })); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java index 2fcf0525..4cbe60e0 100644 --- a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java @@ -2,7 +2,7 @@ import com.flipkart.varadhi.auth.DefaultAuthorizationProvider; import com.flipkart.varadhi.config.RestOptions; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.core.VaradhiTopicFactory; import com.flipkart.varadhi.core.VaradhiTopicService; import com.flipkart.varadhi.exceptions.VaradhiException; @@ -25,6 +25,7 @@ import com.flipkart.varadhi.web.v1.produce.ProduceHandlers; import io.micrometer.core.instrument.MeterRegistry; import io.opentelemetry.api.trace.Tracer; +import io.vertx.core.Future; import io.vertx.core.Vertx; import lombok.extern.slf4j.Slf4j; @@ -52,7 +53,7 @@ public abstract class VerticleDeployer { public VerticleDeployer( String hostName, Vertx vertx, - ServerConfiguration configuration, + AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, MeterRegistry meterRegistry, @@ -131,31 +132,28 @@ public List getRouteDefinitions() { .collect(Collectors.toList()); } - public void deployVerticle(Vertx vertx, ServerConfiguration configuration) { + public Future deployVerticle(Vertx vertx, AppConfiguration configuration) { List handlerDefinitions = getRouteDefinitions(); if (shouldEnableAuthZHandlers(configuration)) { handlerDefinitions.addAll(authZHandlersSupplier.get().get()); } - vertx.deployVerticle( - () -> new RestVerticle( - handlerDefinitions, - behaviorConfigurators, - new FailureHandler(), - configuration.getHttpServerOptions() - ), - configuration.getVerticleDeploymentOptions() - ) - .onFailure(t -> { - log.error("Could not start HttpServer Verticle.", t); - throw new VaradhiException("Failed to Deploy Rest API.", t); - }) - .onSuccess(name -> log.debug("Successfully deployed the Verticle id({}).", name)); + return vertx.deployVerticle( + () -> new RestVerticle( + handlerDefinitions, + behaviorConfigurators, + new FailureHandler(), + configuration.getHttpServerOptions() + ), + configuration.getVerticleDeploymentOptions() + ).onFailure(t -> { + log.error("Could not start HttpServer Verticle.", t); + throw new VaradhiException("Failed to Deploy Rest API.", t); + }).onSuccess(name -> log.debug("Successfully deployed the Verticle id({}).", name)); } - private boolean shouldEnableAuthZHandlers(ServerConfiguration configuration) { + private boolean shouldEnableAuthZHandlers(AppConfiguration configuration) { String defaultProviderClass = DefaultAuthorizationProvider.class.getName(); return configuration.isAuthorizationEnabled() && defaultProviderClass.equals(configuration.getAuthorization().getProviderClassName()); } - } diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java index ac3edb4b..bc360c63 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java @@ -3,9 +3,16 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; +import lombok.Getter; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@messageType") -@Data +@Getter public class ClusterMessage { String id; + long timeStamp; + + public ClusterMessage() { + this.id = java.util.UUID.randomUUID().toString(); + this.timeStamp = System.currentTimeMillis(); + } } diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java new file mode 100644 index 00000000..27b9468c --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java @@ -0,0 +1,13 @@ +package com.flipkart.varadhi.cluster; + + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class CreateSubscription extends SubscriptionMessage { + public CreateSubscription(String subscriptionId) { + super(subscriptionId); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java new file mode 100644 index 00000000..ac7cb353 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java @@ -0,0 +1,13 @@ +package com.flipkart.varadhi.cluster; + + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DeleteSubscription extends SubscriptionMessage { + public DeleteSubscription(String subscriptionId) { + super(subscriptionId); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java index ceb14e16..a0980086 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java @@ -1,5 +1,6 @@ package com.flipkart.varadhi.cluster; + import java.util.concurrent.CompletableFuture; /** diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java index b90a1079..d9d5237a 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java @@ -1,5 +1,6 @@ package com.flipkart.varadhi.cluster; + import java.util.concurrent.CompletableFuture; public interface MessageHandler { diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java new file mode 100644 index 00000000..d140dae7 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java @@ -0,0 +1,12 @@ +package com.flipkart.varadhi.cluster; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class StartSubscription extends SubscriptionMessage { + public StartSubscription(String subscriptionId) { + super(subscriptionId); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java new file mode 100644 index 00000000..b31603b5 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java @@ -0,0 +1,13 @@ +package com.flipkart.varadhi.cluster; + + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class StopSubscription extends SubscriptionMessage { + public StopSubscription(String subscriptionId) { + super(subscriptionId); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java b/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java new file mode 100644 index 00000000..eab17345 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java @@ -0,0 +1,16 @@ +package com.flipkart.varadhi.cluster; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class SubscriptionMessage extends ClusterMessage { + private final String subscriptionId; + + public SubscriptionMessage(String subscriptionId) { + super(); + this.subscriptionId = subscriptionId; + } + +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/Component.java b/server/src/main/java/com/flipkart/varadhi/components/Component.java new file mode 100644 index 00000000..b72e47d7 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/Component.java @@ -0,0 +1,11 @@ +package com.flipkart.varadhi.components; + +import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.config.AppConfiguration; +import io.vertx.core.Future; +import io.vertx.core.Vertx; + +public interface Component { + Future start(Vertx vertx); + Future shutdown(Vertx vertx); +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java b/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java new file mode 100644 index 00000000..380c1ee6 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java @@ -0,0 +1,12 @@ +package com.flipkart.varadhi.components; + +public enum ComponentKind { + Server("Server"), + Controller("Controller"), + All("All"); + + private final String name; + ComponentKind(String name) { + this.name = name; + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/Controller.java b/server/src/main/java/com/flipkart/varadhi/components/Controller.java new file mode 100644 index 00000000..29fad5b0 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/Controller.java @@ -0,0 +1,28 @@ +package com.flipkart.varadhi.components; + +import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.controller.ControllerMgr; +import io.vertx.core.Future; +import io.vertx.core.Vertx; + +public class Controller implements Component { + + private final ControllerMgr controllerMgr; + + public Controller(AppConfiguration configuration, CoreServices coreServices) { + this.controllerMgr = new ControllerMgr(coreServices.getMessagingStackProvider(), + coreServices.getMetaStoreProvider(), + null, + coreServices.getMeterRegistry()); + } + @Override + public Future start(Vertx vertx) { + return controllerMgr.start(); + } + + @Override + public Future shutdown(Vertx vertx) { + return controllerMgr.shutdown(); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/Server.java b/server/src/main/java/com/flipkart/varadhi/components/Server.java new file mode 100644 index 00000000..2281e862 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/Server.java @@ -0,0 +1,88 @@ +package com.flipkart.varadhi.components; + +import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.VerticleDeployer; +import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.deployment.FullDeploymentVerticleDeployer; +import com.flipkart.varadhi.deployment.LeanDeploymentVerticleDeployer; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class Server implements Component { + private String verticleId; + private final AppConfiguration configuration; + private final CoreServices coreServices; + private final String hostName; + + public Server(String hostname, AppConfiguration configuration, CoreServices coreServices) { + this.hostName = hostname; + this.configuration = configuration; + this.coreServices = coreServices; + } + + @Override + public Future start(Vertx vertx) { + return deployVerticle(vertx); + } + + @Override + public Future shutdown(Vertx vertx) { + //TODO:: + // - fail health check. + // - reject any new request for retry (may be via a custom handler ?). + + // Not taking care of concurrent execution, in general not expected for startup/shutdown. + if (null != verticleId) { + log.info("Undeploy verticle {}.", verticleId); + return vertx.undeploy(verticleId).onComplete(ar -> { + if (ar.succeeded()) { + verticleId = null; + log.info("Undeploy completed"); + } else { + log.error("Undeploy failed.", ar.cause()); + } + }); + }else{ + return Future.succeededFuture(); + } + } + private Future deployVerticle( Vertx vertx) { + log.info("Verticle deployment started."); + VerticleDeployer verticleDeployer = createVerticleDeployer(vertx); + return verticleDeployer.deployVerticle(vertx, configuration).compose(r -> { + log.info("Verticle() deployment completed {}.", r); + verticleId = r; + return Future.succeededFuture(); + }, t -> { + log.error("Verticle() deployment failed.", t); + return Future.failedFuture(t); + }); + } + + private VerticleDeployer createVerticleDeployer(Vertx vertx) { + VerticleDeployer verticleDeployer; + if (configuration.getFeatureFlags().isLeanDeployment()) { + verticleDeployer = new LeanDeploymentVerticleDeployer(hostName, + vertx, + configuration, + coreServices.getMessagingStackProvider(), + coreServices.getMetaStoreProvider(), + coreServices.getMeterRegistry(), + coreServices.getTracer() + ); + } else { + verticleDeployer = new FullDeploymentVerticleDeployer(hostName, + vertx, + configuration, + coreServices.getMessagingStackProvider(), + coreServices.getMetaStoreProvider(), + coreServices.getMeterRegistry(), + coreServices.getTracer() + ); + } + return verticleDeployer; + } + +} diff --git a/server/src/main/java/com/flipkart/varadhi/config/ServerConfiguration.java b/server/src/main/java/com/flipkart/varadhi/config/AppConfiguration.java similarity index 82% rename from server/src/main/java/com/flipkart/varadhi/config/ServerConfiguration.java rename to server/src/main/java/com/flipkart/varadhi/config/AppConfiguration.java index 1caa4169..6cd26384 100644 --- a/server/src/main/java/com/flipkart/varadhi/config/ServerConfiguration.java +++ b/server/src/main/java/com/flipkart/varadhi/config/AppConfiguration.java @@ -2,17 +2,25 @@ import com.flipkart.varadhi.auth.AuthenticationOptions; import com.flipkart.varadhi.authz.AuthorizationOptions; +import com.flipkart.varadhi.components.ComponentKind; import com.flipkart.varadhi.produce.config.ProducerOptions; import com.flipkart.varadhi.spi.db.MetaStoreOptions; import com.flipkart.varadhi.spi.services.MessagingStackOptions; import io.vertx.core.DeploymentOptions; import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpServerOptions; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Null; import lombok.Getter; +import java.util.List; + @Getter -public class ServerConfiguration { +public class AppConfiguration { + @NotEmpty + List components; + @NotNull private VertxOptions vertxOptions; @NotNull diff --git a/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java index b6e1d056..5321bb81 100644 --- a/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java @@ -1,7 +1,7 @@ package com.flipkart.varadhi.deployment; import com.flipkart.varadhi.VerticleDeployer; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.spi.db.MetaStoreProvider; import com.flipkart.varadhi.spi.services.MessagingStackProvider; import com.flipkart.varadhi.web.routes.RouteDefinition; @@ -23,7 +23,7 @@ public class FullDeploymentVerticleDeployer extends VerticleDeployer { private final TeamHandlers teamHandlers; private final ProjectHandlers projectHandlers; public FullDeploymentVerticleDeployer( - String hostName, Vertx vertx, ServerConfiguration configuration, + String hostName, Vertx vertx, AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, MeterRegistry meterRegistry, Tracer tracer diff --git a/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java index c3b74ddd..0c9a1992 100644 --- a/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java @@ -3,7 +3,7 @@ import com.flipkart.varadhi.VerticleDeployer; import com.flipkart.varadhi.config.RestOptions; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.entities.Org; import com.flipkart.varadhi.entities.Project; import com.flipkart.varadhi.entities.Team; @@ -11,7 +11,12 @@ import com.flipkart.varadhi.spi.db.MetaStoreProvider; import com.flipkart.varadhi.spi.services.MessagingStackProvider; import io.micrometer.core.instrument.MeterRegistry; +<<<<<<< Updated upstream import io.opentelemetry.api.trace.Tracer; +======= +import io.vertx.core.Future; +import io.vertx.core.Promise; +>>>>>>> Stashed changes import io.vertx.core.Vertx; import lombok.extern.slf4j.Slf4j; @@ -20,7 +25,7 @@ @Slf4j public class LeanDeploymentVerticleDeployer extends VerticleDeployer { public LeanDeploymentVerticleDeployer( - String hostName, Vertx vertx, ServerConfiguration configuration, + String hostName, Vertx vertx, AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, MeterRegistry meterRegistry, Tracer tracer @@ -29,12 +34,16 @@ public LeanDeploymentVerticleDeployer( } @Override - public void deployVerticle( + public Future deployVerticle( Vertx vertx, - ServerConfiguration configuration + AppConfiguration configuration ) { - ensureLeanDeploymentConstraints(configuration.getRestOptions()); - super.deployVerticle(vertx, configuration); + Promise promise = Promise.promise(); + vertx.executeBlocking(future -> { + ensureLeanDeploymentConstraints(configuration.getRestOptions()); + future.complete(); + }, promise); + return promise.future().compose(v -> super.deployVerticle(vertx, configuration)); } private void ensureLeanDeploymentConstraints(RestOptions restOptions) { diff --git a/server/src/main/java/com/flipkart/varadhi/web/AuthnHandler.java b/server/src/main/java/com/flipkart/varadhi/web/AuthnHandler.java index dbef386a..d0cd26cd 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/AuthnHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/web/AuthnHandler.java @@ -1,7 +1,7 @@ package com.flipkart.varadhi.web; import com.flipkart.varadhi.auth.AuthenticationOptions; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.exceptions.InvalidConfigException; import com.flipkart.varadhi.exceptions.VaradhiException; import com.flipkart.varadhi.web.routes.RouteConfigurator; @@ -27,7 +27,7 @@ public class AuthnHandler implements RouteConfigurator { private final Handler authenticationHandler; - public AuthnHandler(Vertx vertx, ServerConfiguration configuration) throws InvalidConfigException { + public AuthnHandler(Vertx vertx, AppConfiguration configuration) throws InvalidConfigException { if (configuration.isAuthenticationEnabled()) { authenticationHandler = switch (configuration.getAuthentication().getMechanism()) { diff --git a/server/src/main/java/com/flipkart/varadhi/web/AuthzHandler.java b/server/src/main/java/com/flipkart/varadhi/web/AuthzHandler.java index e7eaee57..60dde49f 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/AuthzHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/web/AuthzHandler.java @@ -2,7 +2,7 @@ import com.flipkart.varadhi.authz.AuthorizationProvider; import com.flipkart.varadhi.authz.AuthorizationOptions; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.exceptions.InvalidConfigException; import com.flipkart.varadhi.web.routes.RouteConfigurator; import com.flipkart.varadhi.web.routes.RouteDefinition; @@ -12,7 +12,7 @@ public class AuthzHandler implements RouteConfigurator { private final AuthorizationHandlerBuilder authorizationHandlerBuilder; - public AuthzHandler(ServerConfiguration configuration) throws InvalidConfigException { + public AuthzHandler(AppConfiguration configuration) throws InvalidConfigException { if (configuration.isAuthenticationEnabled() && configuration.isAuthorizationEnabled()) { authorizationHandlerBuilder = createAuthorizationHandler(configuration); } else { @@ -26,7 +26,7 @@ public void configure(Route route, RouteDefinition routeDef) { } } - AuthorizationHandlerBuilder createAuthorizationHandler(ServerConfiguration configuration) { + AuthorizationHandlerBuilder createAuthorizationHandler(AppConfiguration configuration) { if (configuration.isAuthorizationEnabled()) { AuthorizationProvider authorizationProvider = getAuthorizationProvider(configuration); return new AuthorizationHandlerBuilder(configuration.getAuthorization() @@ -37,7 +37,7 @@ AuthorizationHandlerBuilder createAuthorizationHandler(ServerConfiguration confi } @SuppressWarnings("unchecked") - private AuthorizationProvider getAuthorizationProvider(ServerConfiguration configuration) { + private AuthorizationProvider getAuthorizationProvider(AppConfiguration configuration) { String providerClassName = configuration.getAuthorization().getProviderClassName(); if (StringUtils.isNotBlank(providerClassName)) { try { diff --git a/server/src/main/resources/configuration.yml b/server/src/main/resources/configuration.yml index eee2501a..3400b91d 100755 --- a/server/src/main/resources/configuration.yml +++ b/server/src/main/resources/configuration.yml @@ -1,3 +1,6 @@ + +components : ["Server", "Controller", "All"] + restOptions: deployedRegion: "default" defaultOrg: "default" diff --git a/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java b/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java index 8339d139..fe7c7ace 100644 --- a/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java +++ b/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java @@ -1,6 +1,6 @@ package com.flipkart.varadhi.deployment; -import com.flipkart.varadhi.config.ServerConfiguration; +import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.db.VaradhiMetaStore; import com.flipkart.varadhi.entities.Org; import com.flipkart.varadhi.entities.Project; @@ -17,12 +17,17 @@ import com.flipkart.varadhi.web.routes.RouteDefinition; import io.micrometer.core.instrument.MeterRegistry; import io.vertx.core.Vertx; +import io.vertx.junit5.Checkpoint; +import io.vertx.junit5.VertxExtension; +import io.vertx.junit5.VertxTestContext; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.test.TestingServer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -30,6 +35,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +@ExtendWith(VertxExtension.class) public class LeanDeploymentVerticleDeployerTest { TestingServer zkCuratorTestingServer; @@ -43,7 +49,7 @@ public class LeanDeploymentVerticleDeployerTest { MetaStoreProvider metaStoreProvider; - ServerConfiguration serverConfiguration; + AppConfiguration appConfiguration; MeterRegistry meterRegistry; @@ -79,21 +85,21 @@ public void setup() throws Exception { when(metaStoreProvider.getMetaStore()).thenReturn(varadhiMetaStore); when(messagingStackProvider.getProducerFactory()).thenReturn(mock(ProducerFactory.class)); - serverConfiguration = YamlLoader.loadConfig( + appConfiguration = YamlLoader.loadConfig( "src/test/resources/testConfiguration.yml", - ServerConfiguration.class); + AppConfiguration.class); orgService = new OrgService(varadhiMetaStore); teamService = new TeamService(varadhiMetaStore); projectService = new ProjectService( varadhiMetaStore, - serverConfiguration.getRestOptions().getProjectCacheBuilderSpec(), + appConfiguration.getRestOptions().getProjectCacheBuilderSpec(), meterRegistry); leanDeploymentVerticleDeployer = new LeanDeploymentVerticleDeployer( "testHostName", vertx, - serverConfiguration, + appConfiguration, messagingStackProvider, metaStoreProvider, meterRegistry, @@ -102,32 +108,39 @@ public void setup() throws Exception { } @Test - public void testNoEntitiesPresent_Success() { - leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration); - - Org org = orgService.getOrg( - serverConfiguration.getRestOptions().getDefaultOrg()); - assertNotNull(org); - assertEquals(serverConfiguration.getRestOptions().getDefaultOrg(), org.getName()); - - Team team = teamService.getTeam( - org.getName(), serverConfiguration.getRestOptions().getDefaultTeam()); - assertNotNull(team); - assertEquals(serverConfiguration.getRestOptions().getDefaultTeam(), team.getName()); - - Project project = projectService.getProject( - serverConfiguration.getRestOptions().getDefaultProject()); - assertNotNull(project); - assertEquals(serverConfiguration.getRestOptions().getDefaultProject(), project.getName()); + public void testNoEntitiesPresent_Success(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + leanDeploymentVerticleDeployer + .deployVerticle(vertx, appConfiguration) + .onComplete(testContext.succeeding( id -> { + Org org = orgService.getOrg( + appConfiguration.getRestOptions().getDefaultOrg()); + assertNotNull(org); + assertEquals(appConfiguration.getRestOptions().getDefaultOrg(), org.getName()); + + Team team = teamService.getTeam( + org.getName(), appConfiguration.getRestOptions().getDefaultTeam()); + assertNotNull(team); + assertEquals(appConfiguration.getRestOptions().getDefaultTeam(), team.getName()); + + Project project = projectService.getProject( + appConfiguration.getRestOptions().getDefaultProject()); + assertNotNull(project); + assertEquals(appConfiguration.getRestOptions().getDefaultProject(), project.getName()); + cp.flag(); + } + )); } @Test - public void testEntitiesPresentWithDefaultName_Success() { - Org org = new Org(serverConfiguration.getRestOptions().getDefaultOrg(), 0); + public void testEntitiesPresentWithDefaultName_Success(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + Org org = new Org(appConfiguration.getRestOptions().getDefaultOrg(), 0); orgService.createOrg(org); - Team team = new Team(serverConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); + Team team = new Team(appConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); teamService.createTeam(team); - Project project = new Project(serverConfiguration.getRestOptions().getDefaultProject(), + Project project = new Project( + appConfiguration.getRestOptions().getDefaultProject(), 0, "", team.getName(), @@ -135,114 +148,124 @@ public void testEntitiesPresentWithDefaultName_Success() { ); projectService.createProject(project); - leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration); - - org = orgService.getOrg(serverConfiguration.getRestOptions().getDefaultOrg()); - assertNotNull(org); - assertEquals(serverConfiguration.getRestOptions().getDefaultOrg(), org.getName()); - - team = teamService.getTeam( - org.getName(), serverConfiguration.getRestOptions().getDefaultTeam()); - assertNotNull(team); - assertEquals(serverConfiguration.getRestOptions().getDefaultTeam(), team.getName()); - - project = projectService.getProject( - serverConfiguration.getRestOptions().getDefaultProject()); - assertNotNull(project); - assertEquals(serverConfiguration.getRestOptions().getDefaultProject(), project.getName()); + leanDeploymentVerticleDeployer + .deployVerticle(vertx, appConfiguration) + .onComplete(testContext.succeeding( id -> { + Org orgObtained = orgService.getOrg(appConfiguration.getRestOptions().getDefaultOrg()); + assertNotNull(orgObtained); + assertEquals(appConfiguration.getRestOptions().getDefaultOrg(), orgObtained.getName()); + + Team teamObtained = teamService.getTeam( + org.getName(), appConfiguration.getRestOptions().getDefaultTeam()); + assertNotNull(teamObtained); + assertEquals(appConfiguration.getRestOptions().getDefaultTeam(), teamObtained.getName()); + + Project pObtained = projectService.getProject( + appConfiguration.getRestOptions().getDefaultProject()); + assertNotNull(pObtained); + assertEquals(appConfiguration.getRestOptions().getDefaultProject(), pObtained.getName()); + cp.flag(); + })); } @Test - public void testDifferentOrgPresent_Failure() { + public void testDifferentOrgPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); Org org = new Org(TEST_ORG, 0); orgService.createOrg(org); - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals(String.format( - "Lean deployment can not be enabled as org with %s name is present.", - TEST_ORG), exception.getMessage()); + leanDeploymentVerticleDeployer + .deployVerticle(vertx, appConfiguration) + .onComplete(testContext.failing(t -> { + assertEquals(String.format( + "Lean deployment can not be enabled as org with %s name is present.", + TEST_ORG), t.getMessage()); + cp.flag(); + })); } @Test - public void testMultipleOrgsPresent_Failure() { + public void testMultipleOrgsPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); Org org1 = new Org(TEST_ORG, 0); Org org2 = new Org(TEST_ORG + "2", 0); orgService.createOrg(org1); orgService.createOrg(org2); - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals("Lean deployment can not be enabled as there are more than one orgs.", - exception.getMessage()); + leanDeploymentVerticleDeployer.deployVerticle(vertx, appConfiguration).onComplete(testContext.failing( t -> + { + assertEquals("Lean deployment can not be enabled as there are more than one orgs.", + t.getMessage()); + cp.flag(); + })); } @Test - public void testDifferentTeamPresent_Failure() { - Org org = new Org(serverConfiguration.getRestOptions().getDefaultOrg(), 0); + public void testDifferentTeamPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + Org org = new Org(appConfiguration.getRestOptions().getDefaultOrg(), 0); orgService.createOrg(org); Team team = new Team(TEST_TEAM, 0, org.getName()); teamService.createTeam(team); - - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals(String.format( - "Lean deployment can not be enabled as team with %s name is present.", - TEST_TEAM), exception.getMessage()); + leanDeploymentVerticleDeployer.deployVerticle(vertx, appConfiguration).onComplete(testContext.failing(t -> { + assertEquals(String.format( + "Lean deployment can not be enabled as team with %s name is present.", + TEST_TEAM), t.getMessage()); + cp.flag(); + })); } @Test - public void testMultipleTeamsPresent_Failure() { - Org org = new Org(serverConfiguration.getRestOptions().getDefaultOrg(), 0); + public void testMultipleTeamsPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + Org org = new Org(appConfiguration.getRestOptions().getDefaultOrg(), 0); orgService.createOrg(org); Team team1 = new Team(TEST_TEAM, 0, org.getName()); Team team2 = new Team(TEST_TEAM + "2", 0, org.getName()); teamService.createTeam(team1); teamService.createTeam(team2); - - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals("Lean deployment can not be enabled as there are more than one teams.", - exception.getMessage()); + leanDeploymentVerticleDeployer.deployVerticle(vertx, appConfiguration).onComplete(testContext.failing( t -> { + assertEquals("Lean deployment can not be enabled as there are more than one teams.", + t.getMessage()); + cp.flag(); + } )); } @Test - public void testDifferentProjectPresent_Failure() { - Org org = new Org(serverConfiguration.getRestOptions().getDefaultOrg(), 0); + public void testDifferentProjectPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + Org org = new Org(appConfiguration.getRestOptions().getDefaultOrg(), 0); orgService.createOrg(org); - Team team = new Team(serverConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); + Team team = new Team(appConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); teamService.createTeam(team); Project project = new Project(TEST_PROJECT, 0, "", team.getName(), org.getName()); projectService.createProject(project); - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals(String.format( - "Lean deployment can not be enabled as project with %s name is present.", - TEST_PROJECT), exception.getMessage()); + leanDeploymentVerticleDeployer.deployVerticle(vertx, appConfiguration).onComplete(testContext.failing( t -> { + assertEquals(String.format( + "Lean deployment can not be enabled as project with %s name is present.", + TEST_PROJECT), t.getMessage()); + cp.flag(); + })); } @Test - public void testMultipleProjectsPresent_Failure() { - Org org = new Org(serverConfiguration.getRestOptions().getDefaultOrg(), 0); + public void testMultipleProjectsPresent_Failure(VertxTestContext testContext) { + Checkpoint cp = testContext.checkpoint(1); + Org org = new Org(appConfiguration.getRestOptions().getDefaultOrg(), 0); orgService.createOrg(org); - Team team = new Team(serverConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); + Team team = new Team(appConfiguration.getRestOptions().getDefaultTeam(), 0, org.getName()); teamService.createTeam(team); Project project1 = new Project(TEST_PROJECT, 0, "", team.getName(), org.getName()); Project project2 = new Project(TEST_PROJECT + "2", 0, "", team.getName(), org.getName()); projectService.createProject(project1); projectService.createProject(project2); - InvalidConfigException exception = assertThrows(InvalidConfigException.class, - () -> leanDeploymentVerticleDeployer.deployVerticle(vertx, serverConfiguration)); - - assertEquals("Lean deployment can not be enabled as there are more than one projects.", - exception.getMessage()); + leanDeploymentVerticleDeployer.deployVerticle(vertx, appConfiguration).onComplete(testContext.failing( t -> { + assertEquals("Lean deployment can not be enabled as there are more than one projects.", + t.getMessage()); + cp.flag(); + })); } @Test diff --git a/settings.gradle b/settings.gradle index aa5e6570..c7da489c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,4 +8,5 @@ */ rootProject.name = 'varadhi' -include('entities', 'spi', 'common', 'core', 'messaging', 'pulsar', 'server', 'authz', 'consumer') +include('entities', 'spi', 'common', 'core', 'messaging', 'pulsar', 'server', 'authz', 'consumer', 'controller') + diff --git a/setup/docker/Dockerfile b/setup/docker/Dockerfile index 37f3dcae..f6a47306 100644 --- a/setup/docker/Dockerfile +++ b/setup/docker/Dockerfile @@ -32,4 +32,4 @@ USER varadhi WORKDIR /usr/share/varadhi # Start Varadhi server -CMD java -cp ./*:dependencies/* com.flipkart.varadhi.Server /etc/varadhi/configuration.yml +CMD java -cp ./*:dependencies/* com.flipkart.varadhi.VaradhiApplication /etc/varadhi/configuration.yml From f5d484c152e79de8b6a69bd3b4b465e346fcfcf8 Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Thu, 7 Mar 2024 12:15:10 +0530 Subject: [PATCH 4/8] - refactoring needed for controller bootstrapping - message channel PR comments --- controller/build.gradle | 1 + .../controller/ControllerMessageHandler.java | 35 -------- .../varadhi/controller/ControllerMgr.java | 54 ++++-------- .../varadhi/controller/Orchestrator.java | 33 -------- .../varadhi/core}/cluster/MessageChannel.java | 23 ++++- .../varadhi/core}/cluster/MessageHandler.java | 5 +- .../cluster/messages}/ClusterMessage.java | 2 +- .../core/cluster/messages/PublishHandler.java | 5 ++ .../core/cluster/messages/RequestHandler.java | 7 ++ .../cluster/messages}/ResponseMessage.java | 2 +- .../core/cluster/messages/SendHandler.java | 8 ++ .../cluster/messages/SubscriptionMessage.java | 17 ++++ .../messages/SubscriptionOperation.java | 45 ++++++++++ .../core/ophandlers/ControllerOpHandler.java | 9 ++ .../core/ophandlers/ServerOpHandler.java | 10 +++ .../core/proxies/ControllerMgrProxy.java | 27 ++++++ .../core/proxies/ServerOpMgrProxy.java | 27 ++++++ .../com/flipkart/varadhi/RestVerticle.java | 4 +- .../com/flipkart/varadhi/ServerOpManager.java | 15 ++++ .../flipkart/varadhi/VaradhiApplication.java | 17 +++- .../flipkart/varadhi/VerticleDeployer.java | 9 +- .../varadhi/cluster/ClusterManager.java | 2 + .../varadhi/cluster/CreateSubscription.java | 13 --- .../varadhi/cluster/DeleteSubscription.java | 13 --- .../varadhi/cluster/MessageChannelImpl.java | 78 ++++++----------- .../varadhi/cluster/StartSubscription.java | 12 --- .../varadhi/cluster/StopSubscription.java | 13 --- .../varadhi/cluster/SubscriptionMessage.java | 16 ---- .../cluster/impl/ClusterManagerImpl.java | 14 +++- .../varadhi/components/Component.java | 5 +- .../varadhi/components/Controller.java | 28 ------- .../components/controller/Controller.java | 36 ++++++++ .../controller/SubscriptionOpHandler.java | 34 ++++++++ .../components/{ => server}/Server.java | 48 +++++++---- .../server/ServerOperationHandler.java | 21 +++++ .../FullDeploymentVerticleDeployer.java | 8 +- .../LeanDeploymentVerticleDeployer.java | 8 +- .../varadhi/services/SubscriptionService.java | 14 +++- .../web/RequestTraceAndLogHandler.java | 1 + .../web/v1/admin/SubscriptionHandlers.java | 3 +- .../cluster/MessageChannelImplTest.java | 84 +++++++++---------- .../LeanDeploymentVerticleDeployerTest.java | 18 +++- .../services/SubscriptionServiceTest.java | 3 +- .../src/test/resources/testConfiguration.yml | 2 + 44 files changed, 485 insertions(+), 344 deletions(-) delete mode 100644 controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java delete mode 100644 controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java rename {server/src/main/java/com/flipkart/varadhi => core/src/main/java/com/flipkart/varadhi/core}/cluster/MessageChannel.java (55%) rename {server/src/main/java/com/flipkart/varadhi => core/src/main/java/com/flipkart/varadhi/core}/cluster/MessageHandler.java (69%) rename {server/src/main/java/com/flipkart/varadhi/cluster => core/src/main/java/com/flipkart/varadhi/core/cluster/messages}/ClusterMessage.java (88%) create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java rename {server/src/main/java/com/flipkart/varadhi/cluster => core/src/main/java/com/flipkart/varadhi/core/cluster/messages}/ResponseMessage.java (77%) create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SendHandler.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java create mode 100644 server/src/main/java/com/flipkart/varadhi/ServerOpManager.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/components/Controller.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java rename server/src/main/java/com/flipkart/varadhi/components/{ => server}/Server.java (63%) create mode 100644 server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java diff --git a/controller/build.gradle b/controller/build.gradle index 17596a93..ebc0a99a 100644 --- a/controller/build.gradle +++ b/controller/build.gradle @@ -3,6 +3,7 @@ plugins { } dependencies { + api(project(":entities")) api(project(":spi")) api(project(":core")) diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java deleted file mode 100644 index 72ae99fe..00000000 --- a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMessageHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.flipkart.varadhi.controller; - - -import com.flipkart.varadhi.exceptions.NotImplementedException; -import lombok.extern.slf4j.Slf4j; - -import java.util.concurrent.CompletableFuture; - -@Slf4j -public class ControllerMessageHandler { -//public class ControllerMessageHandler implements MessageHandler { -// -// private final Orchestrator orchestrator; -// -// public ControllerMessageHandler(Orchestrator orchestrator) { -// this.orchestrator = orchestrator; -// } -// -// @Override -// public CompletableFuture handle(E message) { -// log.info("Received message {} ", message); -// if (message instanceof SubscriptionMessage) { -// return orchestrator.handleSubscriptionMessage((SubscriptionMessage) message); -// }else{ -// log.error("Unknown message type {}", message); -// return CompletableFuture.failedFuture(new NotImplementedException("Unknown message type")); -// } -// } -// -// @Override -// public CompletableFuture request(E message) { -// log.error("Received message {} ", message); -// return CompletableFuture.failedFuture(new NotImplementedException("Request not implemented")); -// } -} diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java index e907e916..eec8f709 100644 --- a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java +++ b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java @@ -1,47 +1,25 @@ package com.flipkart.varadhi.controller; -import com.flipkart.varadhi.core.cluster.MessageChannel; -import com.flipkart.varadhi.core.cluster.MessageHandler; -import com.flipkart.varadhi.spi.db.MetaStoreProvider; -import com.flipkart.varadhi.spi.services.MessagingStackProvider; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; +import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; +import com.flipkart.varadhi.core.proxies.ServerOpMgrProxy; +import com.flipkart.varadhi.entities.VaradhiSubscription; +import com.flipkart.varadhi.spi.db.MetaStore; import io.micrometer.core.instrument.MeterRegistry; -import io.vertx.core.Future; -public class ControllerMgr { - public final String CONTROLLER_ADDRESS = "Controller" ; +import java.util.concurrent.CompletableFuture; - private final MetaStoreProvider metaStoreProvider; - private final MessagingStackProvider messagingStackProvider; - private final MeterRegistry meterRegistry; - private final MessageHandler controllerHandler; - private final Orchestrator orchestrator; +public class ControllerMgr implements ControllerOpHandler { + private ServerOpHandler serverOpHandler; - private final MessageChannel channel; - public ControllerMgr(MessagingStackProvider messagingStackProvider, - MetaStoreProvider metaStoreProvider, - MessageChannel channel, - MeterRegistry meterRegistry - ) { - this.messagingStackProvider = messagingStackProvider; - this.metaStoreProvider = metaStoreProvider; - this.meterRegistry = meterRegistry; - this.channel = channel; - this.orchestrator = new Orchestrator(); - this.controllerHandler = new ControllerMessageHandler(this.orchestrator); + public ControllerMgr(ServerOpHandler serverOpHandler) { + this.serverOpHandler = serverOpHandler; } - - public Future start() { - // leader election and on elected as leader - - // register message handler -// channel.addMessageHandler(CONTROLLER_ADDRESS, controllerHandler); - - // initiate recovery - return Future.succeededFuture(); - } - - public Future shutdown() { - channel.removeMessageHandler(CONTROLLER_ADDRESS); - return Future.succeededFuture(); + @Override + public CompletableFuture StartSubscription(SubscriptionOperation operation) { + operation.markInProgress(); + serverOpHandler.update(operation); + return CompletableFuture.completedFuture(null); } } diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java b/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java deleted file mode 100644 index d80b15a3..00000000 --- a/controller/src/main/java/com/flipkart/varadhi/controller/Orchestrator.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.flipkart.varadhi.controller; - -import com.flipkart.varadhi.core.cluster.messages.StartSubscription; -import com.flipkart.varadhi.core.cluster.messages.StopSubscription; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; -import lombok.extern.slf4j.Slf4j; - -import java.util.concurrent.CompletableFuture; - -@Slf4j -public class Orchestrator { - - public CompletableFuture handleSubscriptionMessage(SubscriptionMessage subscriptionMessage) { - if (subscriptionMessage instanceof StartSubscription) { - return startSubscription((StartSubscription) subscriptionMessage); - } else if (subscriptionMessage instanceof StopSubscription) { - return stopSubscription((StopSubscription) subscriptionMessage); - } - return CompletableFuture.failedFuture(new IllegalArgumentException("Unknown SubscriptionMessage type")); - } - - - private CompletableFuture startSubscription(StartSubscription startSubscription) { - log.info("Starting subscription for {}", startSubscription.getSubscriptionId()); - return CompletableFuture.completedFuture(null); - } - - private CompletableFuture stopSubscription(StopSubscription stopSubscription) { - log.info("Stopping subscription for {}", stopSubscription.getSubscriptionId()); - return CompletableFuture.completedFuture(null); - } -} - diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java similarity index 55% rename from server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java rename to core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java index a0980086..691f32d8 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannel.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java @@ -1,6 +1,8 @@ -package com.flipkart.varadhi.cluster; +package com.flipkart.varadhi.core.cluster; +import com.flipkart.varadhi.core.cluster.messages.*; + import java.util.concurrent.CompletableFuture; /** @@ -21,7 +23,24 @@ public interface MessageChannel { CompletableFuture request(String path, ClusterMessage msg); - void addMessageHandler(String path, MessageHandler messageHandler); + // void addMessageHandler(String path, MessageHandler messageHandler); + void register(String address, Class messageClazz, SendHandler handler); + + void register(String address, Class messageClazz, RequestHandler handler); + + void register(String address, Class messageClazz, PublishHandler handler); void removeMessageHandler(String path); + + public static enum Method { + SEND("send"), + PUBLISH("publish"), + REQUEST("request"); + + private String name; + + Method(String name) { + this.name = name; + } + } } diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java similarity index 69% rename from server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java rename to core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java index d9d5237a..3c4d0d53 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageHandler.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java @@ -1,6 +1,9 @@ -package com.flipkart.varadhi.cluster; +package com.flipkart.varadhi.core.cluster; +import com.flipkart.varadhi.core.cluster.messages.ClusterMessage; +import com.flipkart.varadhi.core.cluster.messages.ResponseMessage; + import java.util.concurrent.CompletableFuture; public interface MessageHandler { diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java similarity index 88% rename from server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java rename to core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java index bc360c63..915482a2 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterMessage.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.cluster; +package com.flipkart.varadhi.core.cluster.messages; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java new file mode 100644 index 00000000..070a3273 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java @@ -0,0 +1,5 @@ +package com.flipkart.varadhi.core.cluster.messages; + +public interface PublishHandler { + void handle(E message); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java new file mode 100644 index 00000000..12b20815 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java @@ -0,0 +1,7 @@ +package com.flipkart.varadhi.core.cluster.messages; + +import java.util.concurrent.CompletableFuture; + +public interface RequestHandler { + CompletableFuture handle(E message); +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ResponseMessage.java similarity index 77% rename from server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java rename to core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ResponseMessage.java index 14ec4036..304c85dc 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/ResponseMessage.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ResponseMessage.java @@ -1,4 +1,4 @@ -package com.flipkart.varadhi.cluster; +package com.flipkart.varadhi.core.cluster.messages; public class ResponseMessage extends ClusterMessage { // indicates a response to a request message. diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SendHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SendHandler.java new file mode 100644 index 00000000..3b061b67 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SendHandler.java @@ -0,0 +1,8 @@ +package com.flipkart.varadhi.core.cluster.messages; + +import java.util.concurrent.CompletableFuture; + +@FunctionalInterface +public interface SendHandler { + CompletableFuture handle(E message); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java new file mode 100644 index 00000000..4dc223bb --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java @@ -0,0 +1,17 @@ +package com.flipkart.varadhi.core.cluster.messages; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class SubscriptionMessage extends ClusterMessage { + private final String subscriptionId; + private final SubscriptionOperation operation; + + public SubscriptionMessage(SubscriptionOperation operation) { + super(); + this.subscriptionId = operation.getSubscriptionId(); + this.operation = operation; + } +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java new file mode 100644 index 00000000..eaeecf7d --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java @@ -0,0 +1,45 @@ +package com.flipkart.varadhi.core.cluster.messages; + + +import com.flipkart.varadhi.entities.VaradhiSubscription; +import lombok.Data; + +import java.util.UUID; + +@Data +public class SubscriptionOperation { + public static enum Kind { + CREATE, START, STOP, DELETE, UPDATE + } + public static enum State { + SCHEDULED, ERRORED, COMPLETED, IN_PROGRESS + } + + private String operationId; + private Kind kind; + private State state; + private String subscriptionId; + private String requestedBy; + private String errorMessage; + private long startTime; + private long endTime; + + public void markInProgress() { + state = State.IN_PROGRESS; + } + + public SubscriptionMessage toMessage() { + return new SubscriptionMessage(this); + } + + public static SubscriptionOperation getSubscriptionOp(Kind opKind, String subscriptionId, String requestedBy) { + SubscriptionOperation op = new SubscriptionOperation(); + op.setOperationId(UUID.randomUUID().toString()); + op.setKind(opKind); + op.setState(State.SCHEDULED); + op.setSubscriptionId(subscriptionId); + op.setRequestedBy(requestedBy); + op.setStartTime(System.currentTimeMillis()); + return op; + } +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java new file mode 100644 index 00000000..41ed379a --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java @@ -0,0 +1,9 @@ +package com.flipkart.varadhi.core.ophandlers; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; + +import java.util.concurrent.CompletableFuture; + +public interface ControllerOpHandler { + CompletableFuture StartSubscription(SubscriptionOperation operation); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java new file mode 100644 index 00000000..b687dea9 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java @@ -0,0 +1,10 @@ +package com.flipkart.varadhi.core.ophandlers; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.entities.VaradhiSubscription; + +import java.util.concurrent.CompletableFuture; + +public interface ServerOpHandler { + CompletableFuture update(SubscriptionOperation operation); +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java b/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java new file mode 100644 index 00000000..174277a3 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java @@ -0,0 +1,27 @@ +package com.flipkart.varadhi.core.proxies; + +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; + +import java.util.concurrent.CompletableFuture; + +public class ControllerMgrProxy implements ControllerOpHandler { + private final String CONTROLLER_ADDR = "Controller"; + private final MessageChannel channel; + + public ControllerMgrProxy(MessageChannel channel) { + this.channel = channel; + } + + @Override + public CompletableFuture StartSubscription(SubscriptionOperation operation) { + SubscriptionMessage message = operation.toMessage(); + return channel.send(getAddress(MessageChannel.Method.SEND, message), message); + } + + private String getAddress(MessageChannel.Method method, SubscriptionMessage message) { + return CONTROLLER_ADDR + "." + message.getClass().getSimpleName() + "." + method; + } +} diff --git a/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java b/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java new file mode 100644 index 00000000..ff677496 --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java @@ -0,0 +1,27 @@ +package com.flipkart.varadhi.core.proxies; + +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; +import com.flipkart.varadhi.entities.VaradhiSubscription; + +import java.util.concurrent.CompletableFuture; + +public class ServerOpMgrProxy implements ServerOpHandler { + private final String SERVER_ADDR = "Server"; + private final MessageChannel channel; + + public ServerOpMgrProxy(MessageChannel channel) { + this.channel = channel; + } + @Override + public CompletableFuture update(SubscriptionOperation operation) { + SubscriptionMessage message = operation.toMessage(); + return channel.send(getAddress(MessageChannel.Method.SEND, message), message); + } + + private String getAddress(MessageChannel.Method method, SubscriptionMessage message) { + return SERVER_ADDR + "." + message.getClass().getSimpleName() + "." + method; + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/RestVerticle.java b/server/src/main/java/com/flipkart/varadhi/RestVerticle.java index 2dcb420f..0a1cf338 100644 --- a/server/src/main/java/com/flipkart/varadhi/RestVerticle.java +++ b/server/src/main/java/com/flipkart/varadhi/RestVerticle.java @@ -102,8 +102,8 @@ public void start(Promise startPromise) { log.info("HttpServer Started."); startPromise.complete(); } else { - log.warn("HttpServer Start Failed."); - startPromise.fail("HttpServer Start Failed."); + log.warn("HttpServer Start Failed." + h.cause()); + startPromise.fail("HttpServer Start Failed." + h.cause()); } }); } diff --git a/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java b/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java new file mode 100644 index 00000000..c31f4820 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java @@ -0,0 +1,15 @@ +package com.flipkart.varadhi; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; +import com.flipkart.varadhi.entities.VaradhiSubscription; + +import java.util.concurrent.CompletableFuture; + +public class ServerOpManager implements ServerOpHandler { + @Override + public CompletableFuture update(SubscriptionOperation operation) { + // persist the operation change. + return CompletableFuture.completedFuture(null); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java index 8210d877..a7c9c881 100644 --- a/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java +++ b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java @@ -1,9 +1,11 @@ package com.flipkart.varadhi; +import com.flipkart.varadhi.cluster.ClusterManager; +import com.flipkart.varadhi.cluster.impl.ClusterManagerImpl; import com.flipkart.varadhi.components.Component; import com.flipkart.varadhi.components.ComponentKind; -import com.flipkart.varadhi.components.Controller; -import com.flipkart.varadhi.components.Server; +import com.flipkart.varadhi.components.controller.Controller; +import com.flipkart.varadhi.components.server.Server; import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.exceptions.InvalidConfigException; import com.flipkart.varadhi.utils.HostUtils; @@ -34,9 +36,10 @@ public static void main(String[] args) { AppConfiguration configuration = readConfiguration(args); CoreServices services = new CoreServices(configuration); Vertx vertx = createVertex(configuration, services); + ClusterManager clusterManager = createClusterManager(vertx); Map components = getComponents(configuration, services); - Future.all(components.entrySet().stream().map(e -> e.getValue().start(vertx).onComplete(ar -> { + Future.all(components.entrySet().stream().map(e -> e.getValue().start(vertx, clusterManager).onComplete(ar -> { if (ar.succeeded()) { log.info("Component({}) started.", e.getKey()); } else { @@ -72,6 +75,12 @@ private static Vertx createVertex(AppConfiguration configuration, CoreServices s return vertx; } + private static ClusterManager createClusterManager(Vertx vertx) { + // TODO:: Placeholder for now. This node joining the cluster needs to be closed + // along with ClusterManager related changes. + return new ClusterManagerImpl(vertx); + } + public static AppConfiguration readConfiguration(String[] args) { if (args.length < 1) { log.error("Usage: java com.flipkart.varadhi.VaradhiApplication configuration.yml"); @@ -114,7 +123,7 @@ private static Map getComponents( configuration.getComponents().contains(kind) )) .collect(Collectors.toMap(Function.identity(), kind -> switch (kind) { - case Server -> new Server("hostName", configuration, coreServices); + case Server -> new Server(configuration, coreServices); case Controller -> new Controller(configuration, coreServices); default -> throw new IllegalArgumentException("Unknown Component Kind: " + kind); })); diff --git a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java index 4cbe60e0..0eca5bd1 100644 --- a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java @@ -5,6 +5,9 @@ import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.core.VaradhiTopicFactory; import com.flipkart.varadhi.core.VaradhiTopicService; +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; +import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; import com.flipkart.varadhi.exceptions.VaradhiException; import com.flipkart.varadhi.produce.otel.ProducerMetricHandler; import com.flipkart.varadhi.produce.services.ProducerService; @@ -51,11 +54,11 @@ public abstract class VerticleDeployer { private final Map behaviorConfigurators = new HashMap<>(); public VerticleDeployer( - String hostName, Vertx vertx, AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, + MessageChannel messageChannel, MeterRegistry meterRegistry, Tracer tracer ) { @@ -87,7 +90,9 @@ public VerticleDeployer( producerMetricsHandler ); this.authZHandlersSupplier = getIamPolicyHandlersSupplier(projectService, metaStore); - this.subscriptionHandlers = new SubscriptionHandlers(new SubscriptionService(metaStore), projectService); + ControllerOpHandler controllerOpHandler = new ControllerMgrProxy(messageChannel); + SubscriptionService subscriptionService = new SubscriptionService(metaStore, controllerOpHandler); + this.subscriptionHandlers = new SubscriptionHandlers(subscriptionService, projectService); this.healthCheckHandler = new HealthCheckHandler(); AuthnHandler authnHandler = new AuthnHandler(vertx, configuration); diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java index 3d7507b4..85fab206 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/ClusterManager.java @@ -1,5 +1,7 @@ package com.flipkart.varadhi.cluster; +import com.flipkart.varadhi.core.cluster.MessageChannel; + import java.util.List; /** diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java deleted file mode 100644 index 27b9468c..00000000 --- a/server/src/main/java/com/flipkart/varadhi/cluster/CreateSubscription.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.flipkart.varadhi.cluster; - - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Getter -@EqualsAndHashCode(callSuper = true) -public class CreateSubscription extends SubscriptionMessage { - public CreateSubscription(String subscriptionId) { - super(subscriptionId); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java deleted file mode 100644 index ac7cb353..00000000 --- a/server/src/main/java/com/flipkart/varadhi/cluster/DeleteSubscription.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.flipkart.varadhi.cluster; - - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Getter -@EqualsAndHashCode(callSuper = true) -public class DeleteSubscription extends SubscriptionMessage { - public DeleteSubscription(String subscriptionId) { - super(subscriptionId); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java index 18eb718c..009f5d5c 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java @@ -1,8 +1,9 @@ package com.flipkart.varadhi.cluster; +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.*; import com.flipkart.varadhi.exceptions.NotImplementedException; import com.flipkart.varadhi.utils.JsonMapper; -import io.vertx.core.Vertx; import io.vertx.core.eventbus.DeliveryOptions; import io.vertx.core.eventbus.EventBus; import io.vertx.core.eventbus.MessageConsumer; @@ -14,21 +15,15 @@ @Slf4j public class MessageChannelImpl implements MessageChannel { - - public static final String DELIVERY_KIND_HEADER = "DeliveryKind"; - public static final String DELIVERY_KIND_SEND = "Send"; - public static final String DELIVERY_KIND_REQUEST = "Request"; - public static final String DELIVERY_KIND_PUBLISH = "Publish"; - private final EventBus vertxEventBus; private final DeliveryOptions deliveryOptions; - private final Map> registerdConsumers; + private final Map> registeredConsumers; //TODO:: Add config details to DeliveryOptions e.g. timeouts, tracing etc as part of cluster manager changes. - public MessageChannelImpl(Vertx vertx) { - this.vertxEventBus = vertx.eventBus(); + public MessageChannelImpl(EventBus vertxEventBus) { + this.vertxEventBus = vertxEventBus; this.deliveryOptions = new DeliveryOptions(); - this.registerdConsumers = new HashMap<>(); + this.registeredConsumers = new HashMap<>(); } @Override @@ -39,10 +34,9 @@ public void publish(String address, ClusterMessage msg) { @Override public CompletableFuture send(String address, ClusterMessage msg) { CompletableFuture future = new CompletableFuture<>(); - DeliveryOptions deliveryOptions = getDeliveryOptions(DELIVERY_KIND_SEND); vertxEventBus.request(address, JsonMapper.jsonSerialize(msg), deliveryOptions, ar -> { if (ar.succeeded()) { - log.info("Received reply: " + ar.result().body()); + log.info("received reply: " + ar.result().body()); future.complete(null); } else { log.info("send failure: " + ar.cause().getMessage()); @@ -52,11 +46,6 @@ public CompletableFuture send(String address, ClusterMessage msg) { return future; } - private DeliveryOptions getDeliveryOptions(String deliveryKind) { - // Add other static config options like timeout etc. - return new DeliveryOptions(deliveryOptions).addHeader(DELIVERY_KIND_HEADER, deliveryKind); - } - @Override public CompletableFuture request(String address, ClusterMessage msg) { throw new NotImplementedException("request not implemented"); @@ -64,46 +53,33 @@ public CompletableFuture request(String address, ClusterMessage @Override public void removeMessageHandler(String address) { - MessageConsumer consumer = registerdConsumers.get(address); + MessageConsumer consumer = registeredConsumers.get(address); if (null != consumer) { consumer.unregister(); - registerdConsumers.remove(address); + registeredConsumers.remove(address); } } @Override - public void addMessageHandler(String address, MessageHandler messageHandler) { - //TODO:: Evaluate if dispatcher mechanism is needed to control the execution parallelism. - MessageConsumer consumer = vertxEventBus.consumer(address, message -> { - ClusterMessage clusterMessage = JsonMapper.jsonDeserialize(message.body(), ClusterMessage.class); - if (null == message.replyAddress()) { - // received via publish message - messageHandler.handle(clusterMessage); - log.info("publish({}) message processed.", clusterMessage.getId()); - } else { - String deliveryKind = message.headers().get(DELIVERY_KIND_HEADER); - if (DELIVERY_KIND_SEND.equals(deliveryKind)) { - // received via send message - // acknowledge to indicate that message is delivered, processing is async. - message.reply("Received"); - messageHandler.handle(clusterMessage); - log.info("send({}) message processed.", clusterMessage.getId()); - } else { - // received via request message - messageHandler.request(clusterMessage).handle((response, failure) -> { - if (null != failure) { - message.fail(500, failure.getMessage()); - log.error("request({}) processing failed. {}", clusterMessage.getId(), failure.getMessage()); - } else { - message.reply(JsonMapper.jsonSerialize(response)); - log.info("request({}) processed with response({})", clusterMessage.getId(), response.getId()); - } - return null; - }); - } - } + public void register(String address, Class messageClazz, SendHandler handler) { + String fullAddress = address + "." + messageClazz.getSimpleName() + "." + Method.SEND ; + MessageConsumer consumer = vertxEventBus.consumer(fullAddress, message -> { + E cm = JsonMapper.jsonDeserialize(message.body(), messageClazz); + message.reply("received"); + handler.handle(cm); + log.info("send({}) message processed.", cm.getId()); }); // not expected to be registered multiple times. - registerdConsumers.put(address, consumer); + registeredConsumers.put(fullAddress, consumer); + } + + @Override + public void register(String address, Class messageClazz, RequestHandler handler) { + throw new NotImplementedException("register RequestHandler not implemented"); + } + + @Override + public void register(String address, Class messageClazz, PublishHandler handler) { + throw new NotImplementedException("register PublishHandler not implemented"); } } diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java deleted file mode 100644 index d140dae7..00000000 --- a/server/src/main/java/com/flipkart/varadhi/cluster/StartSubscription.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.flipkart.varadhi.cluster; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Getter -@EqualsAndHashCode(callSuper = true) -public class StartSubscription extends SubscriptionMessage { - public StartSubscription(String subscriptionId) { - super(subscriptionId); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java b/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java deleted file mode 100644 index b31603b5..00000000 --- a/server/src/main/java/com/flipkart/varadhi/cluster/StopSubscription.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.flipkart.varadhi.cluster; - - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Getter -@EqualsAndHashCode(callSuper = true) -public class StopSubscription extends SubscriptionMessage { - public StopSubscription(String subscriptionId) { - super(subscriptionId); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java b/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java deleted file mode 100644 index eab17345..00000000 --- a/server/src/main/java/com/flipkart/varadhi/cluster/SubscriptionMessage.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.flipkart.varadhi.cluster; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -@Getter -@EqualsAndHashCode(callSuper = true) -public class SubscriptionMessage extends ClusterMessage { - private final String subscriptionId; - - public SubscriptionMessage(String subscriptionId) { - super(); - this.subscriptionId = subscriptionId; - } - -} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/impl/ClusterManagerImpl.java b/server/src/main/java/com/flipkart/varadhi/cluster/impl/ClusterManagerImpl.java index d5942d72..2e3ddc59 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/impl/ClusterManagerImpl.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/impl/ClusterManagerImpl.java @@ -1,15 +1,21 @@ package com.flipkart.varadhi.cluster.impl; -import com.flipkart.varadhi.cluster.*; + +import com.flipkart.varadhi.cluster.ClusterManager; +import com.flipkart.varadhi.cluster.MembershipListener; +import com.flipkart.varadhi.cluster.MessageChannelImpl; +import com.flipkart.varadhi.cluster.NodeInfo; +import com.flipkart.varadhi.core.cluster.MessageChannel; +import io.vertx.core.Vertx; import lombok.RequiredArgsConstructor; import java.util.List; + @RequiredArgsConstructor public class ClusterManagerImpl implements ClusterManager { - // TODO: add instance of zkClusterManager & clusteredVertx and use it to implement the methods of this class - + private final Vertx vertx; @Override public List getAllMembers() { return null; @@ -22,6 +28,6 @@ public void addMembershipListener(MembershipListener listener) { @Override public MessageChannel connect(String nodeId) { - return null; + return new MessageChannelImpl(vertx.eventBus()); } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/Component.java b/server/src/main/java/com/flipkart/varadhi/components/Component.java index b72e47d7..b0e93271 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/Component.java +++ b/server/src/main/java/com/flipkart/varadhi/components/Component.java @@ -1,11 +1,12 @@ package com.flipkart.varadhi.components; import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.cluster.ClusterManager; import com.flipkart.varadhi.config.AppConfiguration; import io.vertx.core.Future; import io.vertx.core.Vertx; public interface Component { - Future start(Vertx vertx); - Future shutdown(Vertx vertx); + Future start(Vertx vertx, ClusterManager clusterManager); + Future shutdown(Vertx vertx, ClusterManager clusterManager); } diff --git a/server/src/main/java/com/flipkart/varadhi/components/Controller.java b/server/src/main/java/com/flipkart/varadhi/components/Controller.java deleted file mode 100644 index 29fad5b0..00000000 --- a/server/src/main/java/com/flipkart/varadhi/components/Controller.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.flipkart.varadhi.components; - -import com.flipkart.varadhi.CoreServices; -import com.flipkart.varadhi.config.AppConfiguration; -import com.flipkart.varadhi.controller.ControllerMgr; -import io.vertx.core.Future; -import io.vertx.core.Vertx; - -public class Controller implements Component { - - private final ControllerMgr controllerMgr; - - public Controller(AppConfiguration configuration, CoreServices coreServices) { - this.controllerMgr = new ControllerMgr(coreServices.getMessagingStackProvider(), - coreServices.getMetaStoreProvider(), - null, - coreServices.getMeterRegistry()); - } - @Override - public Future start(Vertx vertx) { - return controllerMgr.start(); - } - - @Override - public Future shutdown(Vertx vertx) { - return controllerMgr.shutdown(); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java b/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java new file mode 100644 index 00000000..950db9aa --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java @@ -0,0 +1,36 @@ +package com.flipkart.varadhi.components.controller; + +import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.cluster.ClusterManager; +import com.flipkart.varadhi.components.Component; +import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.controller.ControllerMgr; +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.proxies.ServerOpMgrProxy; +import io.vertx.core.Future; +import io.vertx.core.Vertx; + +public class Controller implements Component { + + public Controller(AppConfiguration configuration, CoreServices coreServices) { + } + + @Override + public Future start(Vertx vertx, ClusterManager clusterManager) { + MessageChannel messageChannel = clusterManager.connect(null); + setUpMessageHandlers(messageChannel); + return Future.succeededFuture(); + } + + @Override + public Future shutdown(Vertx vertx, ClusterManager clusterManager) { + return Future.succeededFuture(); + } + + private void setUpMessageHandlers(MessageChannel channel) { + ControllerMgr controllerMgr = new ControllerMgr(new ServerOpMgrProxy(channel)); + SubscriptionOpHandler handler = new SubscriptionOpHandler(controllerMgr, channel); + channel.register("controller", SubscriptionMessage.class, handler::start); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java b/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java new file mode 100644 index 00000000..0dee6f50 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java @@ -0,0 +1,34 @@ +package com.flipkart.varadhi.components.controller; + +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; + +import java.util.concurrent.CompletableFuture; + +public class SubscriptionOpHandler { + private final ControllerOpHandler opHandler; + private final MessageChannel channel; + + public SubscriptionOpHandler(ControllerOpHandler opHandler, MessageChannel channel) { + this.opHandler = opHandler; + this.channel = channel; + } + + public CompletableFuture start(SubscriptionMessage message) { + // TODO::it is not async + SubscriptionOperation operation = message.getOperation(); + if (operation.getKind() != SubscriptionOperation.Kind.START) { + throw new IllegalArgumentException("Invalid operation type"); + } + opHandler.StartSubscription(operation).exceptionally(throwable -> { + operation.setErrorMessage(throwable.getMessage()); + operation.setState(SubscriptionOperation.State.ERRORED); + channel.send("Server", operation.toMessage()); + return null; + }); + // send the update to the server. + return CompletableFuture.completedFuture(null); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/Server.java b/server/src/main/java/com/flipkart/varadhi/components/server/Server.java similarity index 63% rename from server/src/main/java/com/flipkart/varadhi/components/Server.java rename to server/src/main/java/com/flipkart/varadhi/components/server/Server.java index 2281e862..393ddbc9 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/Server.java +++ b/server/src/main/java/com/flipkart/varadhi/components/server/Server.java @@ -1,34 +1,43 @@ -package com.flipkart.varadhi.components; +package com.flipkart.varadhi.components.server; import com.flipkart.varadhi.CoreServices; +import com.flipkart.varadhi.ServerOpManager; import com.flipkart.varadhi.VerticleDeployer; +import com.flipkart.varadhi.cluster.ClusterManager; +import com.flipkart.varadhi.components.Component; import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; import com.flipkart.varadhi.deployment.FullDeploymentVerticleDeployer; import com.flipkart.varadhi.deployment.LeanDeploymentVerticleDeployer; +import io.opentelemetry.api.trace.Tracer; import io.vertx.core.Future; import io.vertx.core.Vertx; import lombok.extern.slf4j.Slf4j; @Slf4j public class Server implements Component { - private String verticleId; private final AppConfiguration configuration; private final CoreServices coreServices; - private final String hostName; + private String verticleId; + private ServerOperationHandler handler; - public Server(String hostname, AppConfiguration configuration, CoreServices coreServices) { - this.hostName = hostname; + public Server(AppConfiguration configuration, CoreServices coreServices) { this.configuration = configuration; this.coreServices = coreServices; + this.handler = + new ServerOperationHandler(new ServerOpManager(), coreServices.getMetaStoreProvider().getMetaStore()); } @Override - public Future start(Vertx vertx) { - return deployVerticle(vertx); + public Future start(Vertx vertx, ClusterManager clusterManager) { + MessageChannel messageChannel = clusterManager.connect(null); + setupMessageHandlers(messageChannel); + return deployVerticle(vertx, messageChannel); } @Override - public Future shutdown(Vertx vertx) { + public Future shutdown(Vertx vertx, ClusterManager clusterManager) { //TODO:: // - fail health check. // - reject any new request for retry (may be via a custom handler ?). @@ -44,13 +53,14 @@ public Future shutdown(Vertx vertx) { log.error("Undeploy failed.", ar.cause()); } }); - }else{ + } else { return Future.succeededFuture(); } } - private Future deployVerticle( Vertx vertx) { + + private Future deployVerticle(Vertx vertx, MessageChannel messageChannel) { log.info("Verticle deployment started."); - VerticleDeployer verticleDeployer = createVerticleDeployer(vertx); + VerticleDeployer verticleDeployer = createVerticleDeployer(vertx, messageChannel); return verticleDeployer.deployVerticle(vertx, configuration).compose(r -> { log.info("Verticle() deployment completed {}.", r); verticleId = r; @@ -61,28 +71,34 @@ private Future deployVerticle( Vertx vertx) { }); } - private VerticleDeployer createVerticleDeployer(Vertx vertx) { + private VerticleDeployer createVerticleDeployer(Vertx vertx, MessageChannel messageChannel) { VerticleDeployer verticleDeployer; + Tracer tracer = coreServices.getTracer("varadhi"); if (configuration.getFeatureFlags().isLeanDeployment()) { - verticleDeployer = new LeanDeploymentVerticleDeployer(hostName, + verticleDeployer = new LeanDeploymentVerticleDeployer( vertx, configuration, coreServices.getMessagingStackProvider(), coreServices.getMetaStoreProvider(), + messageChannel, coreServices.getMeterRegistry(), - coreServices.getTracer() + tracer ); } else { - verticleDeployer = new FullDeploymentVerticleDeployer(hostName, + verticleDeployer = new FullDeploymentVerticleDeployer( vertx, configuration, coreServices.getMessagingStackProvider(), coreServices.getMetaStoreProvider(), + messageChannel, coreServices.getMeterRegistry(), - coreServices.getTracer() + tracer ); } return verticleDeployer; } + public void setupMessageHandlers(MessageChannel messageChannel) { + messageChannel.register("Server", SubscriptionMessage.class, handler::update); + } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java b/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java new file mode 100644 index 00000000..eb47d6af --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java @@ -0,0 +1,21 @@ +package com.flipkart.varadhi.components.server; + +import com.flipkart.varadhi.ServerOpManager; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.spi.db.MetaStore; + +import java.util.concurrent.CompletableFuture; + +public class ServerOperationHandler { + private MetaStore metaStore; + private ServerOpManager serverOpMgr; + + public ServerOperationHandler(ServerOpManager serverOpMgr, MetaStore metaStore) { + this.serverOpMgr = serverOpMgr; + this.metaStore = metaStore; + } + + public CompletableFuture update(SubscriptionMessage message) { + return serverOpMgr.update(null); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java index 05cb73e2..d5ed4d17 100644 --- a/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/deployment/FullDeploymentVerticleDeployer.java @@ -2,6 +2,7 @@ import com.flipkart.varadhi.VerticleDeployer; import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.spi.db.MetaStoreProvider; import com.flipkart.varadhi.spi.services.MessagingStackProvider; import com.flipkart.varadhi.web.routes.RouteDefinition; @@ -24,12 +25,11 @@ public class FullDeploymentVerticleDeployer extends VerticleDeployer { private final ProjectHandlers projectHandlers; public FullDeploymentVerticleDeployer( - String hostName, Vertx vertx, AppConfiguration configuration, + Vertx vertx, AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, - MeterRegistry meterRegistry, - Tracer tracer + MessageChannel messageChannel, MeterRegistry meterRegistry, Tracer tracer ) { - super(hostName, vertx, configuration, messagingStackProvider, metaStoreProvider, meterRegistry, tracer); + super(vertx, configuration, messagingStackProvider, metaStoreProvider, messageChannel, meterRegistry, tracer); this.orgHandlers = new OrgHandlers(this.orgService); this.teamHandlers = new TeamHandlers(this.teamService); this.projectHandlers = new ProjectHandlers(this.projectService); diff --git a/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java index 2f838a12..4fe320c7 100644 --- a/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployer.java @@ -4,6 +4,7 @@ import com.flipkart.varadhi.VerticleDeployer; import com.flipkart.varadhi.config.RestOptions; import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.entities.Org; import com.flipkart.varadhi.entities.Project; import com.flipkart.varadhi.entities.Team; @@ -22,12 +23,11 @@ @Slf4j public class LeanDeploymentVerticleDeployer extends VerticleDeployer { public LeanDeploymentVerticleDeployer( - String hostName, Vertx vertx, AppConfiguration configuration, + Vertx vertx, AppConfiguration configuration, MessagingStackProvider messagingStackProvider, MetaStoreProvider metaStoreProvider, - MeterRegistry meterRegistry, - Tracer tracer + MessageChannel messageChannel, MeterRegistry meterRegistry, Tracer tracer ) { - super(hostName, vertx, configuration, messagingStackProvider, metaStoreProvider, meterRegistry, tracer); + super(vertx, configuration, messagingStackProvider, metaStoreProvider, messageChannel, meterRegistry, tracer); } @Override diff --git a/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java b/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java index 5ff7db21..b80fde59 100644 --- a/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java +++ b/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java @@ -1,5 +1,9 @@ package com.flipkart.varadhi.services; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; +import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; import com.flipkart.varadhi.entities.VaradhiSubscription; import com.flipkart.varadhi.entities.VaradhiTopic; import com.flipkart.varadhi.exceptions.InvalidOperationForResourceException; @@ -11,11 +15,12 @@ import static com.flipkart.varadhi.entities.VersionedEntity.INITIAL_VERSION; public class SubscriptionService { - private final MetaStore metaStore; + private final ControllerOpHandler controllerOpHandler; - public SubscriptionService(MetaStore metaStore) { + public SubscriptionService(MetaStore metaStore, ControllerOpHandler controllerOpHandler) { this.metaStore = metaStore; + this.controllerOpHandler = controllerOpHandler; } public List getSubscriptionList(String projectName) { @@ -33,6 +38,11 @@ public VaradhiSubscription createSubscription(VaradhiSubscription subscription) return subscription; } + public void start(String subscriptionName){ + SubscriptionOperation op = SubscriptionOperation.getSubscriptionOp(SubscriptionOperation.Kind.START, subscriptionName, ""); + controllerOpHandler.StartSubscription(op); + } + private void validateCreation(VaradhiSubscription subscription) { metaStore.getProject(subscription.getProject()); VaradhiTopic topic = metaStore.getTopic(subscription.getTopic()); diff --git a/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java b/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java index 8b6d7c19..401a1af4 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java +++ b/server/src/main/java/com/flipkart/varadhi/web/RequestTraceAndLogHandler.java @@ -32,6 +32,7 @@ public void configure(Route route, RouteDefinition routeDef) { } public void addRequestSpanAndLog(RoutingContext ctx, String apiName) { + //TODO:: Add localhost and remote host information here. long start = System.currentTimeMillis(); Span span = addRequestSpan(apiName); ctx.response().endHandler(r -> { diff --git a/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java b/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java index 6e2e21ba..64c40ab3 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java +++ b/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java @@ -1,5 +1,6 @@ package com.flipkart.varadhi.web.v1.admin; +import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; import com.flipkart.varadhi.entities.*; import com.flipkart.varadhi.services.ProjectService; import com.flipkart.varadhi.services.SubscriptionService; @@ -140,7 +141,7 @@ public void stop(RoutingContext ctx) { private SubscriptionResource getValidSubscriptionResource(RoutingContext ctx) { String projectName = ctx.pathParam(PATH_PARAM_PROJECT); - SubscriptionResource subscription = ctx.get(CONTEXT_KEY_BODY);; + SubscriptionResource subscription = ctx.get(CONTEXT_KEY_BODY); // ensure project name consistent if (!projectName.equals(subscription.getProject())) { diff --git a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java index dd7a6de6..fa70f310 100644 --- a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java +++ b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java @@ -1,10 +1,12 @@ package com.flipkart.varadhi.cluster; import com.fasterxml.jackson.databind.jsontype.NamedType; +import com.flipkart.varadhi.core.cluster.MessageHandler; +import com.flipkart.varadhi.core.cluster.messages.ClusterMessage; +import com.flipkart.varadhi.core.cluster.messages.ResponseMessage; import com.flipkart.varadhi.utils.JsonMapper; import io.vertx.core.Future; import io.vertx.core.Vertx; -import io.vertx.core.VertxOptions; import io.vertx.core.spi.cluster.ClusterManager; import io.vertx.junit5.Checkpoint; import io.vertx.junit5.VertxExtension; @@ -30,9 +32,10 @@ public class MessageChannelImplTest { // TODO:: Tests needs to be added, so this will go under refactor @BeforeEach - public void setup(){ + public void setup() { JsonMapper.getMapper().registerSubtypes(new NamedType(TestClusterMessage.class, "TestClusterMessage")); - JsonMapper.getMapper().registerSubtypes(new NamedType(ExtendedTestClusterMessage.class, "ExtendedTestClusterMessage")); + JsonMapper.getMapper() + .registerSubtypes(new NamedType(ExtendedTestClusterMessage.class, "ExtendedTestClusterMessage")); } private Vertx createClusteredVertx() throws Exception { @@ -41,62 +44,57 @@ private Vertx createClusteredVertx() throws Exception { CuratorFrameworkFactory.newClient( zkCuratorTestingServer.getConnectString(), new ExponentialBackoffRetry(1000, 1))); zkCuratorFramework.start(); - VertxOptions vertxOptions = new VertxOptions(); ClusterManager cm = new ZookeeperClusterManager(zkCuratorFramework, "foo"); - vertxOptions.setClusterManager(cm); - return Vertx.clusteredVertx(vertxOptions).toCompletionStage().toCompletableFuture().get(); + return Vertx.builder().withClusterManager(cm).buildClustered().toCompletionStage().toCompletableFuture().get(); } + @Test public void sendMessageNoConsumer(VertxTestContext testContext) throws Exception { - Checkpoint checkpoint = testContext.checkpoint(1); + Checkpoint checkpoint = testContext.checkpoint(1); Vertx vertx = createClusteredVertx(); - MessageChannelImpl c = new MessageChannelImpl(vertx); + MessageChannelImpl c = new MessageChannelImpl(vertx.eventBus()); ClusterMessage cm = getClusterMessage("foo"); - Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.failing(v -> { - checkpoint.flag(); - })); + Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.failing(v -> checkpoint.flag())); } - @Test - public void testSendMessageConsumerColocated(VertxTestContext testContext) throws Exception{ - Checkpoint checkpoint = testContext.checkpoint(2); - Vertx vertx = createClusteredVertx(); - MessageChannelImpl c = new MessageChannelImpl(vertx); - c.addMessageHandler("foo", new MessageHandler() { - @Override - public CompletableFuture handle(E message) { - if (message instanceof ExtendedTestClusterMessage) { - checkpoint.flag(); - } - return CompletableFuture.completedFuture(null); - } +// @Test +// public void testSendMessageConsumerCollocated(VertxTestContext testContext) throws Exception { +// Checkpoint checkpoint = testContext.checkpoint(2); +// Vertx vertx = createClusteredVertx(); +// MessageChannelImpl c = new MessageChannelImpl(vertx.eventBus()); +// c.addMessageHandler("foo", new MessageHandler() { +// @Override +// public CompletableFuture handle(E message) { +// if (message instanceof ExtendedTestClusterMessage) { +// checkpoint.flag(); +// } +// return CompletableFuture.completedFuture(null); +// } +// +// @Override +// public CompletableFuture request(E message) { +// return null; +// } +// }); +// +// ClusterMessage cm = getClusterMessage("foo"); +// Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.succeeding(v -> checkpoint.flag())); +// } - @Override - public CompletableFuture request(E message) { - return null; - } - }); - - ClusterMessage cm = getClusterMessage("foo"); - Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.succeeding(v -> { - checkpoint.flag(); - })); + ClusterMessage getClusterMessage(String data) { + ExtendedTestClusterMessage dm = new ExtendedTestClusterMessage(); + dm.data1 = data; + dm.data2 = data; + return dm; } - public static class TestClusterMessage extends ClusterMessage { + public static class TestClusterMessage extends ClusterMessage { String data1; } - public static class ExtendedTestClusterMessage extends TestClusterMessage { + public static class ExtendedTestClusterMessage extends TestClusterMessage { String data2; } - ClusterMessage getClusterMessage(String data) { - ExtendedTestClusterMessage dm = new ExtendedTestClusterMessage(); - dm.data1 = data; - dm.data2 = data; - return dm; - } - } diff --git a/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java b/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java index 8f1bdae6..5e106bd0 100644 --- a/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java +++ b/server/src/test/java/com/flipkart/varadhi/deployment/LeanDeploymentVerticleDeployerTest.java @@ -1,6 +1,7 @@ package com.flipkart.varadhi.deployment; import com.flipkart.varadhi.config.AppConfiguration; +import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.db.VaradhiMetaStore; import com.flipkart.varadhi.entities.Org; import com.flipkart.varadhi.entities.Project; @@ -23,6 +24,7 @@ import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.test.TestingServer; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -50,11 +52,12 @@ public class LeanDeploymentVerticleDeployerTest { MeterRegistry meterRegistry; - Vertx vertx = Vertx.vertx(); + Vertx vertx; private OrgService orgService; private TeamService teamService; private ProjectService projectService; + private MessageChannel messageChannel; private static final String TEST_ORG = "testOrg"; @@ -69,6 +72,7 @@ public class LeanDeploymentVerticleDeployerTest { @BeforeEach public void setup() throws Exception { + vertx = Vertx.vertx(); zkCuratorTestingServer = new TestingServer(); zkCurator = spy(CuratorFrameworkFactory.newClient( zkCuratorTestingServer.getConnectString(), new ExponentialBackoffRetry(1000, 1))); @@ -78,6 +82,8 @@ public void setup() throws Exception { messagingStackProvider = mock(MessagingStackProvider.class); metaStoreProvider = mock(MetaStoreProvider.class); meterRegistry = mock(MeterRegistry.class); + messageChannel = mock(MessageChannel.class); + when(metaStoreProvider.getMetaStore()).thenReturn(varadhiMetaStore); when(messagingStackProvider.getProducerFactory()).thenReturn(mock(ProducerFactory.class)); @@ -96,16 +102,24 @@ public void setup() throws Exception { leanDeploymentVerticleDeployer = new LeanDeploymentVerticleDeployer( - "testHostName", vertx, appConfiguration, messagingStackProvider, metaStoreProvider, + messageChannel, meterRegistry, null ); } + @AfterEach + public void tearDown(VertxTestContext testContext) throws Exception { + Checkpoint cp = testContext.checkpoint(1); + vertx.close().onComplete(testContext.succeeding(v -> { + cp.flag(); + })); + } + @Test public void testNoEntitiesPresent_Success(VertxTestContext testContext) { Checkpoint cp = testContext.checkpoint(1); diff --git a/server/src/test/java/com/flipkart/varadhi/services/SubscriptionServiceTest.java b/server/src/test/java/com/flipkart/varadhi/services/SubscriptionServiceTest.java index 6d32417e..c2bf1db7 100644 --- a/server/src/test/java/com/flipkart/varadhi/services/SubscriptionServiceTest.java +++ b/server/src/test/java/com/flipkart/varadhi/services/SubscriptionServiceTest.java @@ -46,6 +46,7 @@ void setUp() throws Exception { zkCuratorTestingServer.getConnectString(), new ExponentialBackoffRetry(1000, 1))); zkCurator.start(); varadhiMetaStore = spy(new VaradhiMetaStore(zkCurator)); + orgService = new OrgService(varadhiMetaStore); teamService = new TeamService(varadhiMetaStore); meterRegistry = new JmxMeterRegistry(JmxConfig.DEFAULT, Clock.SYSTEM); @@ -66,7 +67,7 @@ void setUp() throws Exception { projectService.createProject(o1t1p1); projectService.createProject(o1t1p2); - subscriptionService = new SubscriptionService(varadhiMetaStore); + subscriptionService = new SubscriptionService(varadhiMetaStore, null); } @Test diff --git a/server/src/test/resources/testConfiguration.yml b/server/src/test/resources/testConfiguration.yml index e4ec5054..63cc5589 100644 --- a/server/src/test/resources/testConfiguration.yml +++ b/server/src/test/resources/testConfiguration.yml @@ -1,3 +1,5 @@ +components : ["Server"] + restOptions: deployedRegion: "test" defaultOrg: "test" From f4987751edbe9b3da44dd8e773c0ce736ab785f4 Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Thu, 7 Mar 2024 12:28:09 +0530 Subject: [PATCH 5/8] add string override to channel method --- .../com/flipkart/varadhi/core/cluster/MessageChannel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java index 691f32d8..686b8c4f 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java @@ -42,5 +42,9 @@ public static enum Method { Method(String name) { this.name = name; } + @Override + public String toString() { + return name; + } } } From c0d9a5e5c380aab0a7e600f59fa7481af083c648 Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Thu, 7 Mar 2024 15:05:47 +0530 Subject: [PATCH 6/8] fix commented test and remove obselete message handler --- .../varadhi/core/cluster/MessageHandler.java | 16 ------- .../cluster/MessageChannelImplTest.java | 44 ++++++++----------- 2 files changed, 19 insertions(+), 41 deletions(-) delete mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java deleted file mode 100644 index 3c4d0d53..00000000 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.flipkart.varadhi.core.cluster; - - -import com.flipkart.varadhi.core.cluster.messages.ClusterMessage; -import com.flipkart.varadhi.core.cluster.messages.ResponseMessage; - -import java.util.concurrent.CompletableFuture; - -public interface MessageHandler { - - // handle will be used for messages sent via channel.send() and channel.publish(). - CompletableFuture handle(E message); - - // request will be used for messages sent via channel.request(). - CompletableFuture request(E message); -} diff --git a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java index fa70f310..d3cb5c2e 100644 --- a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java +++ b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java @@ -1,9 +1,9 @@ package com.flipkart.varadhi.cluster; import com.fasterxml.jackson.databind.jsontype.NamedType; -import com.flipkart.varadhi.core.cluster.MessageHandler; +import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.core.cluster.messages.ClusterMessage; -import com.flipkart.varadhi.core.cluster.messages.ResponseMessage; +import com.flipkart.varadhi.core.cluster.messages.SendHandler; import com.flipkart.varadhi.utils.JsonMapper; import io.vertx.core.Future; import io.vertx.core.Vertx; @@ -57,29 +57,23 @@ public void sendMessageNoConsumer(VertxTestContext testContext) throws Exception Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.failing(v -> checkpoint.flag())); } -// @Test -// public void testSendMessageConsumerCollocated(VertxTestContext testContext) throws Exception { -// Checkpoint checkpoint = testContext.checkpoint(2); -// Vertx vertx = createClusteredVertx(); -// MessageChannelImpl c = new MessageChannelImpl(vertx.eventBus()); -// c.addMessageHandler("foo", new MessageHandler() { -// @Override -// public CompletableFuture handle(E message) { -// if (message instanceof ExtendedTestClusterMessage) { -// checkpoint.flag(); -// } -// return CompletableFuture.completedFuture(null); -// } -// -// @Override -// public CompletableFuture request(E message) { -// return null; -// } -// }); -// -// ClusterMessage cm = getClusterMessage("foo"); -// Future.fromCompletionStage(c.send("foo", cm)).onComplete(testContext.succeeding(v -> checkpoint.flag())); -// } + @Test + public void testSendMessageConsumerCollocated(VertxTestContext testContext) throws Exception { + Checkpoint checkpoint = testContext.checkpoint(2); + Vertx vertx = createClusteredVertx(); + MessageChannelImpl c = new MessageChannelImpl(vertx.eventBus()); + c.register("testAddress", ExtendedTestClusterMessage.class, new SendHandler<>() { + @Override + public CompletableFuture handle(ExtendedTestClusterMessage message) { + checkpoint.flag(); + return CompletableFuture.completedFuture(null); + } + }); + + ClusterMessage cm = getClusterMessage("foo"); + String address = "testAddress" + "." + ExtendedTestClusterMessage.class.getSimpleName() + "." + MessageChannel.Method.SEND; + Future.fromCompletionStage(c.send(address, cm)).onComplete(testContext.succeeding(v -> checkpoint.flag())); + } ClusterMessage getClusterMessage(String data) { ExtendedTestClusterMessage dm = new ExtendedTestClusterMessage(); From 1fd93f8af6d00941baba3f4364278bfb2abc41fe Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Tue, 19 Mar 2024 22:02:06 +0530 Subject: [PATCH 7/8] review comments --- .../varadhi/controller/ControllerMgr.java | 21 +++---- .../varadhi/core/cluster/MessageChannel.java | 19 +++--- .../core/cluster/messages/ClusterMessage.java | 10 +++- .../core/cluster/messages/PublishHandler.java | 5 -- .../core/cluster/messages/RequestHandler.java | 7 --- .../cluster/messages/SubscriptionMessage.java | 11 ++-- .../messages/SubscriptionOperation.java | 58 ++++++++++++------- ...ollerOpHandler.java => ControllerApi.java} | 4 +- ...ServerOpHandler.java => WebServerApi.java} | 5 +- ...rMgrProxy.java => ControllerApiProxy.java} | 18 +++--- .../core/proxies/ServerOpMgrProxy.java | 27 --------- .../core/proxies/WebServerApiProxy.java | 25 ++++++++ .../com/flipkart/varadhi/ServerOpManager.java | 15 ----- .../flipkart/varadhi/VaradhiApplication.java | 4 +- .../flipkart/varadhi/VerticleDeployer.java | 8 +-- .../flipkart/varadhi/WebServerOpManager.java | 14 +++++ .../varadhi/cluster/MessageChannelImpl.java | 32 ++++------ .../varadhi/components/Component.java | 2 - .../varadhi/components/ComponentKind.java | 11 +++- .../components/controller/Controller.java | 12 ++-- .../controller/ControllerApiHandler.java | 27 +++++++++ .../controller/SubscriptionOpHandler.java | 34 ----------- .../server/ServerOperationHandler.java | 21 ------- .../Server.java => webserver/WebServer.java} | 19 +++--- .../webserver/WebServerApiHandler.java | 18 ++++++ .../varadhi/services/SubscriptionService.java | 15 +++-- .../varadhi/utils/SubscriptionHelper.java | 9 +++ .../com/flipkart/varadhi/web/Extensions.java | 10 ++++ .../web/v1/admin/SubscriptionHandlers.java | 12 +--- server/src/main/resources/configuration.yml | 2 +- .../cluster/MessageChannelImplTest.java | 3 +- .../src/test/resources/testConfiguration.yml | 2 +- 32 files changed, 238 insertions(+), 242 deletions(-) delete mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java delete mode 100644 core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java rename core/src/main/java/com/flipkart/varadhi/core/ophandlers/{ControllerOpHandler.java => ControllerApi.java} (79%) rename core/src/main/java/com/flipkart/varadhi/core/ophandlers/{ServerOpHandler.java => WebServerApi.java} (51%) rename core/src/main/java/com/flipkart/varadhi/core/proxies/{ControllerMgrProxy.java => ControllerApiProxy.java} (50%) delete mode 100644 core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java create mode 100644 core/src/main/java/com/flipkart/varadhi/core/proxies/WebServerApiProxy.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/ServerOpManager.java create mode 100644 server/src/main/java/com/flipkart/varadhi/WebServerOpManager.java create mode 100644 server/src/main/java/com/flipkart/varadhi/components/controller/ControllerApiHandler.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java delete mode 100644 server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java rename server/src/main/java/com/flipkart/varadhi/components/{server/Server.java => webserver/WebServer.java} (85%) create mode 100644 server/src/main/java/com/flipkart/varadhi/components/webserver/WebServerApiHandler.java diff --git a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java index eec8f709..3d109a6d 100644 --- a/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java +++ b/controller/src/main/java/com/flipkart/varadhi/controller/ControllerMgr.java @@ -1,25 +1,20 @@ package com.flipkart.varadhi.controller; import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; -import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; -import com.flipkart.varadhi.core.proxies.ServerOpMgrProxy; -import com.flipkart.varadhi.entities.VaradhiSubscription; -import com.flipkart.varadhi.spi.db.MetaStore; -import io.micrometer.core.instrument.MeterRegistry; +import com.flipkart.varadhi.core.ophandlers.ControllerApi; +import com.flipkart.varadhi.core.ophandlers.WebServerApi; import java.util.concurrent.CompletableFuture; -public class ControllerMgr implements ControllerOpHandler { - private ServerOpHandler serverOpHandler; +public class ControllerMgr implements ControllerApi { + private final WebServerApi webServerApiProxy; - public ControllerMgr(ServerOpHandler serverOpHandler) { - this.serverOpHandler = serverOpHandler; + public ControllerMgr(WebServerApi webServerApiProxy) { + this.webServerApiProxy = webServerApiProxy; } @Override - public CompletableFuture StartSubscription(SubscriptionOperation operation) { + public CompletableFuture StartSubscription(SubscriptionOperation.StartData operation) { operation.markInProgress(); - serverOpHandler.update(operation); - return CompletableFuture.completedFuture(null); + return webServerApiProxy.update(operation); } } diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java index 686b8c4f..adc55de5 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/MessageChannel.java @@ -17,27 +17,22 @@ */ public interface MessageChannel { - void publish(String path, ClusterMessage msg); + void publish(String apiPath, ClusterMessage msg); - CompletableFuture send(String path, ClusterMessage msg); + CompletableFuture send(String apiPath, ClusterMessage msg); - CompletableFuture request(String path, ClusterMessage msg); + CompletableFuture request(String apiPath, ClusterMessage msg); - // void addMessageHandler(String path, MessageHandler messageHandler); - void register(String address, Class messageClazz, SendHandler handler); + void register(String basePath, Class messageClazz, SendHandler handler); - void register(String address, Class messageClazz, RequestHandler handler); + void removeMessageHandler(String apiPath); - void register(String address, Class messageClazz, PublishHandler handler); - - void removeMessageHandler(String path); - - public static enum Method { + enum Method { SEND("send"), PUBLISH("publish"), REQUEST("request"); - private String name; + private final String name; Method(String name) { this.name = name; diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java index 915482a2..64afa689 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/ClusterMessage.java @@ -1,12 +1,13 @@ package com.flipkart.varadhi.core.cluster.messages; +import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import lombok.Data; import lombok.Getter; -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@messageType") @Getter +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@messageType") +@JsonSubTypes({@JsonSubTypes.Type(value = SubscriptionMessage.class, name = "subscription_message"),}) public class ClusterMessage { String id; long timeStamp; @@ -15,4 +16,9 @@ public ClusterMessage() { this.id = java.util.UUID.randomUUID().toString(); this.timeStamp = System.currentTimeMillis(); } + + public ClusterMessage(String id, long timeStamp) { + this.id = id; + this.timeStamp = timeStamp; + } } diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java deleted file mode 100644 index 070a3273..00000000 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/PublishHandler.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.flipkart.varadhi.core.cluster.messages; - -public interface PublishHandler { - void handle(E message); -} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java deleted file mode 100644 index 12b20815..00000000 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/RequestHandler.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.flipkart.varadhi.core.cluster.messages; - -import java.util.concurrent.CompletableFuture; - -public interface RequestHandler { - CompletableFuture handle(E message); -} diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java index 4dc223bb..4858ee8a 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionMessage.java @@ -6,12 +6,15 @@ @Getter @EqualsAndHashCode(callSuper = true) public class SubscriptionMessage extends ClusterMessage { - private final String subscriptionId; - private final SubscriptionOperation operation; + private final SubscriptionOperation.OpData operation; - public SubscriptionMessage(SubscriptionOperation operation) { + public SubscriptionMessage(SubscriptionOperation.OpData operation) { super(); - this.subscriptionId = operation.getSubscriptionId(); + this.operation = operation; + } + + public SubscriptionMessage(String id, long timestamp, SubscriptionOperation.OpData operation) { + super(id, timestamp); this.operation = operation; } } diff --git a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java index eaeecf7d..8972410f 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java +++ b/core/src/main/java/com/flipkart/varadhi/core/cluster/messages/SubscriptionOperation.java @@ -1,45 +1,63 @@ package com.flipkart.varadhi.core.cluster.messages; -import com.flipkart.varadhi.entities.VaradhiSubscription; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; +import lombok.EqualsAndHashCode; import java.util.UUID; @Data public class SubscriptionOperation { - public static enum Kind { - CREATE, START, STOP, DELETE, UPDATE + public enum Kind { + START, STOP, UPDATE } - public static enum State { + public enum State { SCHEDULED, ERRORED, COMPLETED, IN_PROGRESS } - private String operationId; private Kind kind; private State state; - private String subscriptionId; private String requestedBy; - private String errorMessage; private long startTime; private long endTime; + private OpData data; - public void markInProgress() { - state = State.IN_PROGRESS; - } - - public SubscriptionMessage toMessage() { - return new SubscriptionMessage(this); - } - - public static SubscriptionOperation getSubscriptionOp(Kind opKind, String subscriptionId, String requestedBy) { + public static SubscriptionOperation startOp(String subscriptionId, String requestedBy) { SubscriptionOperation op = new SubscriptionOperation(); - op.setOperationId(UUID.randomUUID().toString()); - op.setKind(opKind); - op.setState(State.SCHEDULED); - op.setSubscriptionId(subscriptionId); + op.setKind(Kind.START); op.setRequestedBy(requestedBy); op.setStartTime(System.currentTimeMillis()); + op.data = new StartData(subscriptionId, UUID.randomUUID().toString()); return op; } + + @Data + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@opDataType") + @JsonSubTypes({@JsonSubTypes.Type(value = StartData.class, name = "startData"),}) + public static class OpData { + private String subscriptionId; + private String operationId; + private State state; + private String errorMsg; + + public void markFail(String reason) { + state = State.ERRORED; + errorMsg = reason; + } + public void markInProgress() { + state = State.IN_PROGRESS; + } + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static class StartData extends OpData { + public StartData(String subscriptionId, String operationId) { + this.setOperationId(operationId); + this.setSubscriptionId(subscriptionId); + this.setState(State.SCHEDULED); + } + } } diff --git a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerApi.java similarity index 79% rename from core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java rename to core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerApi.java index 41ed379a..948db056 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerOpHandler.java +++ b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ControllerApi.java @@ -4,6 +4,6 @@ import java.util.concurrent.CompletableFuture; -public interface ControllerOpHandler { - CompletableFuture StartSubscription(SubscriptionOperation operation); +public interface ControllerApi { + CompletableFuture StartSubscription(SubscriptionOperation.StartData operation); } diff --git a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/WebServerApi.java similarity index 51% rename from core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java rename to core/src/main/java/com/flipkart/varadhi/core/ophandlers/WebServerApi.java index b687dea9..4f2bf7a7 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/ophandlers/ServerOpHandler.java +++ b/core/src/main/java/com/flipkart/varadhi/core/ophandlers/WebServerApi.java @@ -1,10 +1,9 @@ package com.flipkart.varadhi.core.ophandlers; import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.entities.VaradhiSubscription; import java.util.concurrent.CompletableFuture; -public interface ServerOpHandler { - CompletableFuture update(SubscriptionOperation operation); +public interface WebServerApi { + CompletableFuture update(SubscriptionOperation.OpData operation); } diff --git a/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java b/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerApiProxy.java similarity index 50% rename from core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java rename to core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerApiProxy.java index 174277a3..537d7b4d 100644 --- a/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerMgrProxy.java +++ b/core/src/main/java/com/flipkart/varadhi/core/proxies/ControllerApiProxy.java @@ -3,25 +3,25 @@ import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; +import com.flipkart.varadhi.core.ophandlers.ControllerApi; import java.util.concurrent.CompletableFuture; -public class ControllerMgrProxy implements ControllerOpHandler { - private final String CONTROLLER_ADDR = "Controller"; +public class ControllerApiProxy implements ControllerApi { + private final String CONTROLLER_PATH = "controller"; private final MessageChannel channel; - public ControllerMgrProxy(MessageChannel channel) { + public ControllerApiProxy(MessageChannel channel) { this.channel = channel; } @Override - public CompletableFuture StartSubscription(SubscriptionOperation operation) { - SubscriptionMessage message = operation.toMessage(); - return channel.send(getAddress(MessageChannel.Method.SEND, message), message); + public CompletableFuture StartSubscription(SubscriptionOperation.StartData operation) { + SubscriptionMessage message = new SubscriptionMessage(operation); + return channel.send(getApiPath(MessageChannel.Method.SEND, message), message); } - private String getAddress(MessageChannel.Method method, SubscriptionMessage message) { - return CONTROLLER_ADDR + "." + message.getClass().getSimpleName() + "." + method; + private String getApiPath(MessageChannel.Method method, SubscriptionMessage message) { + return CONTROLLER_PATH + "." + message.getClass().getSimpleName() + "." + method; } } diff --git a/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java b/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java deleted file mode 100644 index ff677496..00000000 --- a/core/src/main/java/com/flipkart/varadhi/core/proxies/ServerOpMgrProxy.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.flipkart.varadhi.core.proxies; - -import com.flipkart.varadhi.core.cluster.MessageChannel; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; -import com.flipkart.varadhi.entities.VaradhiSubscription; - -import java.util.concurrent.CompletableFuture; - -public class ServerOpMgrProxy implements ServerOpHandler { - private final String SERVER_ADDR = "Server"; - private final MessageChannel channel; - - public ServerOpMgrProxy(MessageChannel channel) { - this.channel = channel; - } - @Override - public CompletableFuture update(SubscriptionOperation operation) { - SubscriptionMessage message = operation.toMessage(); - return channel.send(getAddress(MessageChannel.Method.SEND, message), message); - } - - private String getAddress(MessageChannel.Method method, SubscriptionMessage message) { - return SERVER_ADDR + "." + message.getClass().getSimpleName() + "." + method; - } -} diff --git a/core/src/main/java/com/flipkart/varadhi/core/proxies/WebServerApiProxy.java b/core/src/main/java/com/flipkart/varadhi/core/proxies/WebServerApiProxy.java new file mode 100644 index 00000000..11c82c0f --- /dev/null +++ b/core/src/main/java/com/flipkart/varadhi/core/proxies/WebServerApiProxy.java @@ -0,0 +1,25 @@ +package com.flipkart.varadhi.core.proxies; + +import com.flipkart.varadhi.core.cluster.MessageChannel; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.WebServerApi; + +import java.util.concurrent.CompletableFuture; + +public class WebServerApiProxy implements WebServerApi { + private final String SERVER_PATH = "webserver"; + private final MessageChannel channel; + + public WebServerApiProxy(MessageChannel channel) { + this.channel = channel; + } + @Override + public CompletableFuture update(SubscriptionOperation.OpData operation) { + SubscriptionMessage message = new SubscriptionMessage(operation); + return channel.send(getApiPath(MessageChannel.Method.SEND, message), message); + } + private String getApiPath(MessageChannel.Method method, SubscriptionMessage message) { + return SERVER_PATH + "." + message.getClass().getSimpleName() + "." + method; + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java b/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java deleted file mode 100644 index c31f4820..00000000 --- a/server/src/main/java/com/flipkart/varadhi/ServerOpManager.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.flipkart.varadhi; - -import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ServerOpHandler; -import com.flipkart.varadhi.entities.VaradhiSubscription; - -import java.util.concurrent.CompletableFuture; - -public class ServerOpManager implements ServerOpHandler { - @Override - public CompletableFuture update(SubscriptionOperation operation) { - // persist the operation change. - return CompletableFuture.completedFuture(null); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java index 51744b3c..3027a723 100644 --- a/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java +++ b/server/src/main/java/com/flipkart/varadhi/VaradhiApplication.java @@ -6,7 +6,7 @@ import com.flipkart.varadhi.components.Component; import com.flipkart.varadhi.components.ComponentKind; import com.flipkart.varadhi.components.controller.Controller; -import com.flipkart.varadhi.components.server.Server; +import com.flipkart.varadhi.components.webserver.WebServer; import com.flipkart.varadhi.config.AppConfiguration; import com.flipkart.varadhi.exceptions.InvalidConfigException; import com.flipkart.varadhi.utils.HostUtils; @@ -145,7 +145,7 @@ private static Map getComponents( configuration.getComponents().contains(kind) )) .collect(Collectors.toMap(Function.identity(), kind -> switch (kind) { - case Server -> new Server(configuration, coreServices); + case Server -> new WebServer(configuration, coreServices); case Controller -> new Controller(configuration, coreServices); default -> throw new IllegalArgumentException("Unknown Component Kind: " + kind); })); diff --git a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java index 6a8a31b3..2a08f7da 100644 --- a/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java +++ b/server/src/main/java/com/flipkart/varadhi/VerticleDeployer.java @@ -6,8 +6,8 @@ import com.flipkart.varadhi.core.VaradhiTopicFactory; import com.flipkart.varadhi.core.VaradhiTopicService; import com.flipkart.varadhi.core.cluster.MessageChannel; -import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; -import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; +import com.flipkart.varadhi.core.ophandlers.ControllerApi; +import com.flipkart.varadhi.core.proxies.ControllerApiProxy; import com.flipkart.varadhi.exceptions.VaradhiException; import com.flipkart.varadhi.produce.otel.ProducerMetricHandler; import com.flipkart.varadhi.produce.services.ProducerService; @@ -90,8 +90,8 @@ public VerticleDeployer( producerMetricsHandler ); this.authZHandlersSupplier = getIamPolicyHandlersSupplier(projectService, metaStore); - ControllerOpHandler controllerOpHandler = new ControllerMgrProxy(messageChannel); - SubscriptionService subscriptionService = new SubscriptionService(metaStore, controllerOpHandler); + ControllerApi controllerApi = new ControllerApiProxy(messageChannel); + SubscriptionService subscriptionService = new SubscriptionService(metaStore, controllerApi); this.subscriptionHandlers = new SubscriptionHandlers(subscriptionService, projectService); this.healthCheckHandler = new HealthCheckHandler(); diff --git a/server/src/main/java/com/flipkart/varadhi/WebServerOpManager.java b/server/src/main/java/com/flipkart/varadhi/WebServerOpManager.java new file mode 100644 index 00000000..f0a1294f --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/WebServerOpManager.java @@ -0,0 +1,14 @@ +package com.flipkart.varadhi; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.WebServerApi; + +import java.util.concurrent.CompletableFuture; + +public class WebServerOpManager implements WebServerApi { + @Override + public CompletableFuture update(SubscriptionOperation.OpData operation) { + // TODO:: persist the operation change. + return CompletableFuture.completedFuture(null); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java index 009f5d5c..cd74745f 100644 --- a/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java +++ b/server/src/main/java/com/flipkart/varadhi/cluster/MessageChannelImpl.java @@ -27,14 +27,14 @@ public MessageChannelImpl(EventBus vertxEventBus) { } @Override - public void publish(String address, ClusterMessage msg) { + public void publish(String apiPath, ClusterMessage msg) { throw new NotImplementedException("publish not implemented"); } @Override - public CompletableFuture send(String address, ClusterMessage msg) { + public CompletableFuture send(String apiPath, ClusterMessage msg) { CompletableFuture future = new CompletableFuture<>(); - vertxEventBus.request(address, JsonMapper.jsonSerialize(msg), deliveryOptions, ar -> { + vertxEventBus.request(apiPath, JsonMapper.jsonSerialize(msg), deliveryOptions, ar -> { if (ar.succeeded()) { log.info("received reply: " + ar.result().body()); future.complete(null); @@ -47,39 +47,29 @@ public CompletableFuture send(String address, ClusterMessage msg) { } @Override - public CompletableFuture request(String address, ClusterMessage msg) { + public CompletableFuture request(String apiPath, ClusterMessage msg) { throw new NotImplementedException("request not implemented"); } @Override - public void removeMessageHandler(String address) { - MessageConsumer consumer = registeredConsumers.get(address); + public void removeMessageHandler(String apiPath) { + MessageConsumer consumer = registeredConsumers.get(apiPath); if (null != consumer) { consumer.unregister(); - registeredConsumers.remove(address); + registeredConsumers.remove(apiPath); } } @Override - public void register(String address, Class messageClazz, SendHandler handler) { - String fullAddress = address + "." + messageClazz.getSimpleName() + "." + Method.SEND ; - MessageConsumer consumer = vertxEventBus.consumer(fullAddress, message -> { + public void register(String basePath, Class messageClazz, SendHandler handler) { + String apiPath = basePath + "." + messageClazz.getSimpleName() + "." + Method.SEND ; + MessageConsumer consumer = vertxEventBus.consumer(apiPath, message -> { E cm = JsonMapper.jsonDeserialize(message.body(), messageClazz); message.reply("received"); handler.handle(cm); log.info("send({}) message processed.", cm.getId()); }); // not expected to be registered multiple times. - registeredConsumers.put(fullAddress, consumer); - } - - @Override - public void register(String address, Class messageClazz, RequestHandler handler) { - throw new NotImplementedException("register RequestHandler not implemented"); - } - - @Override - public void register(String address, Class messageClazz, PublishHandler handler) { - throw new NotImplementedException("register PublishHandler not implemented"); + registeredConsumers.put(apiPath, consumer); } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/Component.java b/server/src/main/java/com/flipkart/varadhi/components/Component.java index b0e93271..72c39f3c 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/Component.java +++ b/server/src/main/java/com/flipkart/varadhi/components/Component.java @@ -1,8 +1,6 @@ package com.flipkart.varadhi.components; -import com.flipkart.varadhi.CoreServices; import com.flipkart.varadhi.cluster.ClusterManager; -import com.flipkart.varadhi.config.AppConfiguration; import io.vertx.core.Future; import io.vertx.core.Vertx; diff --git a/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java b/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java index 2ce26b66..bd3b5a02 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java +++ b/server/src/main/java/com/flipkart/varadhi/components/ComponentKind.java @@ -1,12 +1,17 @@ package com.flipkart.varadhi.components; public enum ComponentKind { - Server("server"), - Controller("controller"), - All("all"); + Server("Server"), + Controller("Controller"), + All("All"); private final String name; ComponentKind(String name) { this.name = name; } + + @Override + public String toString() { + return name; + } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java b/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java index 950db9aa..333a4084 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java +++ b/server/src/main/java/com/flipkart/varadhi/components/controller/Controller.java @@ -7,7 +7,8 @@ import com.flipkart.varadhi.controller.ControllerMgr; import com.flipkart.varadhi.core.cluster.MessageChannel; import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; -import com.flipkart.varadhi.core.proxies.ServerOpMgrProxy; +import com.flipkart.varadhi.core.ophandlers.WebServerApi; +import com.flipkart.varadhi.core.proxies.WebServerApiProxy; import io.vertx.core.Future; import io.vertx.core.Vertx; @@ -19,7 +20,7 @@ public Controller(AppConfiguration configuration, CoreServices coreServices) { @Override public Future start(Vertx vertx, ClusterManager clusterManager) { MessageChannel messageChannel = clusterManager.connect(null); - setUpMessageHandlers(messageChannel); + setupApiHandlers(messageChannel); return Future.succeededFuture(); } @@ -28,9 +29,10 @@ public Future shutdown(Vertx vertx, ClusterManager clusterManager) { return Future.succeededFuture(); } - private void setUpMessageHandlers(MessageChannel channel) { - ControllerMgr controllerMgr = new ControllerMgr(new ServerOpMgrProxy(channel)); - SubscriptionOpHandler handler = new SubscriptionOpHandler(controllerMgr, channel); + private void setupApiHandlers(MessageChannel channel) { + WebServerApi serverApi = new WebServerApiProxy(channel); + ControllerMgr controllerMgr = new ControllerMgr(serverApi); + ControllerApiHandler handler = new ControllerApiHandler(controllerMgr,serverApi); channel.register("controller", SubscriptionMessage.class, handler::start); } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/controller/ControllerApiHandler.java b/server/src/main/java/com/flipkart/varadhi/components/controller/ControllerApiHandler.java new file mode 100644 index 00000000..4d29ac87 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/controller/ControllerApiHandler.java @@ -0,0 +1,27 @@ +package com.flipkart.varadhi.components.controller; + +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; +import com.flipkart.varadhi.core.ophandlers.ControllerApi; +import com.flipkart.varadhi.core.ophandlers.WebServerApi; + +import java.util.concurrent.CompletableFuture; + +public class ControllerApiHandler { + private final ControllerApi opHandler; + private final WebServerApi webServerApiProxy; + + public ControllerApiHandler(ControllerApi opHandler, WebServerApi webServerApiProxy) { + this.opHandler = opHandler; + this.webServerApiProxy = webServerApiProxy; + } + + public CompletableFuture start(SubscriptionMessage message) { + SubscriptionOperation.StartData operation = (SubscriptionOperation.StartData) message.getOperation(); + return opHandler.StartSubscription(operation).exceptionally(throwable -> { + operation.markFail(throwable.getMessage()); + webServerApiProxy.update(operation); + return null; + }); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java b/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java deleted file mode 100644 index 0dee6f50..00000000 --- a/server/src/main/java/com/flipkart/varadhi/components/controller/SubscriptionOpHandler.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.flipkart.varadhi.components.controller; - -import com.flipkart.varadhi.core.cluster.MessageChannel; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; - -import java.util.concurrent.CompletableFuture; - -public class SubscriptionOpHandler { - private final ControllerOpHandler opHandler; - private final MessageChannel channel; - - public SubscriptionOpHandler(ControllerOpHandler opHandler, MessageChannel channel) { - this.opHandler = opHandler; - this.channel = channel; - } - - public CompletableFuture start(SubscriptionMessage message) { - // TODO::it is not async - SubscriptionOperation operation = message.getOperation(); - if (operation.getKind() != SubscriptionOperation.Kind.START) { - throw new IllegalArgumentException("Invalid operation type"); - } - opHandler.StartSubscription(operation).exceptionally(throwable -> { - operation.setErrorMessage(throwable.getMessage()); - operation.setState(SubscriptionOperation.State.ERRORED); - channel.send("Server", operation.toMessage()); - return null; - }); - // send the update to the server. - return CompletableFuture.completedFuture(null); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java b/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java deleted file mode 100644 index eb47d6af..00000000 --- a/server/src/main/java/com/flipkart/varadhi/components/server/ServerOperationHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.flipkart.varadhi.components.server; - -import com.flipkart.varadhi.ServerOpManager; -import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; -import com.flipkart.varadhi.spi.db.MetaStore; - -import java.util.concurrent.CompletableFuture; - -public class ServerOperationHandler { - private MetaStore metaStore; - private ServerOpManager serverOpMgr; - - public ServerOperationHandler(ServerOpManager serverOpMgr, MetaStore metaStore) { - this.serverOpMgr = serverOpMgr; - this.metaStore = metaStore; - } - - public CompletableFuture update(SubscriptionMessage message) { - return serverOpMgr.update(null); - } -} diff --git a/server/src/main/java/com/flipkart/varadhi/components/server/Server.java b/server/src/main/java/com/flipkart/varadhi/components/webserver/WebServer.java similarity index 85% rename from server/src/main/java/com/flipkart/varadhi/components/server/Server.java rename to server/src/main/java/com/flipkart/varadhi/components/webserver/WebServer.java index 393ddbc9..c97e2385 100644 --- a/server/src/main/java/com/flipkart/varadhi/components/server/Server.java +++ b/server/src/main/java/com/flipkart/varadhi/components/webserver/WebServer.java @@ -1,7 +1,7 @@ -package com.flipkart.varadhi.components.server; +package com.flipkart.varadhi.components.webserver; import com.flipkart.varadhi.CoreServices; -import com.flipkart.varadhi.ServerOpManager; +import com.flipkart.varadhi.WebServerOpManager; import com.flipkart.varadhi.VerticleDeployer; import com.flipkart.varadhi.cluster.ClusterManager; import com.flipkart.varadhi.components.Component; @@ -16,23 +16,22 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class Server implements Component { +public class WebServer implements Component { private final AppConfiguration configuration; private final CoreServices coreServices; private String verticleId; - private ServerOperationHandler handler; + private final WebServerApiHandler handler; - public Server(AppConfiguration configuration, CoreServices coreServices) { + public WebServer(AppConfiguration configuration, CoreServices coreServices) { this.configuration = configuration; this.coreServices = coreServices; - this.handler = - new ServerOperationHandler(new ServerOpManager(), coreServices.getMetaStoreProvider().getMetaStore()); + this.handler = new WebServerApiHandler(new WebServerOpManager()); } @Override public Future start(Vertx vertx, ClusterManager clusterManager) { MessageChannel messageChannel = clusterManager.connect(null); - setupMessageHandlers(messageChannel); + setupApiHandlers(messageChannel); return deployVerticle(vertx, messageChannel); } @@ -97,8 +96,8 @@ private VerticleDeployer createVerticleDeployer(Vertx vertx, MessageChannel mess } return verticleDeployer; } - public void setupMessageHandlers(MessageChannel messageChannel) { - messageChannel.register("Server", SubscriptionMessage.class, handler::update); + public void setupApiHandlers(MessageChannel messageChannel) { + messageChannel.register("webserver", SubscriptionMessage.class, handler::update); } } diff --git a/server/src/main/java/com/flipkart/varadhi/components/webserver/WebServerApiHandler.java b/server/src/main/java/com/flipkart/varadhi/components/webserver/WebServerApiHandler.java new file mode 100644 index 00000000..6a9b7840 --- /dev/null +++ b/server/src/main/java/com/flipkart/varadhi/components/webserver/WebServerApiHandler.java @@ -0,0 +1,18 @@ +package com.flipkart.varadhi.components.webserver; + +import com.flipkart.varadhi.WebServerOpManager; +import com.flipkart.varadhi.core.cluster.messages.SubscriptionMessage; + +import java.util.concurrent.CompletableFuture; + +public class WebServerApiHandler { + private final WebServerOpManager serverOpMgr; + + public WebServerApiHandler(WebServerOpManager serverOpMgr) { + this.serverOpMgr = serverOpMgr; + } + + public CompletableFuture update(SubscriptionMessage message) { + return serverOpMgr.update(message.getOperation()); + } +} diff --git a/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java b/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java index b80fde59..e23bd4e9 100644 --- a/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java +++ b/server/src/main/java/com/flipkart/varadhi/services/SubscriptionService.java @@ -2,8 +2,7 @@ import com.flipkart.varadhi.core.cluster.messages.SubscriptionOperation; -import com.flipkart.varadhi.core.ophandlers.ControllerOpHandler; -import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; +import com.flipkart.varadhi.core.ophandlers.ControllerApi; import com.flipkart.varadhi.entities.VaradhiSubscription; import com.flipkart.varadhi.entities.VaradhiTopic; import com.flipkart.varadhi.exceptions.InvalidOperationForResourceException; @@ -16,11 +15,11 @@ public class SubscriptionService { private final MetaStore metaStore; - private final ControllerOpHandler controllerOpHandler; + private final ControllerApi controllerApi; - public SubscriptionService(MetaStore metaStore, ControllerOpHandler controllerOpHandler) { + public SubscriptionService(MetaStore metaStore, ControllerApi controllerApi) { this.metaStore = metaStore; - this.controllerOpHandler = controllerOpHandler; + this.controllerApi = controllerApi; } public List getSubscriptionList(String projectName) { @@ -38,9 +37,9 @@ public VaradhiSubscription createSubscription(VaradhiSubscription subscription) return subscription; } - public void start(String subscriptionName){ - SubscriptionOperation op = SubscriptionOperation.getSubscriptionOp(SubscriptionOperation.Kind.START, subscriptionName, ""); - controllerOpHandler.StartSubscription(op); + public void start(String subscriptionName, String requestedBy){ + SubscriptionOperation op = SubscriptionOperation.startOp(subscriptionName, requestedBy); + controllerApi.StartSubscription((SubscriptionOperation.StartData) op.getData()); } private void validateCreation(VaradhiSubscription subscription) { diff --git a/server/src/main/java/com/flipkart/varadhi/utils/SubscriptionHelper.java b/server/src/main/java/com/flipkart/varadhi/utils/SubscriptionHelper.java index 6785f70a..32377f09 100644 --- a/server/src/main/java/com/flipkart/varadhi/utils/SubscriptionHelper.java +++ b/server/src/main/java/com/flipkart/varadhi/utils/SubscriptionHelper.java @@ -4,7 +4,10 @@ import com.flipkart.varadhi.entities.SubscriptionResource; import com.flipkart.varadhi.entities.SubscriptionShards; import com.flipkart.varadhi.entities.VaradhiSubscription; +import io.vertx.ext.web.RoutingContext; +import static com.flipkart.varadhi.Constants.PathParams.PATH_PARAM_PROJECT; +import static com.flipkart.varadhi.Constants.PathParams.PATH_PARAM_SUBSCRIPTION; import static com.flipkart.varadhi.entities.VersionedEntity.NAME_SEPARATOR; import static com.flipkart.varadhi.entities.VersionedEntity.NAME_SEPARATOR_REGEX; @@ -56,6 +59,12 @@ public static String buildSubscriptionName(String projectName, String subscripti return String.join(NAME_SEPARATOR, projectName, subscriptionName); } + public static String buildSubscriptionName(RoutingContext ctx) { + String projectName = ctx.pathParam(PATH_PARAM_PROJECT); + String subscriptionName = ctx.pathParam(PATH_PARAM_SUBSCRIPTION); + return SubscriptionHelper.buildSubscriptionName(projectName, subscriptionName); + } + public static String buildTopicName(String projectName, String topicName) { return String.join(NAME_SEPARATOR, projectName, topicName); } diff --git a/server/src/main/java/com/flipkart/varadhi/web/Extensions.java b/server/src/main/java/com/flipkart/varadhi/web/Extensions.java index 65d6dbce..cf28c0f6 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/Extensions.java +++ b/server/src/main/java/com/flipkart/varadhi/web/Extensions.java @@ -6,10 +6,13 @@ import io.netty.handler.codec.http.HttpHeaderValues; import io.vertx.core.http.HttpHeaders; import io.vertx.core.http.HttpServerRequest; +import io.vertx.ext.auth.User; import io.vertx.ext.web.RequestBody; import io.vertx.ext.web.RoutingContext; import lombok.extern.slf4j.Slf4j; +import static com.flipkart.varadhi.MessageConstants.ANONYMOUS_IDENTITY; + public class Extensions { @@ -99,5 +102,12 @@ public static T getApiResponse(RoutingContext ctx) { public static void todo(RoutingContext context) { throw new NotImplementedException("Not Implemented."); } + + public static String getIdentityOrDefault(RoutingContext ctx) { + User user = ctx.user(); + return null != user ? user.subject() : ANONYMOUS_IDENTITY; + } + + } } diff --git a/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java b/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java index 64c40ab3..df107f96 100644 --- a/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java +++ b/server/src/main/java/com/flipkart/varadhi/web/v1/admin/SubscriptionHandlers.java @@ -1,6 +1,5 @@ package com.flipkart.varadhi.web.v1.admin; -import com.flipkart.varadhi.core.proxies.ControllerMgrProxy; import com.flipkart.varadhi.entities.*; import com.flipkart.varadhi.services.ProjectService; import com.flipkart.varadhi.services.SubscriptionService; @@ -100,9 +99,7 @@ public void list(RoutingContext ctx) { } public void get(RoutingContext ctx) { - String projectName = ctx.pathParam(PATH_PARAM_PROJECT); - String subscriptionName = ctx.pathParam(PATH_PARAM_SUBSCRIPTION); - String internalSubscriptionName = SubscriptionHelper.buildSubscriptionName(projectName, subscriptionName); + String internalSubscriptionName = SubscriptionHelper.buildSubscriptionName(ctx); SubscriptionResource subscription = SubscriptionHelper.toResource(subscriptionService.getSubscription(internalSubscriptionName)); ctx.endApiWithResponse(subscription); @@ -124,15 +121,12 @@ public void update(RoutingContext ctx) { } public void delete(RoutingContext ctx) { - String projectName = ctx.pathParam(PATH_PARAM_PROJECT); - String subscriptionName = ctx.pathParam(PATH_PARAM_SUBSCRIPTION); - String internalSubscriptionName = SubscriptionHelper.buildSubscriptionName(projectName, subscriptionName); - subscriptionService.deleteSubscription(internalSubscriptionName); + subscriptionService.deleteSubscription(SubscriptionHelper.buildSubscriptionName(ctx)); ctx.endApi(); } public void start(RoutingContext ctx) { - ctx.todo(); + subscriptionService.start(SubscriptionHelper.buildSubscriptionName(ctx), ctx.getIdentityOrDefault()); } public void stop(RoutingContext ctx) { diff --git a/server/src/main/resources/configuration.yml b/server/src/main/resources/configuration.yml index 197f26f9..b988de1b 100755 --- a/server/src/main/resources/configuration.yml +++ b/server/src/main/resources/configuration.yml @@ -1,5 +1,5 @@ -components : ["server", "controller", "all"] +components : ["Server", "Controller", "All"] restOptions: deployedRegion: "default" diff --git a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java index d3cb5c2e..3f4944e2 100644 --- a/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java +++ b/server/src/test/java/com/flipkart/varadhi/cluster/MessageChannelImplTest.java @@ -64,9 +64,8 @@ public void testSendMessageConsumerCollocated(VertxTestContext testContext) thro MessageChannelImpl c = new MessageChannelImpl(vertx.eventBus()); c.register("testAddress", ExtendedTestClusterMessage.class, new SendHandler<>() { @Override - public CompletableFuture handle(ExtendedTestClusterMessage message) { + public void handle(ExtendedTestClusterMessage message) { checkpoint.flag(); - return CompletableFuture.completedFuture(null); } }); diff --git a/server/src/test/resources/testConfiguration.yml b/server/src/test/resources/testConfiguration.yml index 5228c884..63cc5589 100644 --- a/server/src/test/resources/testConfiguration.yml +++ b/server/src/test/resources/testConfiguration.yml @@ -1,4 +1,4 @@ -components : ["server"] +components : ["Server"] restOptions: deployedRegion: "test" From 1f43d2e1d4d013322ec8b4fec42e9fd091a30467 Mon Sep 17 00:00:00 2001 From: Dhruv Kumar Date: Tue, 19 Mar 2024 22:19:42 +0530 Subject: [PATCH 8/8] avoid http port conflict in for server deployment in UTs --- server/src/test/resources/testConfiguration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/resources/testConfiguration.yml b/server/src/test/resources/testConfiguration.yml index 63cc5589..bd1e7643 100644 --- a/server/src/test/resources/testConfiguration.yml +++ b/server/src/test/resources/testConfiguration.yml @@ -46,7 +46,7 @@ metaStoreOptions: configFile: "src/main/resources/zkConfig.yml" httpServerOptions: - port: 8080 + port: 8091 alpnVersions: [ "HTTP_1_1", "HTTP_2" ] decompressionSupported: false useAlpn: true