diff --git a/java/pom.xml b/java/pom.xml index 9227605..9f3ed5d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -1,33 +1,68 @@ 4.0.0 - com.couchbase + com.couchbase.client.demo devguide 1.0-SNAPSHOT 1.8 1.8 + 1.2.17 + 1.7.30 com.couchbase.client java-client - 2.7.9 + 3.0.8 + com.couchbase.client - encryption - 2.0.1 + couchbase-encryption + 3.0.0-pre.1 + + + + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + log4j log4j - 1.2.17 + ${log4j.version} + + + + + couchbase + Couchbase Preview Repository + http://files.couchbase.com/maven2 + + + + sonatypeSnapshots + Sonatype Snapshots + + false + + + true + + https://oss.sonatype.org/content/repositories/snapshots + + + + @@ -35,8 +70,8 @@ maven-compiler-plugin 3.8.1 - 1.8 - 1.8 + 8 + 8 diff --git a/java/src/main/java/com/couchbase/devguide/BulkGet.java b/java/src/main/java/com/couchbase/devguide/BulkGet.java index 2109a5d..f8b2729 100644 --- a/java/src/main/java/com/couchbase/devguide/BulkGet.java +++ b/java/src/main/java/com/couchbase/devguide/BulkGet.java @@ -1,16 +1,27 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.JsonLongDocument; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.DocumentDoesNotExistException; -import rx.Observable; -import rx.functions.Action1; -import rx.functions.Func1; +import com.couchbase.client.java.ReactiveCollection; +import com.couchbase.client.java.json.JsonObject; +import reactor.core.publisher.Flux; /** * Example of Bulk Get in Java for the Couchbase Developer Guide. @@ -32,47 +43,21 @@ protected void doWork() { // Insert 10 documents, the old way for (String id : keys) { - JsonDocument doc = JsonDocument.create(id, content); - bucket.upsert(doc); + collection.upsert(id, content); } + JsonObject jo = collection.get(key+"_1").contentAsObject(); + System.out.println(jo); // Describe what we want to do asynchronously using RxJava Observables: - Observable asyncBulkGet = Observable - // Use RxJava from to start from the keys we know in advance - .from(keys) - //now use flatMap to asynchronously retrieve (get) each corresponding document using the SDK - .flatMap(new Func1>() { - public Observable call(String key) { - if (key.endsWith("3")) - return bucket.async().get(key).delay(3, TimeUnit.SECONDS); //artificial delay for item 3 - return bucket.async().get(key); - } - }); - // So far we've described and not triggered the processing, let's subscribe - /* - * Note: since our app is not fully asynchronous, we want to revert back to blocking at the end, - * so we subscribe using toBlocking(). - * - * toBlocking will throw any exception that was propagated through the Observer's onError method. - * - * The SDK is doing its own parallelisation so the blocking is just waiting for the last item, - * notice how our artificial delay doesn't impact printout of the other values, that come in the order - * in which the server answered... - */ - try { - asyncBulkGet.toBlocking() - // we'll still printout each inserted document (with CAS gotten from the server) - // toBlocking() also offers several ways of getting one of the emitted values (first(), single(), last()) - .forEach(new Action1() { - public void call(JsonDocument jsonDocument) { - LOGGER.info("Found " + jsonDocument); - } - }); - } catch (Exception e) { - LOGGER.error("Error during bulk get", e); - } + ReactiveCollection reactiveCollection = collection.reactive(); + Flux resultFlux = Flux.range(0, 10) + .map(index -> {return key + "_" + index; } ) + .flatMap( k -> reactiveCollection.get(k)); + + resultFlux.subscribe(System.out::println); + } public static void main(String[] args) { diff --git a/java/src/main/java/com/couchbase/devguide/BulkInsert.java b/java/src/main/java/com/couchbase/devguide/BulkInsert.java index 366c656..fdbbcc6 100644 --- a/java/src/main/java/com/couchbase/devguide/BulkInsert.java +++ b/java/src/main/java/com/couchbase/devguide/BulkInsert.java @@ -1,16 +1,25 @@ -package com.couchbase.devguide; - -import java.util.concurrent.TimeUnit; +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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. + */ -import javax.sound.midi.Soundbank; +package com.couchbase.devguide; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.JsonLongDocument; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.DocumentDoesNotExistException; -import rx.Observable; -import rx.functions.Action1; -import rx.functions.Func1; +import com.couchbase.client.java.ReactiveCollection; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.MutationResult; +import reactor.core.publisher.Flux; /** * Example of Bulk Insert in Java for the Couchbase Developer Guide. @@ -26,52 +35,13 @@ protected void doWork() { // Describe what we want to do asynchronously using RxJava Observables: - Observable asyncProcessing = Observable - // Use RxJava range + map to generate 10 keys. One could also use "from" with a pre-existing collection of keys. - .range(0, 10) - .map(new Func1() { - public String call(Integer i) { - return key + "_" + i; - } - }) - //then create a JsonDocument out each one of these keys - .map(new Func1() { - public JsonDocument call(String s) { - return JsonDocument.create(s, content); - } - }) - //now use flatMap to asynchronously call the SDK upsert operation on each - .flatMap(new Func1>() { - public Observable call(JsonDocument doc) { - if (doc.id().endsWith("3")) - return bucket.async().upsert(doc).delay(3, TimeUnit.SECONDS); //artificial delay for item 3 - return bucket.async().upsert(doc); - } - }); + ReactiveCollection reactiveCollection = collection.reactive(); + Flux resultFlux = Flux.range(0, 10) + .map(index -> {return key + "_" + index; } ) + .flatMap( k -> reactiveCollection.upsert(k, content)); + + resultFlux.subscribe(System.out::println); - // So far we've described and not triggered the processing, let's subscribe - /* - * Note: since our app is not fully asynchronous, we want to revert back to blocking at the end, - * so we subscribe using toBlocking(). - * - * toBlocking will throw any exception that was propagated through the Observer's onError method. - * - * The SDK is doing its own parallelisation so the blocking is just waiting for the last item, - * notice how our artificial delay doesn't impact printout of the other values, that come in the order - * in which the server answered... - */ - try { - asyncProcessing.toBlocking() - // we'll still printout each inserted document (with CAS gotten from the server) - // toBlocking() also offers several ways of getting one of the emitted values (first(), single(), last()) - .forEach(new Action1() { - public void call(JsonDocument jsonDocument) { - LOGGER.info("Inserted " + jsonDocument); - } - }); - } catch (Exception e) { - LOGGER.error("Error during bulk insert", e); - } } public static void main(String[] args) { diff --git a/java/src/main/java/com/couchbase/devguide/Cas.java b/java/src/main/java/com/couchbase/devguide/Cas.java index d870f10..ba711ca 100644 --- a/java/src/main/java/com/couchbase/devguide/Cas.java +++ b/java/src/main/java/com/couchbase/devguide/Cas.java @@ -1,15 +1,32 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.GetResult; +import com.couchbase.client.java.kv.ReplaceOptions; + import java.util.concurrent.CountDownLatch; -import com.couchbase.client.java.document.JsonArrayDocument; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.CASMismatchException; /** * Example of Cas (Check and Set) handling in Java for the Couchbase Developer Guide. + * TODO: not tested */ public class Cas extends ConnectionBase { @@ -18,26 +35,26 @@ public class Cas extends ConnectionBase { @Override protected void doWork() { - JsonArrayDocument initialDoc = JsonArrayDocument.create(KEY, JsonArray.empty()); - bucket.upsert(initialDoc); + JsonArray initialDoc = JsonArray.create().add("initial"); + bucket.defaultCollection().upsert(KEY, initialDoc); LOGGER.info("Will attempt concurrent document mutations without CAS"); parallel(false); - JsonArray currentList = bucket.get(KEY, JsonArrayDocument.class).content(); + JsonArray currentList = bucket.defaultCollection().get(KEY).contentAsArray(); LOGGER.info("Current list has " + currentList.size() + " elements"); if (currentList.size() != PARALLEL) { LOGGER.info("Concurrent modifications removed some of our items! " + currentList.toString()); } // Reset the list again - bucket.upsert(initialDoc); + bucket.defaultCollection().upsert(KEY,initialDoc); //The same as above, but using CAS LOGGER.info("Will attempt concurrent modifications using CAS"); parallel(true); - currentList = bucket.get(KEY, JsonArrayDocument.class).content(); + currentList = bucket.defaultCollection().get(KEY).contentAsArray(); LOGGER.info("Current list has " + currentList.size() + " elements: " + currentList.toString()); if (currentList.size() != PARALLEL) { LOGGER.error("Expected the whole list of elements - " + currentList.toString()); @@ -46,11 +63,9 @@ protected void doWork() { public void iterationWithoutCAS(int idx, CountDownLatch latch) { //this code plainly ignores the CAS by creating a new document (CAS O) - JsonArray l = bucket.get(KEY, JsonArrayDocument.class).content(); - l.add("item_" + idx); - JsonArrayDocument updatedDoc = JsonArrayDocument.create(KEY, l); - bucket.replace(updatedDoc); - + JsonArray l = bucket.defaultCollection().get(KEY).contentAsArray(); + l.add("value_"+idx); + bucket.defaultCollection().replace(KEY, l); latch.countDown(); } @@ -58,18 +73,21 @@ public void iterationWithCAS(int idx, CountDownLatch latch) { String item = "item_" + idx; while(true) { - JsonArrayDocument current = bucket.get(KEY, JsonArrayDocument.class); - JsonArray l = current.content(); - l.add(item); + //GetResult current = bucket.defaultCollection().get(KEY); + //JsonArray l = bucket.defaultCollection().get(KEY).contentAsArray(); + //l.add( "value_"+idx); //we mutated the content of the document, and the SDK injected the CAS value in there as well // so we can use it directly try { - bucket.replace(current); + GetResult current = bucket.defaultCollection().get(KEY); + JsonArray l = current.contentAsArray(); + l.add( "value_"+idx); + bucket.defaultCollection().replace(KEY,l, ReplaceOptions.replaceOptions().cas(current.cas())); break; //success! stop the loop - } catch (CASMismatchException e) { + } catch (RuntimeException e) { //in case a parallel execution already updated the document, continue trying - LOGGER.info("Cas mismatch for item " + item); + LOGGER.info(e+" Cas mismatch for item " + item); } } latch.countDown(); diff --git a/java/src/main/java/com/couchbase/devguide/Cloud.java b/java/src/main/java/com/couchbase/devguide/Cloud.java index 10cad8b..90b74c2 100644 --- a/java/src/main/java/com/couchbase/devguide/Cloud.java +++ b/java/src/main/java/com/couchbase/devguide/Cloud.java @@ -1,14 +1,34 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; + +import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import com.couchbase.client.core.env.IoConfig; +import com.couchbase.client.core.env.SecurityConfig; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; +import com.couchbase.client.java.ClusterOptions; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.Scope; +import com.couchbase.client.java.env.ClusterEnvironment; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions; +import com.couchbase.client.java.query.QueryResult; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; @@ -20,7 +40,14 @@ import java.util.List; import java.util.stream.Collectors; -public class Example { +import static com.couchbase.client.java.query.QueryOptions.queryOptions; + +/** + * Example of Cas (Check and Set) handling in Java for the Couchbase Developer Guide. + * TODO: not tested | ported from 2.x, but not tested. See CloudConnect.java for 3.x + */ + +public class Cloud { // Update this to your certificate. private static final String CERT = "-----BEGIN CERTIFICATE-----\n" + "MIIDFTCCAf2gAwIBAgIRANLVkgOvtaXiQJi0V6qeNtswDQYJKoZIhvcNAQELBQAw\n" + @@ -44,7 +71,7 @@ public class Example { public static void main(String... args) throws Exception { // Update this to your cluster - String endpoint = "endpoint"; + String endpoint = "cb..dp.cloud.couchbase.com"; String bucketName = "couchbasecloudbucket"; String username = "user"; String password = "password"; @@ -54,19 +81,21 @@ public static void main(String... args) throws Exception { trustStore.load(null, null); trustStore.setCertificateEntry("server", decodeCertificates(Collections.singletonList(CERT)).get(0)); - CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder() - .sslEnabled(true) - .dnsSrvEnabled(true) - .sslTruststore(trustStore) - .build(); + ClusterEnvironment env = ClusterEnvironment.builder() + .securityConfig(SecurityConfig.enableTls(true) + .trustManagerFactory(InsecureTrustManagerFactory.INSTANCE)) + .ioConfig(IoConfig.enableDnsSrv(true)) + .build(); // Initialize the Connection - Cluster cluster = CouchbaseCluster.create(env, endpoint); - cluster.authenticate(username, password); - Bucket bucket = cluster.openBucket(bucketName); + Cluster cluster = Cluster.connect(endpoint, + ClusterOptions.clusterOptions(username, password).environment(env)); + Bucket bucket = cluster.bucket(bucketName); + Scope scope = bucket.defaultScope(); + Collection collection = bucket.defaultCollection(); // Create a N1QL Primary Index (but ignore if it exists) - bucket.bucketManager().createN1qlPrimaryIndex(true, false); + cluster.queryIndexes().createPrimaryIndex(bucketName, CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true)); // Create a JSON Document JsonObject arthur = JsonObject.create() @@ -75,21 +104,21 @@ public static void main(String... args) throws Exception { .put("interests", JsonArray.from("Holy Grail", "African Swallows")); // Store the Document - bucket.upsert(JsonDocument.create("u:king_arthur", arthur)); + collection.upsert( "u:king_arthur", arthur); // Load the Document and print it // Prints Content and Metadata of the stored Document - System.out.println(bucket.get("u:king_arthur")); + System.out.println(collection.get("u:king_arthur")); // Perform a N1QL Query - N1qlQueryResult result = bucket.query( - N1qlQuery.parameterized(String.format("SELECT name FROM `%s` WHERE $1 IN interests", bucketName), - JsonArray.from("African Swallows")) + // Perform a N1QL Query + QueryResult result = cluster.query( + String.format("SELECT name FROM `%s` WHERE $1 IN interests", bucketName), + queryOptions().parameters(JsonArray.from("African Swallows")) ); // Print each found Row - for (N1qlQueryRow row : result) { - // Prints {"name":"Arthur"} + for (JsonObject row : result.rowsAsObject()) { System.out.println(row); } } diff --git a/java/src/main/java/com/couchbase/devguide/CloudConnect.java b/java/src/main/java/com/couchbase/devguide/CloudConnect.java new file mode 100644 index 0000000..79f7f97 --- /dev/null +++ b/java/src/main/java/com/couchbase/devguide/CloudConnect.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; + +import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import com.couchbase.client.core.env.IoConfig; +import com.couchbase.client.core.env.SecurityConfig; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.ClusterOptions; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.env.ClusterEnvironment; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions; +import com.couchbase.client.java.query.QueryResult; +import static com.couchbase.client.java.query.QueryOptions.queryOptions; + +import java.time.Duration; + +public class CloudConnect { + public static void main(String... args) { + // Update this to your cluster + String endpoint = "cb..dp.cloud.couchbase.com"; + String bucketName = "couchbasecloudbucket"; + String username = "user"; + String password = "password"; + // User Input ends here. + + ClusterEnvironment env = ClusterEnvironment.builder() + .securityConfig(SecurityConfig.enableTls(true) + .trustManagerFactory(InsecureTrustManagerFactory.INSTANCE)) + .ioConfig(IoConfig.enableDnsSrv(true)) + .build(); + // env = ClusterEnvironment.builder().build(); + + // Initialize the Connection + Cluster cluster = Cluster.connect(endpoint, + ClusterOptions.clusterOptions(username, password).environment(env)); + Bucket bucket = cluster.bucket(bucketName); + bucket.waitUntilReady(Duration.parse("PT10S")); + Collection collection = bucket.defaultCollection(); + + cluster.queryIndexes().createPrimaryIndex(bucketName, CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true)); + + // Create a JSON Document + JsonObject arthur = JsonObject.create() + .put("name", "Arthur") + .put("email", "kingarthur@couchbase.com") + .put("interests", JsonArray.from("Holy Grail", "African Swallows")); + + // Store the Document + collection.upsert( + "u:king_arthur", + arthur + ); + + // Load the Document and print it + // Prints Content and Metadata of the stored Document + System.out.println(collection.get("u:king_arthur")); + + // Perform a N1QL Query + QueryResult result = cluster.query( + String.format("SELECT name FROM `%s` WHERE $1 IN interests", bucketName), + queryOptions().parameters(JsonArray.from("African Swallows")) + ); + + // Print each found Row + for (JsonObject row : result.rowsAsObject()) { + System.out.println(row); + } + } +} diff --git a/java/src/main/java/com/couchbase/devguide/ConnectingCertAuth.java b/java/src/main/java/com/couchbase/devguide/ConnectingCertAuth.java index eafae88..c133882 100644 --- a/java/src/main/java/com/couchbase/devguide/ConnectingCertAuth.java +++ b/java/src/main/java/com/couchbase/devguide/ConnectingCertAuth.java @@ -1,10 +1,29 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; +import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import com.couchbase.client.core.env.IoConfig; +import com.couchbase.client.core.env.SecurityConfig; +import com.couchbase.client.core.error.DocumentNotFoundException; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import com.couchbase.client.java.ClusterOptions; +import com.couchbase.client.java.env.ClusterEnvironment; /** * This example shows how to connect to a couchbase server EE cluster using @@ -16,23 +35,37 @@ * https://developer.couchbase.com/documentation/server/current/security/security-x509certsintro.html */ public class ConnectingCertAuth { + static String connectstring = "127.0.0.1"; + static String username="Administrator"; + static String password="password"; public static void main(String... args) { - CouchbaseEnvironment environment = DefaultCouchbaseEnvironment.builder() + ClusterEnvironment env = ClusterEnvironment.builder() + .securityConfig(SecurityConfig.enableTls(true) + .trustManagerFactory(InsecureTrustManagerFactory.INSTANCE)) + .ioConfig(IoConfig.enableDnsSrv(true)) + /* .sslEnabled(true) .certAuthEnabled(true) .sslKeystoreFile("/path/to/keystore") .sslKeystorePassword("password") .sslTruststoreFile("/path/to/truststore") // you can also pack it all in just the keystore .sslTruststorePassword("password") + */ .build(); - Cluster cluster = CouchbaseCluster.create(environment, "127.0.0.1"); + Cluster cluster = Cluster.connect(connectstring, + ClusterOptions.clusterOptions(username, password).environment(env)); // IMPORTANT: do NOT call cluster.authenticate() since this is part of the cert auth - Bucket bucket = cluster.openBucket("travel-sample"); + Bucket bucket = cluster.bucket("default"); // perform operations here... - bucket.get("mydoc"); + try { + bucket.defaultCollection() + .get("mydoc"); + } catch (DocumentNotFoundException dnf){ + System.out.println(dnf); + } } } diff --git a/java/src/main/java/com/couchbase/devguide/ConnectingSsl.java b/java/src/main/java/com/couchbase/devguide/ConnectingSsl.java index b705cc6..607155f 100644 --- a/java/src/main/java/com/couchbase/devguide/ConnectingSsl.java +++ b/java/src/main/java/com/couchbase/devguide/ConnectingSsl.java @@ -1,44 +1,63 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import java.util.Arrays; -import java.util.List; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import com.couchbase.client.core.env.SecurityConfig; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import com.couchbase.client.java.ClusterOptions; +import com.couchbase.client.java.env.ClusterEnvironment; + import org.apache.log4j.Logger; public class ConnectingSsl { protected static final Logger LOGGER = Logger.getLogger("devguide"); - protected final Cluster cluster; protected final Bucket bucket; - protected final CouchbaseEnvironment env; + protected final ClusterEnvironment env; //=== EDIT THESE TO ADAPT TO YOUR COUCHBASE INSTALLATION === public static final String bucketName = "default"; - public static final String bucketPassword = ""; - public static final List nodes = Arrays.asList("127.0.0.1"); + static String connectstring = "127.0.0.1"; + static String username="Administrator"; + static String password="password"; //=== You need to correctly set up your JVM keystore first! === //see instructions in http://developer.couchbase.com/documentation/server/4.0/sdks/java-2.2/managing-connections.html#story-h2-5 protected ConnectingSsl() { //configure the SDK to use SSL and point it to the keystore - env = DefaultCouchbaseEnvironment.builder() - .sslEnabled(true) - .sslKeystoreFile("/path/tokeystore") - .sslKeystorePassword("password") - .build(); + + env = ClusterEnvironment.builder() + .securityConfig(SecurityConfig.enableTls(true) + .trustStore(Paths.get("/path/tokeystore"),"password", Optional.empty())) + .build(); //connect to the cluster using the SSL configuration, by hitting one of the given nodes - cluster = CouchbaseCluster.create(env, nodes); + cluster = Cluster.connect(connectstring, + ClusterOptions.clusterOptions(username, password).environment(env)); //get a Bucket reference from the cluster to the configured bucket - bucket = cluster.openBucket(bucketName, bucketPassword); + bucket = cluster.bucket(bucketName); } private void disconnect() { @@ -46,7 +65,7 @@ private void disconnect() { cluster.disconnect(); //also release the environment since we created it ourselves (notice this is an async operation so we block on it) - env.shutdownAsync().toBlocking().first(); + env.shutdownAsync(); } public void execute() { diff --git a/java/src/main/java/com/couchbase/devguide/ConnectionBase.java b/java/src/main/java/com/couchbase/devguide/ConnectionBase.java index c8c17dc..0fca3fd 100644 --- a/java/src/main/java/com/couchbase/devguide/ConnectionBase.java +++ b/java/src/main/java/com/couchbase/devguide/ConnectionBase.java @@ -1,33 +1,59 @@ -package com.couchbase.devguide; +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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. + */ -import java.util.Arrays; -import java.util.List; +package com.couchbase.devguide; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.env.CouchbaseEnvironment; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.Scope; import org.apache.log4j.Logger; +import java.time.Duration; + public class ConnectionBase { protected static final Logger LOGGER = Logger.getLogger("devguide"); protected final Cluster cluster; protected final Bucket bucket; + protected final Scope scope; + protected final Collection collection; + protected final Scope namedScope; + protected final Collection namedCollection; //=== EDIT THESE TO ADAPT TO YOUR COUCHBASE INSTALLATION === public static final String bucketName = "default"; - public static final String bucketPassword = ""; - public static final List nodes = Arrays.asList("127.0.0.1"); - public static CouchbaseEnvironment environment = DefaultCouchbaseEnvironment.create(); + public static final String scopeName = "scope-name"; + public static final String collectionName = "collection-name"; + public static final String userName = "Administrator"; + public static final String userPass = "password"; + public static final String seedNode = "127.0.0.1"; public ConnectionBase() { - //connect to the cluster by hitting one of the given nodes - cluster = CouchbaseCluster.create(environment, nodes); - //get a Bucket reference from the cluster to the configured bucket - bucket = cluster.openBucket(bucketName, bucketPassword); + // connect deferred to the cluster by hitting one of the given nodes + cluster = Cluster.connect(seedNode, userName, userPass); + // get a Bucket reference from the cluster to the configured bucket + bucket = cluster.bucket(bucketName); + // reference the scope and collection + scope = bucket.defaultScope(); + collection = bucket.defaultCollection(); + namedScope = bucket.scope(scopeName); + namedCollection = scope.collection(collectionName); + bucket.waitUntilReady(Duration.ofSeconds(30)); } private void disconnect() { diff --git a/java/src/main/java/com/couchbase/devguide/Counter.java b/java/src/main/java/com/couchbase/devguide/Counter.java index 4145d15..e8c3921 100644 --- a/java/src/main/java/com/couchbase/devguide/Counter.java +++ b/java/src/main/java/com/couchbase/devguide/Counter.java @@ -1,7 +1,25 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.JsonLongDocument; -import com.couchbase.client.java.error.DocumentDoesNotExistException; +import com.couchbase.client.core.error.DocumentNotFoundException; +import com.couchbase.client.java.kv.CounterResult; +import com.couchbase.client.java.kv.DecrementOptions; +import com.couchbase.client.java.kv.IncrementOptions; /** * Example of Counters in Java for the Couchbase Developer Guide. @@ -13,26 +31,26 @@ protected void doWork() { String key = "javaDevguideExampleCounter"; // Remove document so we have predictable behavior in this example try { - bucket.remove(key); - } catch (DocumentDoesNotExistException e) { + bucket.defaultCollection().remove(key); + } catch (DocumentNotFoundException e) { //do nothing, the document is already not here } try { - bucket.counter(key, 20); - } catch (DocumentDoesNotExistException e) { + bucket.defaultCollection().binary().increment(key, IncrementOptions.incrementOptions().delta(20).initial(100)); + } catch (DocumentNotFoundException e) { LOGGER.info("The counter method failed because the counter doesn't exist yet and no initial value was provided"); } - JsonLongDocument rv = bucket.counter(key, 20, 100); - LOGGER.info("Delta=20, Initial=100. Current value is: " + rv.content()); + CounterResult rv = bucket.defaultCollection().binary().increment(key, IncrementOptions.incrementOptions().initial(20)); + LOGGER.info("increment Delta=20, Initial=100. Current value is: " + rv.content()); - rv = bucket.counter(key, 1); - LOGGER.info("Delta=1. Current value is: " + rv.content()); + rv = bucket.defaultCollection().binary().increment(key, IncrementOptions.incrementOptions().delta(1)); + LOGGER.info("increment Delta=1. Current value is: " + rv.content()); - rv = bucket.counter(key, -50); - LOGGER.info("Delta=-50. Current value is: " + rv.content()); + rv = bucket.defaultCollection().binary().decrement(key, DecrementOptions.decrementOptions().delta(50)); + LOGGER.info("decrement Delta=50. Current value is: " + rv.content()); } public static void main(String[] args) { diff --git a/java/src/main/java/com/couchbase/devguide/Durability.java b/java/src/main/java/com/couchbase/devguide/Durability.java index c64bbc5..d170061 100644 --- a/java/src/main/java/com/couchbase/devguide/Durability.java +++ b/java/src/main/java/com/couchbase/devguide/Durability.java @@ -1,38 +1,55 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import java.util.concurrent.TimeUnit; +import java.time.Duration; import java.util.concurrent.TimeoutException; -import com.couchbase.client.core.ReplicaNotAvailableException; -import com.couchbase.client.core.ReplicaNotConfiguredException; -import com.couchbase.client.java.PersistTo; -import com.couchbase.client.java.ReplicateTo; -import com.couchbase.client.java.document.JsonLongDocument; -import com.couchbase.client.java.document.JsonStringDocument; -import com.couchbase.client.java.error.DocumentDoesNotExistException; -import com.couchbase.client.java.error.DurabilityException; +import com.couchbase.client.core.error.DurabilityImpossibleException; +import com.couchbase.client.core.error.ReplicaNotAvailableException; +import com.couchbase.client.core.error.ReplicaNotConfiguredException; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.PersistTo; +import com.couchbase.client.java.kv.ReplicateTo; +import com.couchbase.client.java.kv.UpsertOptions; /** * Example of Durability in Java for the Couchbase Developer Guide. + * TODO: not tested */ public class Durability extends ConnectionBase { @Override protected void doWork() { String key = "javaDevguideExampleDurability"; - JsonStringDocument doc = JsonStringDocument.create(key, "a String is valid JSON"); + JsonObject doc = JsonObject.create().put("value","a String is valid JSON"); LOGGER.info("Storing with maximum factor"); // In the Java SDK you must specify a factor matching the number of replicas you have configured // if you want "maximum" persistence or replication // Here we expect 3 replicas configured so we can wait for persistence on 4 nodes total, replication on 3 replicas. try { - bucket.upsert(doc, PersistTo.FOUR, ReplicateTo.THREE); - } catch (DurabilityException e) { //if the durability cannot be met - if (e.getCause() instanceof ReplicaNotConfiguredException) { + bucket.defaultCollection().upsert( key, doc, UpsertOptions.upsertOptions().durability(PersistTo.FOUR, + ReplicateTo.THREE)); + } catch (Exception e) { //if the durability cannot be met + if (e instanceof ReplicaNotConfiguredException) { //this exception is a fail fast if not enough replicas are configured on the bucket LOGGER.info("Couldn't persist to FOUR nor replicate to THREE, not enough replicas configured"); - } else if (e.getCause() instanceof ReplicaNotAvailableException) { + } else if (e instanceof ReplicaNotAvailableException) { //this exception occurs if enough replica are configured on the bucket but currently not enough are online //eg. during a failover LOGGER.info("Couldn't persist/replicate on 1 replica, not enough replicas online"); @@ -43,15 +60,16 @@ protected void doWork() { // Store with persisting to master node LOGGER.info("Storing with waiting for persistence on MASTER"); - bucket.upsert(doc, PersistTo.MASTER); + bucket.defaultCollection().upsert( key, doc, UpsertOptions.upsertOptions().durability(PersistTo.ACTIVE, ReplicateTo.NONE)); LOGGER.info("Storing with waiting for persistence on any two nodes, replication on one replica node"); try { - bucket.upsert(doc, PersistTo.TWO, ReplicateTo.ONE); - } catch (DurabilityException e) { + bucket.defaultCollection().upsert( key, doc, UpsertOptions.upsertOptions().durability(PersistTo.TWO, ReplicateTo.ONE).timeout(Duration.ofSeconds(1))); + } catch (DurabilityImpossibleException e) { //if the durability cannot be met (eg. if the cluster detected that the replica wasn't available due to failover) LOGGER.error("Durability Exception", e); } catch (RuntimeException e) { + System.out.println(e); if (e.getCause() instanceof TimeoutException) { //if one of the nodes isn't responsive, a TimeoutException rather than DurabilityException may occur LOGGER.warn("The replica didn't notify us in time"); diff --git a/java/src/main/java/com/couchbase/devguide/Expiration.java b/java/src/main/java/com/couchbase/devguide/Expiration.java index 9ef8eb1..dcce7a3 100644 --- a/java/src/main/java/com/couchbase/devguide/Expiration.java +++ b/java/src/main/java/com/couchbase/devguide/Expiration.java @@ -1,8 +1,27 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.DocumentAlreadyExistsException; +import com.couchbase.client.core.error.DocumentNotFoundException; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.GetResult; +import com.couchbase.client.java.kv.UpsertOptions; + +import java.time.Duration; /** * Example of Expiry/TTL in Java for the Couchbase Developer Guide. @@ -16,44 +35,59 @@ protected void doWork() { JsonObject content = JsonObject.create().put("some", "value"); LOGGER.info("Storing with an expiration of 2 seconds"); - bucket.upsert(JsonDocument.create(key, 2, content)); + bucket.defaultCollection().upsert(key, content, UpsertOptions.upsertOptions().expiry(Duration.ofSeconds(2))); LOGGER.info("Getting item back immediately"); - LOGGER.info(bucket.get(key).content()); + LOGGER.info(bucket.defaultCollection().get(key)); LOGGER.info("Sleeping for 4 seconds..."); sleepSeconds(4); - LOGGER.info("Getting key again..."); + LOGGER.info("Getting key again (should fail)"); //get returns null if the key doesn't exist - if (bucket.get(key) == null) { + try { + if (bucket.defaultCollection() + .get(key) == null) { + LOGGER.info("Get failed because item has expired"); + } + } catch (DocumentNotFoundException dnf){ LOGGER.info("Get failed because item has expired"); } LOGGER.info("Storing item again (without expiry)"); - bucket.upsert(JsonDocument.create(key, content)); + bucket.defaultCollection().upsert(key, content); LOGGER.info("Using get-and-touch to retrieve key and modify expiry"); - JsonDocument rv = bucket.getAndTouch(key, 2); - LOGGER.info("Value is:" + rv.content()); + GetResult rv = bucket.defaultCollection().getAndTouch(key, Duration.ofSeconds(2)); + LOGGER.info("Value is:" + rv); LOGGER.info("Sleeping for 4 seconds again"); sleepSeconds(4); LOGGER.info("Getting key again (should fail)"); - if (bucket.get(key) == null) { - LOGGER.info("Failed (not found)"); + try { + if (bucket.defaultCollection() + .get(key) == null) { + LOGGER.info("Get failed because item has expired"); + } + } catch (DocumentNotFoundException dnf){ + LOGGER.info("Get failed because item has expired"); } LOGGER.info("Storing key again..."); - bucket.upsert(JsonDocument.create(key, content)); + bucket.defaultCollection().upsert(key, content); LOGGER.info("Using touch (without get). Setting expiry for 1 second"); - bucket.touch(key, 1); + bucket.defaultCollection().touch(key, Duration.ofSeconds(1)); LOGGER.info("Sleeping for 4 seconds..."); sleepSeconds(4); - LOGGER.info("Will try to get item again... (should fail)"); - if (bucket.get(key) == null) { - LOGGER.info("Get failed because key has expired"); + LOGGER.info("Will try to get item again (should fail)"); + try { + if (bucket.defaultCollection() + .get(key) == null) { + LOGGER.info("Get failed because item has expired"); + } + } catch (DocumentNotFoundException dnf){ + LOGGER.info("Get failed because item has expired"); } } diff --git a/java/src/main/java/com/couchbase/devguide/FieldEncryptionAES.java b/java/src/main/java/com/couchbase/devguide/FieldEncryptionAES.java index 33037eb..c29ca9d 100644 --- a/java/src/main/java/com/couchbase/devguide/FieldEncryptionAES.java +++ b/java/src/main/java/com/couchbase/devguide/FieldEncryptionAES.java @@ -1,37 +1,74 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import java.nio.charset.Charset; +import com.couchbase.client.core.encryption.CryptoManager; +import com.couchbase.client.encryption.AeadAes256CbcHmacSha512Provider; +import com.couchbase.client.encryption.DefaultCryptoManager; +import com.couchbase.client.encryption.KeyStoreKeyring; +import com.couchbase.client.encryption.Keyring; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.ClusterOptions; +import com.couchbase.client.java.encryption.annotation.Encrypted; +import com.couchbase.client.java.env.ClusterEnvironment; + +import java.io.FileInputStream; +import java.security.KeyStore; -import com.couchbase.client.encryption.AES128CryptoProvider; -import com.couchbase.client.encryption.AES256CryptoProvider; -import com.couchbase.client.encryption.CryptoManager; -import com.couchbase.client.encryption.JceksKeyStoreProvider; -import com.couchbase.client.java.document.EntityDocument; -import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; -import com.couchbase.client.java.repository.annotation.EncryptedField; -import com.couchbase.client.java.repository.annotation.Id; public class FieldEncryptionAES extends ConnectionBase { - static { + @Override + protected void doWork() { + Cluster cluster; try { - JceksKeyStoreProvider kp = new JceksKeyStoreProvider("secret"); - kp.publicKeyName("mypublickey"); - kp.storeKey("mypublickey", "!mysecretkey#9^5usdk39d&dlf)03sL".getBytes(Charset.forName("UTF-8"))); - kp.signingKeyName("HMACsecret"); - kp.storeKey("HMACsecret", "myauthpassword".getBytes(Charset.forName("UTF-8"))); - AES256CryptoProvider aes256CryptoProvider = new AES256CryptoProvider(kp); - CryptoManager cryptoManager = new CryptoManager(); - cryptoManager.registerProvider("MyAESProvider", aes256CryptoProvider); - environment = DefaultCouchbaseEnvironment.builder().cryptoManager(cryptoManager).build(); - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(1); + KeyStore javaKeyStore = KeyStore.getInstance("MyKeyStoreType"); + FileInputStream fis = new java.io.FileInputStream("keyStoreName"); + char[] password = {'a', 'b', 'c'}; + javaKeyStore.load(fis, + password); + Keyring keyring = new KeyStoreKeyring(javaKeyStore, + keyName -> "swordfish"); + + // AES-256 authenticated with HMAC SHA-512. Requires a 64-byte key. + AeadAes256CbcHmacSha512Provider provider = AeadAes256CbcHmacSha512Provider.builder() + .keyring(keyring) + .build(); + + CryptoManager cryptoManager = DefaultCryptoManager.builder() + .decrypter(provider.decrypter()) + .defaultEncrypter(provider.encrypterForKey("myKey")) + .build(); + + ClusterEnvironment env = ClusterEnvironment.builder() + .cryptoManager(cryptoManager) + .build(); + + cluster = Cluster.connect("localhost", + ClusterOptions.clusterOptions("username", + "password") + .environment(env)); + } catch (Exception e){ + throw new RuntimeException(e); } - } - @Override - protected void doWork() { + Bucket myBucket = cluster.bucket(bucketName); + Person person = new Person(); person.id = "johnd"; person.password = "secret"; @@ -40,18 +77,16 @@ protected void doWork() { person.userName = "jdoe"; person.age = 20; - EntityDocument document = EntityDocument.create(person); - bucket.repository().upsert(document); - EntityDocument stored = bucket.repository().get(person.id, Person.class); - System.out.println("Password: " + stored.content().password); + myBucket.defaultCollection().upsert(person.id, person); + Person stored = bucket.defaultCollection().get(person.id).contentAs(Person.class); + System.out.println("Password: " + stored.password); } public static class Person { - @Id public String id; - @EncryptedField(provider = "MyAESProvider") + @Encrypted public String password; //The rest will be transported and stored unencrypted @@ -64,4 +99,4 @@ public static class Person { public static void main(String[] args) { new FieldEncryptionAES().execute(); } -} \ No newline at end of file +} diff --git a/java/src/main/java/com/couchbase/devguide/HealthCheck.java b/java/src/main/java/com/couchbase/devguide/HealthCheck.java new file mode 100644 index 0000000..f8a1d14 --- /dev/null +++ b/java/src/main/java/com/couchbase/devguide/HealthCheck.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; + +import com.couchbase.client.core.diagnostics.DiagnosticsResult; +import com.couchbase.client.core.diagnostics.EndpointDiagnostics; +import com.couchbase.client.core.diagnostics.EndpointPingReport; +import com.couchbase.client.core.diagnostics.PingResult; +import com.couchbase.client.core.diagnostics.PingState; +import com.couchbase.client.core.endpoint.EndpointState; +import com.couchbase.client.core.service.ServiceType; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.MutationResult; + +import java.time.Duration; +import java.util.List; +import java.util.Map; + + +/** + * Example Health Check with the Couchbase Java SDKa for the Couchbase Developer Guide. + */ +public class HealthCheck extends ConnectionBase { + + +// public static void main(String... args) { + +// Cluster cluster = Cluster.connect("127.0.0.1", "Administrator", "password"); +// +// Bucket bucket = cluster.bucket("bucket-name"); +// Scope scope = bucket.scope("scope-name"); +// Collection collection = scope.collection("collection-name"); +// +// JsonObject json = JsonObject.create() +// .put("foo", "bar") +// .put("baz", "qux"); +// +// +// AsyncCollection asyncCollection = collection.async(); +// ReactiveCollection reactiveCollection = collection.reactive(); +// +// JsonObject content = JsonObject.create().put("foo", "bar"); +//// MutationResult result = collection.upsert("document-key", content); +// +// PingResult ping = bucket.ping(); + @Override + protected void doWork() { + + bucket.waitUntilReady(Duration.ofSeconds(5)); + + JsonObject content = JsonObject.create() + .put("foo", "bar") + .put("baz", "qux"); + + MutationResult result = collection.upsert("document-key", content); + + // Ping a specified bucket to look at the state of all associated endpoints + PingResult pingResult = bucket.ping(); + // Look at the KV endpoints and warn if their state is not OK + Map> pingEndpoints = pingResult.endpoints(); + List kvPingReports = pingEndpoints.get(ServiceType.KV); + + for (EndpointPingReport pingEndpoint : kvPingReports) { + if (pingEndpoint.state() != PingState.OK) { + LOGGER.warn(String.format("Node %s at remote %s is %s.", pingEndpoint.id(), pingEndpoint.remote(), pingEndpoint.state())); + } else { + LOGGER.info(String.format("Node %s at remote %s is OK.", pingEndpoint.id(), pingEndpoint.remote())); + } + } + + // Get all diagnostics associated with a given cluster, passively + DiagnosticsResult diagnosticsResult = cluster.diagnostics(); + Map> diagEndpoints = diagnosticsResult.endpoints(); + // Look at the KV connections, warn if not connected + List kvDiagReports = diagEndpoints.get(ServiceType.KV); + + for (EndpointDiagnostics diagEndpoint : kvDiagReports) { + // Identify the KV connection associated with the bucket we are using from the namespace + if (diagEndpoint.namespace().isPresent() && diagEndpoint.namespace().get().contentEquals(bucketName)) { + if (diagEndpoint.state() != EndpointState.CONNECTED) { + LOGGER.warn(String.format("Endpoint %s at remote %s is in state %s.", diagEndpoint.id(), diagEndpoint.remote(), diagEndpoint.state())); + } else { + LOGGER.info(String.format("Endpoint %s at remote %s connected.", diagEndpoint.id().orElse("NO_ID"), diagEndpoint.remote())); + } + } + } + } + + public static void main(String[] args) { + new HealthCheck().execute(); + } + + +} diff --git a/java/src/main/java/com/couchbase/devguide/QueryConsistency.java b/java/src/main/java/com/couchbase/devguide/QueryConsistency.java index 61c2351..d99bc2b 100644 --- a/java/src/main/java/com/couchbase/devguide/QueryConsistency.java +++ b/java/src/main/java/com/couchbase/devguide/QueryConsistency.java @@ -1,23 +1,31 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import static com.couchbase.client.java.query.Select.select; -import static com.couchbase.client.java.query.dsl.Expression.x; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions; +import com.couchbase.client.java.query.QueryOptions; +import com.couchbase.client.java.query.QueryResult; +import com.couchbase.client.java.query.QueryScanConsistency; +import com.couchbase.client.java.query.QueryStatus; import java.util.Random; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.JsonLongDocument; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.DocumentDoesNotExistException; -import com.couchbase.client.java.query.N1qlParams; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.Statement; -import com.couchbase.client.java.query.consistency.ScanConsistency; -import com.couchbase.client.java.query.dsl.functions.MetaFunctions; - /** * Example of N1QL Query Consistency in Java for the Couchbase Developer Guide. */ @@ -27,7 +35,7 @@ public class QueryConsistency extends ConnectionBase { protected void doWork() { String key = "javaDevguideExampleQueryConsistency"; - LOGGER.info("Please ensure there is a primary index on the default bucket!"); + cluster.queryIndexes().createPrimaryIndex(bucketName, CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true)); Random random = new Random(); int randomNumber = random.nextInt(10000000); @@ -37,30 +45,17 @@ protected void doWork() { .put("email", "brass.doorknob@juno.com") .put("random", randomNumber); //upsert it with the corresponding random key - JsonDocument doc = JsonDocument.create(key, user); //the same document will be updated with a random internal value - bucket.upsert(doc); - - //immediately query N1QL (note we imported relevant static methods) - //prepare the statement - Statement statement = select("name", "email", "random", "META(default).id") - .from("default") - .where(x("$1").in("name")); - - //configure the query - N1qlParams params = N1qlParams.build() - //If this line is removed, the latest 'random' field might not be present - .consistency(ScanConsistency.REQUEST_PLUS); - - N1qlQuery query = N1qlQuery.parameterized(statement, JsonArray.from("Brass"), params); + bucket.defaultCollection().upsert(key, user); LOGGER.info("Expecting random: " + randomNumber); - N1qlQueryResult result = bucket.query(query); - if (!result.finalSuccess() || result.allRows().isEmpty()) { - LOGGER.warn("No result/errors: " + result.errors().toString()); + QueryResult result = cluster.query("select name, email, random, META(default).id " + + " from default where $1 in name", + QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS).parameters(JsonArray.from("Brass"))); + if (!result.metaData().status().equals(QueryStatus.SUCCESS) ) { + LOGGER.warn("No result/errors: " + result.metaData().warnings()); } - for (N1qlQueryRow queryRow : result) { - JsonObject row = queryRow.value(); + for (JsonObject row : result.rowsAsObject()) { int rowRandom = row.getInt("random"); String rowId = row.getString("id"); @@ -74,7 +69,7 @@ protected void doWork() { } if (System.getProperty("REMOVE_DOORKNOBS") != null || System.getenv("REMOVE_DOORKNOBS") != null) { - bucket.remove(rowId); + bucket.defaultCollection().remove(rowId); } } } diff --git a/java/src/main/java/com/couchbase/devguide/QueryCriteria.java b/java/src/main/java/com/couchbase/devguide/QueryCriteria.java index b4b5200..eb8c1cc 100644 --- a/java/src/main/java/com/couchbase/devguide/QueryCriteria.java +++ b/java/src/main/java/com/couchbase/devguide/QueryCriteria.java @@ -1,14 +1,28 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import static com.couchbase.client.java.query.dsl.Expression.i; -import static com.couchbase.client.java.query.dsl.Expression.s; -import static com.couchbase.client.java.query.dsl.Expression.x; +import com.couchbase.client.core.error.ParsingFailureException; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.query.QueryMetaData; +import com.couchbase.client.java.query.QueryOptions; +import com.couchbase.client.java.query.QueryScanConsistency; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.Select; -import com.couchbase.client.java.query.Statement; +import java.util.List; /** * Example of Querying with N1QL in Java for the Couchbase Developer Guide. @@ -17,23 +31,37 @@ public class QueryCriteria extends ConnectionBase { @Override protected void doWork() { - String statement = "SELECT airportname, city, country FROM `travel-sample` WHERE type=\"airport\" AND city=\"Reno\""; - N1qlQuery query = N1qlQuery.simple(statement); + + JsonObject airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Reno International Airport") + .put("city", "Reno") + .put("country", "United States"); + + bucket.defaultCollection().upsert("1", airport); + + + String statement = "SELECT airportname, city, country FROM `default` WHERE type=\"airport\" AND city=\"Reno\""; LOGGER.info("Results from a simple statement:"); LOGGER.info(statement); - N1qlQueryResult result = bucket.query(query); - for (N1qlQueryRow row : result) { - LOGGER.info("\t" + row.value()); + List result = cluster.query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)).rowsAsObject(); + for (JsonObject row : result) { + LOGGER.info("\t" + row); } //when there is a server-side error, the server will feed errors in the result.error() collection //you can find that out by checking finalSuccess() == false //alternatively, syntax errors are also detected early and for them you can check parseSuccess() - N1qlQueryResult errorResult = bucket.query(N1qlQuery.simple("SELECTE * FROM `travel-sample` LIMIT 3")); - LOGGER.info("With bad syntax, parseSuccess = " + errorResult.parseSuccess() - + ", finalSuccess = " + errorResult.finalSuccess() + ", errors: " + errorResult.errors()); + try { + QueryMetaData errorResult = cluster.query("SELECTE * FROM `travel-sample` LIMIT 3") + .metaData(); + LOGGER.info("With bad syntax, finalSuccess = " + errorResult.status() + ", errors: " + errorResult.warnings()); + }catch (ParsingFailureException pf){ + System.out.println(pf); + } +/* //there is also a fluent API to construct N1QL statements, generally import static the Select.select method Statement fluentStatement = Select.select("airportname", "city", "country") @@ -54,7 +82,7 @@ protected void doWork() { //the result also contains metrics sent by the server LOGGER.info("Metrics: " + fluentResult.info()); - +*/ } public static void main(String[] args) { diff --git a/java/src/main/java/com/couchbase/devguide/QueryPlaceholders.java b/java/src/main/java/com/couchbase/devguide/QueryPlaceholders.java index aeb9a0c..3a60738 100644 --- a/java/src/main/java/com/couchbase/devguide/QueryPlaceholders.java +++ b/java/src/main/java/com/couchbase/devguide/QueryPlaceholders.java @@ -1,10 +1,26 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.json.JsonArray; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.ParameterizedN1qlQuery; +import com.couchbase.client.java.json.JsonArray; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.query.QueryOptions; + +import java.util.List; /** * Example of Querying using placeholders with N1QL in Java for the Couchbase Developer Guide. @@ -13,29 +29,65 @@ public class QueryPlaceholders extends ConnectionBase { private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$1 AND type=\"airport\""; - private N1qlQueryResult queryCity(String city) { + private List queryCity(String city) { + + //the placeholder values can be provided as a JSON array (if using $1 syntax) // or map-like JSON object (if using $name syntax) JsonArray placeholderValues = JsonArray.from(city); - - ParameterizedN1qlQuery query = N1qlQuery.parameterized(PLACEHOLDER_STATEMENT, placeholderValues); - return bucket.query(query); + return cluster.query("SELECT airportname FROM `default` WHERE city=$1 AND type=\"airport\"", + QueryOptions.queryOptions().parameters(placeholderValues)).rowsAsObject(); } @Override protected void doWork() { + + JsonObject airport; + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Reno International Airport") + .put("city", "Reno") + .put("country", "United States"); + + bucket.defaultCollection().upsert("1", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Los Angeles International Airport") + .put("city", "Los Angeles") + .put("country", "United States"); + + bucket.defaultCollection().upsert("2", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Culver City Airport") + .put("city", "Los Angeles") + .put("country", "United States"); + + bucket.defaultCollection().upsert("3", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Dallas International Airport") + .put("city", "Dallas") + .put("country", "United States"); + + bucket.defaultCollection().upsert("4", airport); + LOGGER.info("Airports in Reno: "); - for (N1qlQueryRow row : queryCity("Reno")) { + for (JsonObject row : queryCity("Reno")) { LOGGER.info("\t" + row); } LOGGER.info("Airports in Dallas: "); - for (N1qlQueryRow row : queryCity("Dallas")) { + for (JsonObject row : queryCity("Dallas")) { LOGGER.info("\t" + row); } LOGGER.info("Airports in Los Angeles: "); - for (N1qlQueryRow row : queryCity("Los Angeles")) { + for (JsonObject row : queryCity("Los Angeles")) { LOGGER.info("\t" + row); } } diff --git a/java/src/main/java/com/couchbase/devguide/QueryPrepared.java b/java/src/main/java/com/couchbase/devguide/QueryPrepared.java index 2176ec6..c149fcf 100644 --- a/java/src/main/java/com/couchbase/devguide/QueryPrepared.java +++ b/java/src/main/java/com/couchbase/devguide/QueryPrepared.java @@ -1,64 +1,94 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.query.N1qlParams; -import com.couchbase.client.java.query.N1qlQuery; -import com.couchbase.client.java.query.N1qlQueryResult; -import com.couchbase.client.java.query.N1qlQueryRow; -import com.couchbase.client.java.query.ParameterizedN1qlQuery; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.query.QueryOptions; + +import java.util.List; /** - * Example of Querying with N1QL and its Prepared Statement feature, in Java for the Couchbase Developer Guide. + * Example of Querying using placeholders with N1QL in Java for the Couchbase Developer Guide. */ public class QueryPrepared extends ConnectionBase { - private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$city AND type=\"airport\""; + private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$1 AND type=\"airport\""; - private N1qlQueryResult queryCity(String city, boolean optimize) { + private List queryCity(String city) { //the placeholder values can be provided as a JSON array (if using $1 syntax) // or map-like JSON object (if using $name syntax) - JsonObject placeholderValues = JsonObject.create().put("city", city); - - //the N1qlParams.adhoc(false) is used to trigger server-side optimizations, namely preparing - // the query and reusing the prepared data on subsequent calls - N1qlParams params = N1qlParams.build().adhoc(!optimize); - - ParameterizedN1qlQuery query = N1qlQuery.parameterized(PLACEHOLDER_STATEMENT, placeholderValues, params); - return bucket.query(query); + JsonObject placeholderValues = JsonObject.create().put("city",city); + return cluster.query("SELECT airportname FROM `travel-sample` WHERE city=$1 AND type=\"airport\"", + QueryOptions.queryOptions().parameters(placeholderValues)).rowsAsObject(); } @Override protected void doWork() { + JsonObject airport; + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Reno International Airport") + .put("city", "Reno") + .put("country", "United States"); + + bucket.defaultCollection().upsert("1", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Los Angeles International Airport") + .put("city", "Los Angeles") + .put("country", "United States"); + + bucket.defaultCollection().upsert("2", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Culver City Airport") + .put("city", "Los Angeles") + .put("country", "United States"); + + bucket.defaultCollection().upsert("3", airport); + + airport = JsonObject.create() + .put( "type", "airport") + .put("airportname", "Dallas International Airport") + .put("city", "Dallas") + .put("country", "United States"); + + bucket.defaultCollection().upsert("4", airport); + LOGGER.info("Airports in Reno: "); - N1qlQueryResult result = queryCity("Reno", true); - for (N1qlQueryRow row : result) { + for (JsonObject row : queryCity("Reno")) { LOGGER.info("\t" + row); } - LOGGER.info("1st query took " + result.info().executionTime()); - result = queryCity("Dallas", true); - LOGGER.info("\nAirports in Dallas: "); - for (N1qlQueryRow row : result) { + LOGGER.info("Airports in Dallas: "); + for (JsonObject row : queryCity("Dallas")) { LOGGER.info("\t" + row); } - LOGGER.info("2nd query took " + result.info().executionTime()); - LOGGER.info("\nAirports in Los Angeles: "); - result = queryCity("Los Angeles", true); - for (N1qlQueryRow row : result) { + LOGGER.info("Airports in Los Angeles: "); + for (JsonObject row : queryCity("Los Angeles")) { LOGGER.info("\t" + row); } - LOGGER.info("3rd query took " + result.info().executionTime()); - - LOGGER.info("\nCompare with unprepared (adhoc) query for Los Angeles: "); - LOGGER.info(queryCity("Los Angeles", false).info().executionTime()); - - //invalidateQueryCache empties the local cache of optimized statements, returning the previous count - //of such statements. - LOGGER.info("\nThe SDK prepared " + bucket.invalidateQueryCache() + " queries"); } public static void main(String[] args) { - new QueryPrepared().execute(); + new QueryPlaceholders().execute(); } } diff --git a/java/src/main/java/com/couchbase/devguide/Retrieving.java b/java/src/main/java/com/couchbase/devguide/Retrieving.java index af82f8c..855ddba 100644 --- a/java/src/main/java/com/couchbase/devguide/Retrieving.java +++ b/java/src/main/java/com/couchbase/devguide/Retrieving.java @@ -1,7 +1,24 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.core.error.DocumentNotFoundException; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.GetResult; /** * Example of Retrieving in Java for the Couchbase Developer Guide. @@ -12,16 +29,21 @@ public class Retrieving extends ConnectionBase { protected void doWork() { String key = "javaDevguideExampleRetrieving"; LOGGER.info("Getting non-existent key. Should fail.."); - JsonDocument nonExistentDocument = bucket.get("non-exist-document"); - if (nonExistentDocument == null) { - LOGGER.info("Got null for missing document, it doesn't exist!"); + try { + GetResult nonExistentDocument = bucket.defaultCollection() + .get("non-exist-document"); + if (nonExistentDocument == null) { + LOGGER.info("Got null for missing document, it doesn't exist!"); + } + } catch (DocumentNotFoundException dnf){ + System.out.println(dnf); } LOGGER.info("Upserting..."); - JsonDocument document = JsonDocument.create(key, JsonObject.create().put("foo", "bar")); - bucket.upsert(document); + JsonObject document = JsonObject.create().put("foo", "bar"); + bucket.defaultCollection().upsert(key,document); LOGGER.info("Getting..."); - LOGGER.info(bucket.get(key)); + LOGGER.info(bucket.defaultCollection().get(key)); } public static void main(String[] args) { diff --git a/java/src/main/java/com/couchbase/devguide/Updating.java b/java/src/main/java/com/couchbase/devguide/Updating.java index 8fca252..7f6d797 100644 --- a/java/src/main/java/com/couchbase/devguide/Updating.java +++ b/java/src/main/java/com/couchbase/devguide/Updating.java @@ -1,8 +1,24 @@ +/* + * Copyright (c) 2020 Couchbase, Inc. + * + * Licensed 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 com.couchbase.devguide; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; -import com.couchbase.client.java.error.DocumentAlreadyExistsException; +import com.couchbase.client.core.error.DocumentExistsException; +import com.couchbase.client.java.json.JsonObject; +import com.couchbase.client.java.kv.MutationResult; /** * Example of Updating/Storing in Java for the Couchbase Developer Guide. @@ -15,28 +31,26 @@ protected void doWork() { //create content JsonObject content = JsonObject.create().put("topic", "storing").put("mutation", true); - //create document - JsonDocument document = JsonDocument.create(key, content); - LOGGER.info("Prepared document " + document); + LOGGER.info("Prepared document " + content); //store the document (upsert will always work whether or not a value is already associated to the key) - document = bucket.upsert(document); - LOGGER.info("Document after upsert: " + document); //notice the CAS changed (the returned document is updated with correct CAS) + MutationResult result = bucket.defaultCollection().upsert( key, content); + LOGGER.info("Result after upsert: " + result); //notice the CAS changed (the returned document is updated with correct CAS) //prepare an update - document.content().put("update", "something"); + content.put("update", "something"); //see that inserting it fails because it already exists try { - bucket.insert(document); - } catch (DocumentAlreadyExistsException e) { + bucket.defaultCollection().insert(key,content); + } catch (DocumentExistsException e) { LOGGER.warn("Couldn't insert it, DocumentAlreadyExists... Let's try to replace it"); } //on the other hand, updating works (it would have failed if the key was not in database) - document = bucket.replace(document); - LOGGER.info("Replaced the old document by the new one: " + document); //notice the document's CAS changed again... + result = bucket.defaultCollection().replace(key,content); + LOGGER.info("Replaced the old document by the new one: " + result); //notice the document's CAS changed again... - LOGGER.info("Got the following from database: " + bucket.get(key)); //... which is consistent with a get (RYOW) + LOGGER.info("Got the following from database: " + bucket.defaultCollection().get(key)); //... which is consistent with a get (RYOW) } public static void main(String[] args) { diff --git a/java/src/main/resources/log4j.properties b/java/src/main/resources/log4j.properties index 5fa53de..eca11da 100644 --- a/java/src/main/resources/log4j.properties +++ b/java/src/main/resources/log4j.properties @@ -13,4 +13,21 @@ log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.appender.shortstdout=org.apache.log4j.ConsoleAppender log4j.appender.shortstdout.Target=System.out log4j.appender.shortstdout.layout=org.apache.log4j.PatternLayout -log4j.appender.shortstdout.layout.ConversionPattern=%d{HH:mm:ss} %m%n \ No newline at end of file +log4j.appender.shortstdout.layout.ConversionPattern=%d{HH:mm:ss} %m%n + +#log4j.logger.com.couchbase=INFO, stdout +#log4j.logger.reactor.util=INFO, stdout + +# -Dlog4j.debug +# +# org.slf4j +# slf4j-log4j12 +# ${slf4j.version} +# +# +# +# log4j +# log4j +# ${log4j.version} +# +#