This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch AIRAVATA-3981/integration-health-check
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 12deed3ee683834400f99c8ab693274fe38a0ee4
Author: yasithdev <[email protected]>
AuthorDate: Thu Mar 26 15:33:56 2026 -0500

    feat: add Database, RabbitMQ, and Kafka integration health tests
---
 .../airavata/integration/DatabaseHealthTest.java   | 85 ++++++++++++++++++++++
 .../airavata/integration/KafkaHealthTest.java      | 58 +++++++++++++++
 .../airavata/integration/RabbitMQHealthTest.java   | 74 +++++++++++++++++++
 3 files changed, 217 insertions(+)

diff --git 
a/integration-tests/src/test/java/org/apache/airavata/integration/DatabaseHealthTest.java
 
b/integration-tests/src/test/java/org/apache/airavata/integration/DatabaseHealthTest.java
new file mode 100644
index 0000000000..ce9fd48f8c
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/airavata/integration/DatabaseHealthTest.java
@@ -0,0 +1,85 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.integration;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Verifies JDBC connectivity to the Airavata database and the presence of
+ * core tables required for experiment and resource management.
+ */
+@Tag("integration")
+class DatabaseHealthTest {
+
+    private static final String HOST =
+            System.getProperty("airavata.db.host", "localhost");
+    private static final int PORT =
+            Integer.parseInt(System.getProperty("airavata.db.port", "13306"));
+    private static final String DATABASE =
+            System.getProperty("airavata.db.name", "airavata");
+    private static final String USER =
+            System.getProperty("airavata.db.user", "airavata");
+    private static final String PASSWORD =
+            System.getProperty("airavata.db.password", "123456");
+
+    private static final String JDBC_URL =
+            "jdbc:mariadb://" + HOST + ":" + PORT + "/" + DATABASE;
+
+    static Stream<String> requiredTables() {
+        return Stream.of(
+                "EXPERIMENT",
+                "APPLICATION_DEPLOYMENT",
+                "COMPUTE_RESOURCE",
+                "GATEWAY",
+                "USER_PROFILE",
+                "SHARING_ENTITY",
+                "CREDENTIAL");
+    }
+
+    @ParameterizedTest(name = "table {0} exists")
+    @MethodSource("requiredTables")
+    void requiredTableShouldExist(String tableName) throws Exception {
+        try (Connection connection = DriverManager.getConnection(JDBC_URL, 
USER, PASSWORD)) {
+            assertTrue(connection.isValid(5), "Database connection is not 
valid");
+
+            DatabaseMetaData meta = connection.getMetaData();
+            List<String> found = new ArrayList<>();
+            try (ResultSet rs = meta.getTables(DATABASE, null, tableName, new 
String[]{"TABLE"})) {
+                while (rs.next()) {
+                    found.add(rs.getString("TABLE_NAME"));
+                }
+            }
+            assertTrue(
+                    found.stream().anyMatch(t -> 
t.equalsIgnoreCase(tableName)),
+                    "Expected table '" + tableName + "' was not found in 
database '" + DATABASE + "'");
+        }
+    }
+}
diff --git 
a/integration-tests/src/test/java/org/apache/airavata/integration/KafkaHealthTest.java
 
b/integration-tests/src/test/java/org/apache/airavata/integration/KafkaHealthTest.java
new file mode 100644
index 0000000000..45b0f800de
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/airavata/integration/KafkaHealthTest.java
@@ -0,0 +1,58 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.integration;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+import org.apache.kafka.clients.admin.AdminClient;
+import org.apache.kafka.clients.admin.AdminClientConfig;
+import org.apache.kafka.clients.admin.DescribeClusterResult;
+import org.apache.kafka.common.Node;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Verifies that the Kafka cluster is reachable and has at least one broker 
node.
+ */
+@Tag("integration")
+class KafkaHealthTest {
+
+    private static final String BOOTSTRAP_SERVERS =
+            System.getProperty("airavata.kafka.bootstrap.servers", 
"localhost:9092");
+
+    @Test
+    void kafkaClusterShouldHaveAtLeastOneBroker() throws ExecutionException, 
InterruptedException {
+        Properties config = new Properties();
+        config.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, 
BOOTSTRAP_SERVERS);
+        config.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, "10000");
+        config.put(AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, "10000");
+
+        try (AdminClient adminClient = AdminClient.create(config)) {
+            DescribeClusterResult result = adminClient.describeCluster();
+            Collection<Node> nodes = result.nodes().get();
+
+            assertFalse(nodes.isEmpty(), "Kafka cluster reported no broker 
nodes");
+        }
+    }
+}
diff --git 
a/integration-tests/src/test/java/org/apache/airavata/integration/RabbitMQHealthTest.java
 
b/integration-tests/src/test/java/org/apache/airavata/integration/RabbitMQHealthTest.java
new file mode 100644
index 0000000000..597e61d159
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/airavata/integration/RabbitMQHealthTest.java
@@ -0,0 +1,74 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.airavata.integration;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Verifies AMQP connectivity to RabbitMQ and that the core Airavata exchanges
+ * are already declared (passive declare — does not create them).
+ */
+@Tag("integration")
+class RabbitMQHealthTest {
+
+    private static final String HOST =
+            System.getProperty("airavata.rabbitmq.host", "localhost");
+    private static final int PORT =
+            Integer.parseInt(System.getProperty("airavata.rabbitmq.port", 
"5672"));
+    private static final String USERNAME =
+            System.getProperty("airavata.rabbitmq.username", "airavata");
+    private static final String PASSWORD =
+            System.getProperty("airavata.rabbitmq.password", "airavata");
+    private static final String VHOST =
+            System.getProperty("airavata.rabbitmq.vhost", "/");
+
+    static Stream<String> exchanges() {
+        return Stream.of(
+                "experiment_exchange",
+                "process_exchange",
+                "status_exchange");
+    }
+
+    @ParameterizedTest(name = "exchange {0} is declared")
+    @MethodSource("exchanges")
+    void exchangeShouldBeDeclared(String exchangeName) throws Exception {
+        ConnectionFactory factory = new ConnectionFactory();
+        factory.setHost(HOST);
+        factory.setPort(PORT);
+        factory.setUsername(USERNAME);
+        factory.setPassword(PASSWORD);
+        factory.setVirtualHost(VHOST);
+
+        try (Connection connection = factory.newConnection();
+             Channel channel = connection.createChannel()) {
+            assertDoesNotThrow(
+                    () -> channel.exchangeDeclarePassive(exchangeName),
+                    "Exchange '" + exchangeName + "' is not declared in 
RabbitMQ");
+        }
+    }
+}

Reply via email to