diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52172ec..c80f8fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,5 +47,8 @@ jobs: - name: Build with Maven run: mvn -B clean verify -Dno-format + - name: Ignoring modules that do not support native-compilation + run: sed -i -e '/couchbase\-parent<\/module>/d' keyvalue-parent/pom.xml + - name: Build with Maven (Native) run: mvn -B verify -Dnative -Dquarkus.native.container-build -Dnative.surefire.skip diff --git a/README.md b/README.md index 961170d..cc1a372 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ # Quarkus JNoSQL + [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) [![Version](https://img.shields.io/maven-central/v/io.quarkiverse.jnosql/quarkus-jnosql-core?logo=apache-maven&style=flat-square)](https://search.maven.org/artifact/io.quarkiverse.jnosql/quarkus-jnosql-core) -The Quarkus JNoSql Extension adds support for +The Quarkus JNoSql Extension adds support for [JNoSQL](http://www.jnosql.org/), an implementation of [Jakarta NoSQL](https://jakarta.ee/specifications/nosql/). :information_source: **Recommended Quarkus version: `3.2.2.Final` or higher** -### Usage +### Jakarta NoSQL Entity Mapping Sample ```java import jakarta.nosql.Column; @@ -19,10 +20,10 @@ import jakarta.nosql.Id; @Entity public class TestEntity { - + @Id private String id; - + @Column private String testField; } @@ -30,13 +31,13 @@ public class TestEntity { ## KeyValue -### Configuration +### Required Configuration The JNoSql KeyValue Quarkus extension supports the following configuration: - | Name | Type | Default | - |---|---|---| - | `jnosql.keyvalue.database`
The database's name. | string | | +| Name | Description | Type | Default | +|----------------------------|---------------------|--------|---------| +| `jnosql.keyvalue.database` | The database's name | string | | ### Usage @@ -44,9 +45,9 @@ The JNoSql KeyValue Quarkus extension supports the following configuration: @Inject private KeyValueTemplate template; -public void insert(TestEntity entity) { - template.insert(entity); -} +public void insert(TestEntity entity){ + template.insert(entity); + } ``` ### ArangoDB @@ -54,26 +55,31 @@ public void insert(TestEntity entity) { Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-keyvalue-arangodb ``` -Please refer to the [AranboDB JNoSQL driver](https://github.com/eclipse/jnosql-databases#arangodb) for specific configuration. +Please refer to the [AranboDB JNoSQL driver](https://github.com/eclipse/jnosql-databases#arangodb) for specific +configuration. ### DynamoDB Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-keyvalue-dynamodb ``` -Please refer to the [DynamoDB Quarkiverse extension](https://quarkiverse.github.io/quarkiverse-docs/quarkus-amazon-services/dev/amazon-dynamodb.html) for specific configuration. +Please refer to +the [DynamoDB Quarkiverse extension](https://quarkiverse.github.io/quarkiverse-docs/quarkus-amazon-services/dev/amazon-dynamodb.html) +for specific configuration. ### Hazelcast @@ -93,6 +99,7 @@ Please refer to the [Quarkus Hazelcast extension](https://github.com/hazelcast/q Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-keyvalue-redis @@ -101,15 +108,43 @@ Add the dependency to the target project: Please refer to the [Redis Quarkus extension](https://quarkus.io/guides/redis-reference) for specific configuration. +### Couchbase + +Add the dependency to the target project: + +:warning: **This extension doesn't support native-compilation** + +```xml + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase + +``` + +#### Required Configuration + +This JNoSql KeyValue Quarkus extension for Couchbase supports the following configuration: + +| Name | Description | Type | Default | +|-----------------------------|-----------------------|--------|---------| +| `jnosql.couchbase.host` | the connection string | string | | +| `jnosql.couchbase.user` | The username [^0] | string | | +| `jnosql.couchbase.password` | The password [^0] | string | | +| `jnosql.couchbase.password` | The password [^0] | string | | + +[^0]: Pay attention to the way the sensitive variables are stored in order to avoid data leakage and security flaws. + +Please, take a look at the [Eclipse JNoSQL Database API for Couchbase documentation](https://github.com/eclipse/jnosql-databases#configuration-2) to learn more about all supported properties. + ## Document ### Configuration The JNoSql Document Quarkus extension supports the following configuration: - | Name | Type | Default | - |---|---|---| - | `jnosql.document.database`
The database's name. | string | | +| Name | Type | Default | + |----------------------------------------------------|--------|---------| +| `jnosql.document.database`
The database's name. | string | | ### Usage @@ -117,9 +152,9 @@ The JNoSql Document Quarkus extension supports the following configuration: @Inject private DocumentTemplate template; -public void insert(TestDocumentEntity entity) { - template.insert(entity); -} +public void insert(TestDocumentEntity entity){ + template.insert(entity); + } ``` ### ArangoDB @@ -127,13 +162,15 @@ public void insert(TestDocumentEntity entity) { Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-document-arangodb ``` -Please refer to the [AranboDB JNoSQL driver](https://github.com/eclipse/jnosql-databases#arangodb) for specific configuration. +Please refer to the [AranboDB JNoSQL driver](https://github.com/eclipse/jnosql-databases#arangodb) for specific +configuration. ### CouchDB @@ -153,19 +190,23 @@ Please refer to the [CouchDB JNoSQL driver](https://github.com/eclipse/jnosql-da Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-document-elasticsearch ``` -Please refer to the [Elasticsearch Quarkus extension](https://quarkus.io/guides/elasticsearch#using-the-elasticsearch-java-client) for specific configuration. +Please refer to +the [Elasticsearch Quarkus extension](https://quarkus.io/guides/elasticsearch#using-the-elasticsearch-java-client) for +specific configuration. ### MongoDB Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-document-mongodb @@ -193,15 +234,16 @@ Please refer to the [Solr JNoSQL driver](https://github.com/eclipse/jnosql-datab The JNoSql Column Quarkus extension supports the following configuration: -| Name | Type | Default | - |--------------------------------------------------|---|---| -| `jnosql.column.database`
The database's name. | string | | +| Name | Type | Default | + |--------------------------------------------------|--------|---------| +| `jnosql.column.database`
The database's name. | string | | ### Cassandra Add the dependency to the target project: ```xml + io.quarkiverse.jnosql quarkus-jnosql-column-cassandra @@ -230,4 +272,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. +Contributions of any kind welcome! + diff --git a/core-parent/runtime/src/main/java/io/quarkiverse/jnosql/core/runtime/JvmOnlyRecorder.java b/core-parent/runtime/src/main/java/io/quarkiverse/jnosql/core/runtime/JvmOnlyRecorder.java new file mode 100644 index 0000000..f962f66 --- /dev/null +++ b/core-parent/runtime/src/main/java/io/quarkiverse/jnosql/core/runtime/JvmOnlyRecorder.java @@ -0,0 +1,24 @@ +package io.quarkiverse.jnosql.core.runtime; + +import org.jboss.logging.Logger; + +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class JvmOnlyRecorder { + + private static final Logger LOG = Logger.getLogger(JvmOnlyRecorder.class); + + public JvmOnlyRecorder() { + } + + public static void warnJvmInNative(Logger log, String feature) { + log.warnf( + "The %s extension was not tested in native mode. You may want to report about the success or failure running it in native mode on https://github.com/quarkiverse/quarkus-jnosql/issues?q=is:issue+%s", + feature, feature.replace('-', '+')); + } + + public void warnJvmInNative(String feature) { + warnJvmInNative(LOG, feature); + } +} diff --git a/keyvalue-parent/couchbase-parent/deployment/pom.xml b/keyvalue-parent/couchbase-parent/deployment/pom.xml new file mode 100644 index 0000000..f53e208 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/deployment/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase-parent + 3.2.2.0 + + quarkus-jnosql-keyvalue-couchbase-deployment + Quarkus JNoSQL - KeyValue - Couchbase - Deployment + + + io.quarkiverse.jnosql + quarkus-jnosql-core-deployment + ${project.version} + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-deployment + ${project.version} + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase + ${project.version} + + + io.quarkus + quarkus-junit5-internal + test + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/keyvalue-parent/couchbase-parent/deployment/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/deployment/Processor.java b/keyvalue-parent/couchbase-parent/deployment/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/deployment/Processor.java new file mode 100644 index 0000000..5202620 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/deployment/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/deployment/Processor.java @@ -0,0 +1,41 @@ +package io.quarkiverse.jnosql.keyvalue.couchbase.deployment; + +import org.eclipse.jnosql.databases.couchbase.communication.QuarkusCouchbaseKeyValueConfiguration; +import org.jboss.logging.Logger; + +import io.quarkiverse.jnosql.core.runtime.JvmOnlyRecorder; +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.pkg.steps.NativeBuild; + +class Processor { + + private static final Logger LOG = Logger.getLogger(Processor.class); + + private static final String FEATURE = "jnosql-keyvalue-couchbase"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + + /** + * Remove this once this extension starts supporting the native mode. + */ + @BuildStep(onlyIf = NativeBuild.class) + @Record(value = ExecutionTime.RUNTIME_INIT) + void warnJvmInNative(JvmOnlyRecorder recorder) { + JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time + recorder.warnJvmInNative(FEATURE); // warn at runtime + } + + @BuildStep + void build(BuildProducer additionalBeanProducer) { + additionalBeanProducer.produce(AdditionalBeanBuildItem.unremovableOf(QuarkusCouchbaseKeyValueConfiguration.class)); + } + +} diff --git a/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLDevModeTest.java b/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLDevModeTest.java new file mode 100644 index 0000000..70a8d43 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLDevModeTest.java @@ -0,0 +1,23 @@ +package io.quarkiverse.jnosql.document.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusDevModeTest; + +public class JNoSQLDevModeTest { + + // Start hot reload (DevMode) test with your extension loaded + @RegisterExtension + static final QuarkusDevModeTest devModeTest = new QuarkusDevModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)); + + @Test + public void writeYourOwnDevModeTest() { + // Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information + Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName()); + } +} diff --git a/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLTest.java b/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLTest.java new file mode 100644 index 0000000..cb7cfec --- /dev/null +++ b/keyvalue-parent/couchbase-parent/deployment/src/test/java/io/quarkiverse/jnosql/document/test/JNoSQLTest.java @@ -0,0 +1,23 @@ +package io.quarkiverse.jnosql.document.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class JNoSQLTest { + + // Start unit test with your extension loaded + @RegisterExtension + static final QuarkusUnitTest unitTest = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)); + + @Test + public void writeYourOwnUnitTest() { + // Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information + Assertions.assertTrue(true, "Add some assertions to " + getClass().getName()); + } +} diff --git a/keyvalue-parent/couchbase-parent/integration-tests/pom.xml b/keyvalue-parent/couchbase-parent/integration-tests/pom.xml new file mode 100644 index 0000000..8014ff6 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/pom.xml @@ -0,0 +1,120 @@ + + + 4.0.0 + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase-parent + 3.2.2.0 + + quarkus-jnosql-keyvalue-couchbase-integration-tests + Quarkus JNoSQL - KeyValue - Couchbase - Integration Tests + + 1.18.3 + true + + + + io.quarkus + quarkus-resteasy + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-integration-tests + ${project.version} + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase + ${project.version} + + + io.quarkus + quarkus-junit5 + test + + + org.awaitility + awaitility + test + + + io.rest-assured + rest-assured + test + + + org.testcontainers + couchbase + ${testcontainers.version} + test + + + junit + junit + + + + + io.quarkus + quarkus-junit4-mock + test + + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + native-image + + + native + + + + + + maven-surefire-plugin + + ${native.surefire.skip} + + + + + + false + native + + + + diff --git a/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResource.java b/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResource.java new file mode 100644 index 0000000..9ffd755 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResource.java @@ -0,0 +1,28 @@ +/* +* 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 io.quarkiverse.jnosql.keyvalue.couchbase.it; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.nosql.keyvalue.KeyValueTemplate; +import jakarta.ws.rs.Path; + +import io.quarkiverse.jnosql.keyvalue.it.AbstractJNoSQLKeyValueResource; + +@Path("/jnosql") +@ApplicationScoped +public class JNoSQLResource extends AbstractJNoSQLKeyValueResource { +} diff --git a/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/Person.java b/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/Person.java new file mode 100644 index 0000000..6cf1259 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/src/main/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/Person.java @@ -0,0 +1,45 @@ +package io.quarkiverse.jnosql.keyvalue.couchbase.it; + +import java.util.List; + +import jakarta.nosql.Column; +import jakarta.nosql.Entity; +import jakarta.nosql.Id; + +@Entity +public class Person { + + @Id + private String id; + + @Column + private String name; + + @Column + private List phones; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getPhones() { + return phones; + } + + public void setPhones(List phones) { + this.phones = phones; + } + +} diff --git a/keyvalue-parent/couchbase-parent/integration-tests/src/main/resources/application.properties b/keyvalue-parent/couchbase-parent/integration-tests/src/main/resources/application.properties new file mode 100644 index 0000000..175f363 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/src/main/resources/application.properties @@ -0,0 +1,3 @@ +jnosql.keyvalue.database=test +jnosql.couchbase.collections=Person +jnosql.couchbase.index=Person \ No newline at end of file diff --git a/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/CouchbaseTestResource.java b/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/CouchbaseTestResource.java new file mode 100644 index 0000000..f184376 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/CouchbaseTestResource.java @@ -0,0 +1,188 @@ +package io.quarkiverse.jnosql.keyvalue.couchbase.it; + +import static com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions; +import static com.couchbase.client.java.manager.query.GetAllQueryIndexesOptions.getAllQueryIndexesOptions; + +import java.time.Duration; +import java.util.*; + +import jakarta.data.exceptions.MappingException; + +import org.eclipse.jnosql.communication.Settings; +import org.eclipse.jnosql.databases.couchbase.communication.*; +import org.eclipse.jnosql.mapping.config.MappingConfigurations; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.couchbase.BucketDefinition; +import org.testcontainers.couchbase.CouchbaseContainer; +import org.testcontainers.shaded.org.awaitility.Awaitility; +import org.testcontainers.utility.TestcontainersConfiguration; + +import com.couchbase.client.core.error.BucketNotFoundException; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.manager.bucket.BucketManager; +import com.couchbase.client.java.manager.bucket.BucketSettings; +import com.couchbase.client.java.manager.collection.CollectionManager; +import com.couchbase.client.java.manager.collection.CollectionSpec; +import com.couchbase.client.java.manager.collection.ScopeSpec; +import com.couchbase.client.java.manager.query.QueryIndex; +import com.couchbase.client.java.manager.query.QueryIndexManager; + +import io.quarkiverse.jnosql.core.runtime.MicroProfileSettings; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class CouchbaseTestResource extends CouchbaseConfiguration implements QuarkusTestResourceLifecycleManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(CouchbaseTestResource.class); + + private static final String CONTAINER_IMAGE = "couchbase/server"; + private static final String COUCHDB_BUCKET_NAME = "quarkus"; + + private CouchbaseContainer container; + + private final Settings settings = new MicroProfileSettings(); + + @Override + public Map start() { + LOGGER.info(TestcontainersConfiguration.getInstance().toString()); + + update(settings); + + var bucketName = settings + .get(MappingConfigurations.KEY_VALUE_DATABASE.get(), String.class) + .orElse(COUCHDB_BUCKET_NAME); + + BucketDefinition bucketDefinition = new BucketDefinition(bucketName); + + container = new CouchbaseContainer(CONTAINER_IMAGE) + .withBucket(bucketDefinition); + + container.start(); + + setHost(container.getConnectionString()); + setUser(container.getUsername()); + setPassword(container.getPassword()); + + var couchbaseSettings = toCouchbaseSettings(); + + LOGGER.info(couchbaseSettings.toString()); + + setupCluster(couchbaseSettings, bucketName); + + Map config = new HashMap<>(Map.of( + MappingConfigurations.KEY_VALUE_DATABASE.get(), bucketName, + CouchbaseConfigurations.HOST.get(), container.getConnectionString(), + CouchbaseConfigurations.USER.get(), container.getUsername(), + CouchbaseConfigurations.PASSWORD.get(), container.getPassword(), + CouchbaseConfigurations.COLLECTIONS.get(), String.join(",", couchbaseSettings.getCollections()))); + + Optional.ofNullable(couchbaseSettings.getIndex()) + .ifPresent(index -> config.put(CouchbaseConfigurations.INDEX.get(), index)); + + return config; + + } + + @Override + protected void update(Settings settings) { + validateCouchbaseSettings(settings); + super.update(settings); + } + + private void validateCouchbaseSettings(Settings settings) { + List.of( + CouchbaseConfigurations.INDEX).forEach( + setting -> settings.get(setting, String.class) + .orElseThrow(() -> new MappingException("Please, inform the database filling up the property " + + setting.get()))); + } + + @Override + public void stop() { + try { + if (container != null) { + container.stop(); + } + } catch (Exception e) { + // ignored + } + } + + public void setupCluster(CouchbaseSettings settings, String database) { + long start = System.currentTimeMillis(); + LOGGER.info("starting the setup with database: " + database); + + try (Cluster cluster = settings.getCluster()) { + + BucketManager buckets = cluster.buckets(); + try { + buckets.getBucket(database); + } catch (BucketNotFoundException exp) { + LOGGER.info("The database/bucket does not exist, creating it: " + database); + buckets.createBucket(BucketSettings.create(database)); + } + Bucket bucket = cluster.bucket(database); + bucket.waitUntilReady(Duration.ofSeconds(5)); + + final CollectionManager manager = bucket.collections(); + List scopes = manager.getAllScopes(); + String finalScope = settings.getScope().orElseGet(() -> bucket.defaultScope().name()); + ScopeSpec spec = scopes.stream().filter(s -> finalScope.equals(s.name())) + .findFirst().orElseThrow(); + + for (String collection : collections) { + if (spec.collections().stream().noneMatch(c -> collection.equals(c.name()))) { + LOGGER.info("creating '" + collection + "' in '" + finalScope + "' scope"); + await(() -> manager.createCollection(CollectionSpec.create(collection, finalScope))); + } + } + if (index != null) { + QueryIndexManager queryIndexManager = cluster.queryIndexes(); + List indexes = queryIndexManager.getAllIndexes(database, getAllQueryIndexesOptions() + .scopeName(finalScope).collectionName(index)); + if (indexes.isEmpty()) { + LOGGER.info("Index does not exist, creating primary key with scope " + + scope + " collection " + index + " at database " + database); + final var _queryIndexManager = queryIndexManager; + await(() -> _queryIndexManager.createPrimaryIndex(database, createPrimaryQueryIndexOptions() + .scopeName(finalScope).collectionName(index))); + } + + for (String collection : collections) { + queryIndexManager = cluster.queryIndexes(); + indexes = queryIndexManager.getAllIndexes(database, getAllQueryIndexesOptions() + .scopeName(finalScope).collectionName(collection)); + if (indexes.isEmpty()) { + LOGGER.info("Index for " + collection + " collection does not exist, creating primary key with scope " + + scope + " collection " + collection + " at database " + database); + final var _queryIndexManager = queryIndexManager; + await(() -> _queryIndexManager + .createPrimaryIndex(database, createPrimaryQueryIndexOptions() + .scopeName(finalScope).collectionName(collection))); + } + } + + } + + long end = System.currentTimeMillis() - start; + LOGGER.info("Finished the setup with database: " + database + " end with millis " + + end); + } + } + + private void await(Runnable runnable) { + Awaitility.given() + .ignoreExceptions() + .await().until(() -> { + try { + runnable.run(); + } catch (RuntimeException ex) { + LOGGER.warn("occurred an issue, but it'll be retried: " + ex.getMessage(), ex); + throw ex; + } + return true; + }); + } + +} diff --git a/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResourceTest.java b/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResourceTest.java new file mode 100644 index 0000000..c9a93f6 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/integration-tests/src/test/java/io/quarkiverse/jnosql/keyvalue/couchbase/it/JNoSQLResourceTest.java @@ -0,0 +1,27 @@ +package io.quarkiverse.jnosql.keyvalue.couchbase.it; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(CouchbaseTestResource.class) +@TestHTTPEndpoint(JNoSQLResource.class) +public class JNoSQLResourceTest { + + @Test + public void testHelloEndpoint() { + given() + .when().get() + .then() + .statusCode(200) + .body(is(not(empty()))); + } +} diff --git a/keyvalue-parent/couchbase-parent/pom.xml b/keyvalue-parent/couchbase-parent/pom.xml new file mode 100644 index 0000000..c0bc3bf --- /dev/null +++ b/keyvalue-parent/couchbase-parent/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-parent + 3.2.2.0 + + + pom + quarkus-jnosql-keyvalue-couchbase-parent + Quarkus JNoSQL - KeyValue - Couchbase - Parent + + + deployment + runtime + + + + + it + + + performRelease + !true + + + + integration-tests + + + + + \ No newline at end of file diff --git a/keyvalue-parent/couchbase-parent/runtime/pom.xml b/keyvalue-parent/couchbase-parent/runtime/pom.xml new file mode 100644 index 0000000..3c267e7 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/runtime/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue-couchbase-parent + 3.2.2.0 + + quarkus-jnosql-keyvalue-couchbase + Quarkus JNoSQL - KeyValue - Couchbase - Runtime + + + io.quarkiverse.jnosql + quarkus-jnosql-keyvalue + ${project.version} + + + org.eclipse.jnosql.databases + jnosql-couchbase + + + + + + io.quarkus + quarkus-extension-maven-plugin + ${quarkus.version} + + + compile + + extension-descriptor + + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/keyvalue-parent/couchbase-parent/runtime/src/main/java/org/eclipse/jnosql/databases/couchbase/communication/QuarkusCouchbaseKeyValueConfiguration.java b/keyvalue-parent/couchbase-parent/runtime/src/main/java/org/eclipse/jnosql/databases/couchbase/communication/QuarkusCouchbaseKeyValueConfiguration.java new file mode 100644 index 0000000..cfac068 --- /dev/null +++ b/keyvalue-parent/couchbase-parent/runtime/src/main/java/org/eclipse/jnosql/databases/couchbase/communication/QuarkusCouchbaseKeyValueConfiguration.java @@ -0,0 +1,28 @@ +package org.eclipse.jnosql.databases.couchbase.communication; + +import java.util.List; + +import jakarta.data.exceptions.MappingException; +import jakarta.inject.Singleton; + +import org.eclipse.jnosql.communication.Settings; +import org.eclipse.jnosql.communication.keyvalue.KeyValueConfiguration; + +@Singleton +public class QuarkusCouchbaseKeyValueConfiguration implements KeyValueConfiguration { + + @Override + public CouchbaseBucketManagerFactory apply(Settings settings) throws NullPointerException { + validateSettings(settings); + return new CouchbaseKeyValueConfiguration().apply(settings); + } + + protected void validateSettings(Settings settings) { + List.of(CouchbaseConfigurations.HOST, + CouchbaseConfigurations.USER, + CouchbaseConfigurations.PASSWORD).forEach( + setting -> settings.get(setting, String.class).orElseThrow( + () -> new MappingException( + "Please, inform the database filling up the property " + setting.get()))); + } +} diff --git a/keyvalue-parent/couchbase-parent/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/keyvalue-parent/couchbase-parent/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000..752371e --- /dev/null +++ b/keyvalue-parent/couchbase-parent/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,9 @@ +name: JNoSQL KeyValue Couchbase +#description: Do something useful. +metadata: +# keywords: +# - jnosql +# guide: https://quarkiverse.github.io/quarkiverse-docs/jnosql/dev/ +# categories: +# - "miscellaneous" +# status: "preview" diff --git a/keyvalue-parent/pom.xml b/keyvalue-parent/pom.xml index 2a2e280..010db37 100644 --- a/keyvalue-parent/pom.xml +++ b/keyvalue-parent/pom.xml @@ -19,6 +19,7 @@ dynamodb-parent hazelcast-parent redis-parent + couchbase-parent integration-tests diff --git a/pom.xml b/pom.xml index 53b514a..aa3582c 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ UTF-8 3.2.4.Final 3.2.4.Final + 3.0.0-M2 1.2.0 4.0.0 3.0.0-M1 @@ -45,6 +46,13 @@ pom import + + org.apache.camel.quarkus + camel-quarkus-bom + ${camel-quarkus-bom.version} + pom + import + org.eclipse.jnosql.mapping jnosql-mapping-core @@ -116,6 +124,11 @@ jnosql-couchdb ${jnosql.version} + + org.eclipse.jnosql.databases + jnosql-couchbase + ${jnosql.version} +