From 91c57354ccac023cfcd67ff62bd14836c6b6822c Mon Sep 17 00:00:00 2001 From: Seun Matt Date: Tue, 19 Sep 2017 12:23:09 +0100 Subject: [PATCH] rename module to couchbase --- couchbase/.gitignore | 6 + couchbase/README.md | 51 ++++ couchbase/mvnw | 233 ++++++++++++++++ couchbase/mvnw.cmd | 145 ++++++++++ couchbase/pom.xml | 82 ++++++ .../couchbase/async/CouchbaseEntity.java | 9 + .../couchbase/async/person/Person.java | 90 +++++++ .../async/person/PersonCrudService.java | 24 ++ .../async/person/PersonDocumentConverter.java | 28 ++ .../async/person/RegistrationService.java | 28 ++ .../async/service/AbstractBucketService.java | 27 ++ .../async/service/AbstractCrudService.java | 142 ++++++++++ .../async/service/BucketService.java | 8 + .../async/service/ClusterService.java | 8 + .../async/service/ClusterServiceImpl.java | 36 +++ .../couchbase/async/service/CrudService.java | 26 ++ .../async/service/JsonDocumentConverter.java | 10 + .../async/service/TutorialBucketService.java | 32 +++ .../couchbase/intro/CodeSnippets.java | 87 ++++++ .../mapreduce/CouchbaseKeyGenerator.java | 6 + .../mapreduce/DuplicateKeyException.java | 10 + .../mapreduce/RandomUUIDGenerator.java | 11 + .../couchbase/mapreduce/StudentGrade.java | 50 ++++ .../mapreduce/StudentGradeKeyGenerator.java | 9 + .../mapreduce/StudentGradeQueryBuilder.java | 70 +++++ .../mapreduce/StudentGradeService.java | 169 ++++++++++++ .../couchbase/n1ql/BucketFactory.java | 26 ++ .../baeldung/couchbase/n1ql/CodeSnippets.java | 34 +++ .../couchbase/spring/person/Person.java | 86 ++++++ .../spring/person/PersonCrudService.java | 69 +++++ .../person/PersonDocumentConverter.java | 28 ++ .../spring/person/RegistrationService.java | 28 ++ .../spring/service/BucketService.java | 9 + .../spring/service/ClusterService.java | 17 ++ .../spring/service/ClusterServiceImpl.java | 81 ++++++ .../couchbase/spring/service/CrudService.java | 16 ++ .../spring/service/JsonDocumentConverter.java | 10 + .../spring/service/TutorialBucketService.java | 29 ++ .../src/main/resources/application.properties | 0 couchbase/src/main/resources/logback.xml | 19 ++ .../couchbase/async/AsyncIntegrationTest.java | 13 + .../async/AsyncIntegrationTestConfig.java | 9 + .../PersonCrudServiceIntegrationTest.java | 216 +++++++++++++++ .../ClusterServiceIntegrationTest.java | 35 +++ .../StudentGradeServiceIntegrationTest.java | 150 +++++++++++ .../couchbase/n1ql/IntegrationTestConfig.java | 26 ++ .../couchbase/n1ql/N1QLIntegrationTest.java | 248 ++++++++++++++++++ .../couchbase/spring/IntegrationTest.java | 13 + .../spring/IntegrationTestConfig.java | 9 + .../PersonCrudServiceIntegrationTest.java | 75 ++++++ .../ClusterServiceIntegrationTest.java | 34 +++ couchbase/src/test/resources/logback.xml | 19 ++ 52 files changed, 2696 insertions(+) create mode 100644 couchbase/.gitignore create mode 100644 couchbase/README.md create mode 100644 couchbase/mvnw create mode 100644 couchbase/mvnw.cmd create mode 100644 couchbase/pom.xml create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java create mode 100644 couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java create mode 100644 couchbase/src/main/resources/application.properties create mode 100644 couchbase/src/main/resources/logback.xml create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java create mode 100644 couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java create mode 100644 couchbase/src/test/resources/logback.xml diff --git a/couchbase/.gitignore b/couchbase/.gitignore new file mode 100644 index 0000000000..f6867e01bd --- /dev/null +++ b/couchbase/.gitignore @@ -0,0 +1,6 @@ +# Created by .ignore support plugin (hsz.mobi) + +# IntelliJ project files +.idea +*.iml +/target/ diff --git a/couchbase/README.md b/couchbase/README.md new file mode 100644 index 0000000000..f124a0192c --- /dev/null +++ b/couchbase/README.md @@ -0,0 +1,51 @@ +## Couchbase SDK Tutorial Project + +### Relevant Articles: +- [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk) +- [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring) +- [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) +- [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view) + +### Overview +This Maven project contains the Java code for the Couchbase entities and Spring services +as described in the tutorials, as well as a unit/integration test +for each service implementation. + +### Working with the Code +The project was developed and tested using Java 7 and 8 in the Eclipse-based +Spring Source Toolkit (STS) and therefore should run fine in any +recent version of Eclipse or another IDE of your choice +that supports Java 7 or later. + +### Building the Project +You can also build the project using Maven outside of any IDE: +``` +mvn clean install +``` + +### Package Organization +Java classes for the intro tutorial are in the +org.baeldung.couchbase.intro package. + +Java classes for the Spring service tutorial are in the +org.baeldung.couchbase.spring package hierarchy. + +Java classes for the Asynchronous Couchbase tutorial are in the +org.baeldung.couchbase.async package hierarchy. + + +### Running the tests +The test classes for the Spring service tutorial are: +- org.baeldung.couchbase.spring.service.ClusterServiceTest +- org.baeldung.couchbase.spring.person.PersonCrudServiceTest + +The test classes for the Asynchronous Couchbase tutorial are in the +org.baeldung.couchbase.async package hierarchy: +- org.baeldung.couchbase.async.service.ClusterServiceTest +- org.baeldung.couchbase.async.person.PersonCrudServiceTest + +The test classes may be run as JUnit tests from your IDE +or using the Maven command line: +``` +mvn test +``` diff --git a/couchbase/mvnw b/couchbase/mvnw new file mode 100644 index 0000000000..a1ba1bf554 --- /dev/null +++ b/couchbase/mvnw @@ -0,0 +1,233 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} "$@" diff --git a/couchbase/mvnw.cmd b/couchbase/mvnw.cmd new file mode 100644 index 0000000000..2b934e89dd --- /dev/null +++ b/couchbase/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% \ No newline at end of file diff --git a/couchbase/pom.xml b/couchbase/pom.xml new file mode 100644 index 0000000000..819c53b038 --- /dev/null +++ b/couchbase/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + com.baeldung + couchbase-sdk + 0.1-SNAPSHOT + jar + couchbase-sdk + Couchbase SDK Tutorials + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + com.couchbase.client + java-client + ${couchbase.client.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + + + org.springframework + spring-context + ${spring-framework.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-context-support + ${spring-framework.version} + + + commons-logging + commons-logging + + + + + + + org.springframework + spring-test + ${spring-framework.version} + test + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + test + + + + + 1.8 + UTF-8 + 2.5.0 + 4.3.5.RELEASE + 3.5 + 2.9.1 + + + diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java b/couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java new file mode 100644 index 0000000000..8f459e364f --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.async; + +public interface CouchbaseEntity { + + String getId(); + + void setId(String id); + +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java new file mode 100644 index 0000000000..f1135a32a2 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java @@ -0,0 +1,90 @@ +package com.baeldung.couchbase.async.person; + +import com.baeldung.couchbase.async.CouchbaseEntity; + +public class Person implements CouchbaseEntity { + + private String id; + private String type; + private String name; + private String homeTown; + + Person() { + } + + public Person(Builder b) { + this.id = b.id; + this.type = b.type; + this.name = b.name; + this.homeTown = b.homeTown; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHomeTown() { + return homeTown; + } + + public void setHomeTown(String homeTown) { + this.homeTown = homeTown; + } + + public static class Builder { + private String id; + private String type; + private String name; + private String homeTown; + + public static Builder newInstance() { + return new Builder(); + } + + public Person build() { + return new Person(this); + } + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder type(String type) { + this.type = type; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder homeTown(String homeTown) { + this.homeTown = homeTown; + return this; + } + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java new file mode 100644 index 0000000000..407bc7ee1c --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java @@ -0,0 +1,24 @@ +package com.baeldung.couchbase.async.person; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import com.baeldung.couchbase.async.service.AbstractCrudService; +import com.baeldung.couchbase.async.service.BucketService; + +@Service +public class PersonCrudService extends AbstractCrudService { + + @Autowired + public PersonCrudService(@Qualifier("TutorialBucketService") BucketService bucketService, PersonDocumentConverter converter) { + super(bucketService, converter); + } + + @PostConstruct + private void init() { + loadBucket(); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java new file mode 100644 index 0000000000..0f08679ace --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java @@ -0,0 +1,28 @@ +package com.baeldung.couchbase.async.person; + +import org.springframework.stereotype.Service; + +import com.baeldung.couchbase.async.service.JsonDocumentConverter; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.document.json.JsonObject; + +@Service +public class PersonDocumentConverter implements JsonDocumentConverter { + + @Override + public JsonDocument toDocument(Person p) { + JsonObject content = JsonObject.empty().put("type", "Person").put("name", p.getName()).put("homeTown", p.getHomeTown()); + return JsonDocument.create(p.getId(), content); + } + + @Override + public Person fromDocument(JsonDocument doc) { + JsonObject content = doc.content(); + Person p = new Person(); + p.setId(doc.id()); + p.setType("Person"); + p.setName(content.getString("name")); + p.setHomeTown(content.getString("homeTown")); + return p; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java new file mode 100644 index 0000000000..7cbc3625db --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java @@ -0,0 +1,28 @@ +package com.baeldung.couchbase.async.person; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.couchbase.client.core.CouchbaseException; + +@Service +public class RegistrationService { + + @Autowired + private PersonCrudService crud; + + public void registerNewPerson(String name, String homeTown) { + Person person = new Person(); + person.setName(name); + person.setHomeTown(homeTown); + crud.create(person); + } + + public Person findRegistrant(String id) { + try { + return crud.read(id); + } catch (CouchbaseException e) { + return crud.readFromReplica(id); + } + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java new file mode 100644 index 0000000000..1180ea00a6 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java @@ -0,0 +1,27 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public abstract class AbstractBucketService implements BucketService { + + private ClusterService clusterService; + + private Bucket bucket; + + protected void openBucket() { + bucket = clusterService.openBucket(getBucketName(), getBucketPassword()); + } + + protected abstract String getBucketName(); + + protected abstract String getBucketPassword(); + + public AbstractBucketService(ClusterService clusterService) { + this.clusterService = clusterService; + } + + @Override + public Bucket getBucket() { + return bucket; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java new file mode 100644 index 0000000000..089cc55d5d --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java @@ -0,0 +1,142 @@ +package com.baeldung.couchbase.async.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.couchbase.async.CouchbaseEntity; +import com.couchbase.client.core.BackpressureException; +import com.couchbase.client.core.time.Delay; +import com.couchbase.client.java.AsyncBucket; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.ReplicaMode; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.util.retry.RetryBuilder; + +import rx.Observable; +import rx.functions.Action1; +import rx.functions.Func1; + +public abstract class AbstractCrudService implements CrudService { + + private static final Logger logger = LoggerFactory.getLogger(AbstractCrudService.class); + + private BucketService bucketService; + private Bucket bucket; + private JsonDocumentConverter converter; + + public AbstractCrudService(BucketService bucketService, JsonDocumentConverter converter) { + this.bucketService = bucketService; + this.converter = converter; + } + + protected void loadBucket() { + bucket = bucketService.getBucket(); + } + + @Override + public void create(T t) { + if (t.getId() == null) { + t.setId(UUID.randomUUID().toString()); + } + JsonDocument doc = converter.toDocument(t); + bucket.insert(doc); + } + + @Override + public T read(String id) { + JsonDocument doc = bucket.get(id); + return (doc == null ? null : converter.fromDocument(doc)); + } + + @Override + public T readFromReplica(String id) { + List docs = bucket.getFromReplica(id, ReplicaMode.FIRST); + return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0))); + } + + @Override + public void update(T t) { + JsonDocument doc = converter.toDocument(t); + bucket.upsert(doc); + } + + @Override + public void delete(String id) { + bucket.remove(id); + } + + @Override + public List readBulk(Iterable ids) { + final AsyncBucket asyncBucket = bucket.async(); + Observable asyncOperation = Observable.from(ids).flatMap(new Func1>() { + public Observable call(String key) { + return asyncBucket.get(key); + } + }); + + final List items = new ArrayList(); + try { + asyncOperation.toBlocking().forEach(new Action1() { + public void call(JsonDocument doc) { + T item = converter.fromDocument(doc); + items.add(item); + } + }); + } catch (Exception e) { + logger.error("Error during bulk get", e); + } + + return items; + } + + @Override + public void createBulk(Iterable items) { + final AsyncBucket asyncBucket = bucket.async(); + Observable.from(items).flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(final T t) { + if (t.getId() == null) { + t.setId(UUID.randomUUID().toString()); + } + JsonDocument doc = converter.toDocument(t); + return asyncBucket.insert(doc).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build()); + } + }).last().toBlocking().single(); + } + + @Override + public void updateBulk(Iterable items) { + final AsyncBucket asyncBucket = bucket.async(); + Observable.from(items).flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(final T t) { + JsonDocument doc = converter.toDocument(t); + return asyncBucket.upsert(doc).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build()); + } + }).last().toBlocking().single(); + } + + @Override + public void deleteBulk(Iterable ids) { + final AsyncBucket asyncBucket = bucket.async(); + Observable.from(ids).flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(String key) { + return asyncBucket.remove(key).retryWhen(RetryBuilder.anyOf(BackpressureException.class).delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)).max(10).build()); + } + }).last().toBlocking().single(); + } + + @Override + public boolean exists(String id) { + return bucket.exists(id); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java new file mode 100644 index 0000000000..28470be99f --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java @@ -0,0 +1,8 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public interface BucketService { + + Bucket getBucket(); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java new file mode 100644 index 0000000000..7bf891244f --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java @@ -0,0 +1,8 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public interface ClusterService { + + Bucket openBucket(String name, String password); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java new file mode 100644 index 0000000000..e708922988 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java @@ -0,0 +1,36 @@ +package com.baeldung.couchbase.async.service; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.annotation.PostConstruct; + +import org.springframework.stereotype.Service; + +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; + +@Service +public class ClusterServiceImpl implements ClusterService { + + private Cluster cluster; + private Map buckets = new ConcurrentHashMap<>(); + + @PostConstruct + private void init() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create(); + cluster = CouchbaseCluster.create(env, "localhost"); + } + + @Override + synchronized public Bucket openBucket(String name, String password) { + if (!buckets.containsKey(name)) { + Bucket bucket = cluster.openBucket(name, password); + buckets.put(name, bucket); + } + return buckets.get(name); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java new file mode 100644 index 0000000000..5bd0e52214 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.async.service; + +import java.util.List; + +public interface CrudService { + + void create(T t); + + T read(String id); + + T readFromReplica(String id); + + void update(T t); + + void delete(String id); + + List readBulk(Iterable ids); + + void createBulk(Iterable items); + + void updateBulk(Iterable items); + + void deleteBulk(Iterable ids); + + boolean exists(String id); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java new file mode 100644 index 0000000000..193e91016a --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java @@ -0,0 +1,10 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.document.JsonDocument; + +public interface JsonDocumentConverter { + + JsonDocument toDocument(T t); + + T fromDocument(JsonDocument doc); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java new file mode 100644 index 0000000000..459585d995 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java @@ -0,0 +1,32 @@ +package com.baeldung.couchbase.async.service; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("TutorialBucketService") +public class TutorialBucketService extends AbstractBucketService { + + @PostConstruct + void init() { + openBucket(); + } + + @Autowired + public TutorialBucketService(ClusterService clusterService) { + super(clusterService); + } + + @Override + protected String getBucketName() { + return "baeldung-tutorial"; + } + + @Override + protected String getBucketPassword() { + return ""; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java b/couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java new file mode 100644 index 0000000000..e7bddc6442 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java @@ -0,0 +1,87 @@ +package com.baeldung.couchbase.intro; + +import java.util.List; +import java.util.UUID; + +import com.couchbase.client.core.CouchbaseException; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.CouchbaseCluster; +import com.couchbase.client.java.ReplicaMode; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +public class CodeSnippets { + + static Cluster loadClusterWithDefaultEnvironment() { + return CouchbaseCluster.create("localhost"); + } + + static Cluster loadClusterWithCustomEnvironment() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().connectTimeout(10000).kvTimeout(3000).build(); + return CouchbaseCluster.create(env, "localhost"); + } + + static Bucket loadDefaultBucketWithBlankPassword(Cluster cluster) { + return cluster.openBucket(); + } + + static Bucket loadBaeldungBucket(Cluster cluster) { + return cluster.openBucket("baeldung", ""); + } + + static JsonDocument insertExample(Bucket bucket) { + JsonObject content = JsonObject.empty().put("name", "John Doe").put("type", "Person").put("email", "john.doe@mydomain.com").put("homeTown", "Chicago"); + String id = UUID.randomUUID().toString(); + JsonDocument document = JsonDocument.create(id, content); + JsonDocument inserted = bucket.insert(document); + return inserted; + } + + static JsonDocument retrieveAndUpsertExample(Bucket bucket, String id) { + JsonDocument document = bucket.get(id); + JsonObject content = document.content(); + content.put("homeTown", "Kansas City"); + JsonDocument upserted = bucket.upsert(document); + return upserted; + } + + static JsonDocument replaceExample(Bucket bucket, String id) { + JsonDocument document = bucket.get(id); + JsonObject content = document.content(); + content.put("homeTown", "Milwaukee"); + JsonDocument replaced = bucket.replace(document); + return replaced; + } + + static JsonDocument removeExample(Bucket bucket, String id) { + JsonDocument removed = bucket.remove(id); + return removed; + } + + static JsonDocument getFirstFromReplicaExample(Bucket bucket, String id) { + try { + return bucket.get(id); + } catch (CouchbaseException e) { + List list = bucket.getFromReplica(id, ReplicaMode.FIRST); + if (!list.isEmpty()) { + return list.get(0); + } + } + return null; + } + + static JsonDocument getLatestReplicaVersion(Bucket bucket, String id) { + long maxCasValue = -1; + JsonDocument latest = null; + for (JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) { + if (replica.cas() > maxCasValue) { + latest = replica; + maxCasValue = replica.cas(); + } + } + return latest; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java new file mode 100644 index 0000000000..9ac1bbb3f7 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java @@ -0,0 +1,6 @@ +package com.baeldung.couchbase.mapreduce; + +public interface CouchbaseKeyGenerator { + + String generateKey(T t); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java new file mode 100644 index 0000000000..78baaa155c --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java @@ -0,0 +1,10 @@ +package com.baeldung.couchbase.mapreduce; + +@SuppressWarnings("serial") +public class DuplicateKeyException extends Exception { + + public DuplicateKeyException(String s) { + super(s); + } + +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java new file mode 100644 index 0000000000..9baf4a4f43 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java @@ -0,0 +1,11 @@ +package com.baeldung.couchbase.mapreduce; + +import java.util.UUID; + +public class RandomUUIDGenerator implements CouchbaseKeyGenerator { + + @Override + public String generateKey(T t) { + return UUID.randomUUID().toString(); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java new file mode 100644 index 0000000000..846aba716a --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java @@ -0,0 +1,50 @@ +package com.baeldung.couchbase.mapreduce; + +public class StudentGrade { + + private String name; + private String course; + private Integer grade; + private Integer hours; + + public StudentGrade() { } + + public StudentGrade(String name, String course, Integer grade, Integer hours) { + this.name = name; + this.course = course; + this.grade = grade; + this.hours = hours; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCourse() { + return course; + } + + public void setCourse(String course) { + this.course = course; + } + + public Integer getGrade() { + return grade; + } + + public void setGrade(Integer grade) { + this.grade = grade; + } + + public Integer getHours() { + return hours; + } + + public void setHours(Integer hours) { + this.hours = hours; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java new file mode 100644 index 0000000000..680e37ba57 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.mapreduce; + +public class StudentGradeKeyGenerator implements CouchbaseKeyGenerator { + + @Override + public String generateKey(StudentGrade g) { + return g.getName() + ":" + g.getCourse(); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java new file mode 100644 index 0000000000..37bb03645a --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java @@ -0,0 +1,70 @@ +package com.baeldung.couchbase.mapreduce; + +import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper; +import com.couchbase.client.java.document.json.JsonArray; +import com.couchbase.client.java.view.ViewQuery; + +public class StudentGradeQueryBuilder { + + final ObjectMapper om = new ObjectMapper(); + + public ViewQuery findAll() { + return ViewQuery.from("studentGrades", "findByCourse"); + } + + public ViewQuery findByCourse(String course) { + return ViewQuery.from("studentGrades", "findByCourse") + .key(course); + } + + public ViewQuery findByCourses(String... courses) { + return ViewQuery.from("studentGrades", "findByCourse") + .keys(JsonArray.from(courses)); + } + + public ViewQuery findByGradeInRange(int lower, int upper, boolean inclusiveEnd) { + return ViewQuery.from("studentGrades", "findByGrade") + .startKey(lower) + .endKey(upper) + .inclusiveEnd(inclusiveEnd); + } + + public ViewQuery findByGradeLessThan(int upper) { + return ViewQuery.from("studentGrades", "findByGrade") + .endKey(upper) + .inclusiveEnd(false); + } + + public ViewQuery findByGradeGreaterThan(int lower) { + return ViewQuery.from("studentGrades", "findByGrade") + .startKey(lower); + } + + public ViewQuery findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) { + return ViewQuery.from("studentGrades", "findByCourseAndGrade") + .startKey(JsonArray.from(course, minGrade)) + .endKey(JsonArray.from(course, maxGrade)) + .inclusiveEnd(inclusiveEnd); + } + + public ViewQuery findTopGradesByCourse(String course, int limit) { + return ViewQuery.from("studentGrades", "findByCourseAndGrade") + .startKey(JsonArray.from(course, 100)) + .endKey(JsonArray.from(course, 0)) + .inclusiveEnd(true) + .descending() + .limit(limit); + } + + public ViewQuery countStudentsByCourse() { + return ViewQuery.from("studentGrades", "countStudentsByCourse") + .reduce() + .groupLevel(1); + } + + public ViewQuery sumCreditsByStudent() { + return ViewQuery.from("studentGrades", "sumCreditsByStudent") + .reduce() + .groupLevel(1); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java new file mode 100644 index 0000000000..2d2c63f699 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java @@ -0,0 +1,169 @@ +package com.baeldung.couchbase.mapreduce; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper; +import com.couchbase.client.java.Bucket; +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.view.ViewQuery; +import com.couchbase.client.java.view.ViewResult; +import com.couchbase.client.java.view.ViewRow; + +public class StudentGradeService { + + final CouchbaseKeyGenerator keyGenerator; + final CouchbaseCluster cluster; + final Bucket bucket; + final ObjectMapper om = new ObjectMapper(); + final StudentGradeQueryBuilder queryBuilder; + + public StudentGradeService(CouchbaseKeyGenerator keyGenerator) { + this.keyGenerator = keyGenerator; + this.queryBuilder = new StudentGradeQueryBuilder(); + cluster = CouchbaseCluster.create("127.0.0.1"); + bucket = cluster.openBucket("baeldung-tutorial"); + } + + public String insert(StudentGrade studentGrade) throws DuplicateKeyException { + String id = keyGenerator.generateKey(studentGrade); + if(bucket.exists(id)) { + throw new DuplicateKeyException("document already exists with key " + id); + } + JsonObject content = JsonObject.empty() + .put("type", "StudentGrade") + .put("name", studentGrade.getName()) + .put("course", studentGrade.getCourse()) + .put("grade", studentGrade.getGrade()) + .put("hours", studentGrade.getHours()); + JsonDocument doc = JsonDocument.create(id, content); + bucket.insert(doc); + return id; + } + + public List findAll() { + ViewQuery query = queryBuilder.findAll(); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + private List extractDocuments(ViewResult result) { + List docs = new ArrayList<>(); + for(ViewRow row : result.allRows()) { + JsonDocument doc = row.document(); + docs.add(doc); + } + return docs; + } + + public List findByCourse(String course) { + ViewQuery query = queryBuilder.findByCourse(course); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findByCourses(String... courses) { + ViewQuery query = queryBuilder.findByCourses(courses); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findByGradeInRange(int lower, int upper, boolean inclusiveEnd) { + ViewQuery query = queryBuilder.findByGradeInRange(lower, upper, inclusiveEnd); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findByGradeLessThan(int upper) { + ViewQuery query = queryBuilder.findByGradeLessThan(upper); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findByGradeGreaterThan(int lower) { + ViewQuery query = queryBuilder.findByGradeGreaterThan(lower); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) { + ViewQuery query = queryBuilder.findByCourseAndGradeInRange(course, minGrade, maxGrade, inclusiveEnd); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public List findTopGradesByCourse(String course, int limit) { + ViewQuery query = queryBuilder.findTopGradesByCourse(course, limit); + ViewResult result = bucket.query(query); + return extractDocuments(result); + } + + public Map countStudentsByCourse() { + ViewQuery query = ViewQuery.from("studentGrades", "countStudentsByCourse") + .reduce() + .groupLevel(1); + ViewResult result = bucket.query(query); + + Map numStudentsByCourse = new HashMap<>(); + for(ViewRow row : result.allRows()) { + JsonArray keyArray = (JsonArray) row.key(); + String course = keyArray.getString(0); + long count = Long.valueOf(row.value().toString()); + numStudentsByCourse.put(course, count); + } + + return numStudentsByCourse; + } + + public Map sumCreditHoursByStudent() { + ViewQuery query = ViewQuery.from("studentGrades", "sumHoursByStudent") + .reduce() + .groupLevel(1); + ViewResult result = bucket.query(query); + + Map creditHoursByStudent = new HashMap<>(); + for(ViewRow row : result.allRows()) { + String course = (String) row.key(); + long sum = Long.valueOf(row.value().toString()); + creditHoursByStudent.put(course, sum); + } + + return creditHoursByStudent; + } + + public Map sumGradePointsByStudent() { + ViewQuery query = ViewQuery.from("studentGrades", "sumGradePointsByStudent") + .reduce() + .groupLevel(1); + ViewResult result = bucket.query(query); + + Map gradePointsByStudent = new HashMap<>(); + for(ViewRow row : result.allRows()) { + String course = (String) row.key(); + long sum = Long.valueOf(row.value().toString()); + gradePointsByStudent.put(course, sum); + } + + return gradePointsByStudent; + } + + public Map calculateGpaByStudent() { + Map creditHoursByStudent = sumCreditHoursByStudent(); + Map gradePointsByStudent = sumGradePointsByStudent(); + + Map result = new HashMap<>(); + for(Entry creditHoursEntry : creditHoursByStudent.entrySet()) { + String name = creditHoursEntry.getKey(); + long totalHours = creditHoursEntry.getValue(); + long totalGradePoints = gradePointsByStudent.get(name); + result.put(name, ((float) totalGradePoints / totalHours)); + } + return result; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java new file mode 100644 index 0000000000..98fbe17e60 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class BucketFactory { + + @Autowired + private Cluster cluster; + + private Bucket travelSampleBucket; + private Bucket testBucket; + + public Bucket getTravelSampleBucket() { + return (travelSampleBucket != null) ? + travelSampleBucket : cluster.openBucket("travel-sample"); + } + + public Bucket getTestBucket() { + return (testBucket != null) ? + testBucket : cluster.openBucket("test"); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java new file mode 100644 index 0000000000..45067911cb --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java @@ -0,0 +1,34 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.query.N1qlQueryResult; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public class CodeSnippets { + + private static ObjectMapper objectMapper = new ObjectMapper(); + + private static final Logger logger = Logger.getLogger(CodeSnippets.class.getName()); + + public static List extractJsonResult(N1qlQueryResult result) { + return result.allRows().stream() + .map(row -> { + try { + return objectMapper.readTree(row.value().toString()); + }catch (IOException e) { + logger.log(Level.WARNING, e.getLocalizedMessage()); + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java new file mode 100644 index 0000000000..403b7c8d3b --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java @@ -0,0 +1,86 @@ +package com.baeldung.couchbase.spring.person; + +public class Person { + + private String id; + private String type; + private String name; + private String homeTown; + + Person() { + } + + public Person(Builder b) { + this.id = b.id; + this.type = b.type; + this.name = b.name; + this.homeTown = b.homeTown; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHomeTown() { + return homeTown; + } + + public void setHomeTown(String homeTown) { + this.homeTown = homeTown; + } + + public static class Builder { + private String id; + private String type; + private String name; + private String homeTown; + + public static Builder newInstance() { + return new Builder(); + } + + public Person build() { + return new Person(this); + } + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder type(String type) { + this.type = type; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder homeTown(String homeTown) { + this.homeTown = homeTown; + return this; + } + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java new file mode 100644 index 0000000000..163f6417ca --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java @@ -0,0 +1,69 @@ +package com.baeldung.couchbase.spring.person; + +import java.util.List; +import java.util.UUID; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.couchbase.spring.service.CrudService; +import com.baeldung.couchbase.spring.service.TutorialBucketService; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.ReplicaMode; +import com.couchbase.client.java.document.JsonDocument; + +@Service +public class PersonCrudService implements CrudService { + + @Autowired + private TutorialBucketService bucketService; + + @Autowired + private PersonDocumentConverter converter; + + private Bucket bucket; + + @PostConstruct + private void init() { + bucket = bucketService.getBucket(); + } + + @Override + public void create(Person person) { + if (person.getId() == null) { + person.setId(UUID.randomUUID().toString()); + } + JsonDocument document = converter.toDocument(person); + bucket.insert(document); + } + + @Override + public Person read(String id) { + JsonDocument doc = bucket.get(id); + return (doc != null ? converter.fromDocument(doc) : null); + } + + @Override + public Person readFromReplica(String id) { + List docs = bucket.getFromReplica(id, ReplicaMode.FIRST); + return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0))); + } + + @Override + public void update(Person person) { + JsonDocument document = converter.toDocument(person); + bucket.upsert(document); + } + + @Override + public void delete(String id) { + bucket.remove(id); + } + + @Override + public boolean exists(String id) { + return bucket.exists(id); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java new file mode 100644 index 0000000000..71108d16dd --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java @@ -0,0 +1,28 @@ +package com.baeldung.couchbase.spring.person; + +import org.springframework.stereotype.Service; + +import com.baeldung.couchbase.spring.service.JsonDocumentConverter; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.document.json.JsonObject; + +@Service +public class PersonDocumentConverter implements JsonDocumentConverter { + + @Override + public JsonDocument toDocument(Person p) { + JsonObject content = JsonObject.empty().put("type", "Person").put("name", p.getName()).put("homeTown", p.getHomeTown()); + return JsonDocument.create(p.getId(), content); + } + + @Override + public Person fromDocument(JsonDocument doc) { + JsonObject content = doc.content(); + Person p = new Person(); + p.setId(doc.id()); + p.setType("Person"); + p.setName(content.getString("name")); + p.setHomeTown(content.getString("homeTown")); + return p; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java new file mode 100644 index 0000000000..cad3bdd5a5 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java @@ -0,0 +1,28 @@ +package com.baeldung.couchbase.spring.person; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.couchbase.client.core.CouchbaseException; + +@Service +public class RegistrationService { + + @Autowired + private PersonCrudService crud; + + public void registerNewPerson(String name, String homeTown) { + Person person = new Person(); + person.setName(name); + person.setHomeTown(homeTown); + crud.create(person); + } + + public Person findRegistrant(String id) { + try { + return crud.read(id); + } catch (CouchbaseException e) { + return crud.readFromReplica(id); + } + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java new file mode 100644 index 0000000000..1ea9c72114 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.spring.service; + +import com.couchbase.client.java.Bucket; + +public interface BucketService { + + Bucket getBucket(); + +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java new file mode 100644 index 0000000000..da7a10141f --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java @@ -0,0 +1,17 @@ +package com.baeldung.couchbase.spring.service; + +import java.util.List; + +import com.couchbase.client.java.AsyncBucket; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.document.JsonDocument; + +public interface ClusterService { + + Bucket openBucket(String name, String password); + + List getDocuments(Bucket bucket, Iterable keys); + + List getDocumentsAsync(AsyncBucket bucket, Iterable keys); + +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java new file mode 100644 index 0000000000..1cceb11ccc --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java @@ -0,0 +1,81 @@ +package com.baeldung.couchbase.spring.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.annotation.PostConstruct; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.couchbase.client.java.AsyncBucket; +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.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +import rx.Observable; +import rx.functions.Action1; +import rx.functions.Func1; + +@Service +public class ClusterServiceImpl implements ClusterService { + private static final Logger logger = LoggerFactory.getLogger(ClusterServiceImpl.class); + + private Cluster cluster; + private Map buckets = new ConcurrentHashMap<>(); + + @PostConstruct + private void init() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create(); + cluster = CouchbaseCluster.create(env, "localhost"); + } + + @Override + synchronized public Bucket openBucket(String name, String password) { + if (!buckets.containsKey(name)) { + Bucket bucket = cluster.openBucket(name, password); + buckets.put(name, bucket); + } + return buckets.get(name); + } + + @Override + public List getDocuments(Bucket bucket, Iterable keys) { + List docs = new ArrayList<>(); + for (String key : keys) { + JsonDocument doc = bucket.get(key); + if (doc != null) { + docs.add(doc); + } + } + return docs; + } + + @Override + public List getDocumentsAsync(final AsyncBucket asyncBucket, Iterable keys) { + Observable asyncBulkGet = Observable.from(keys).flatMap(new Func1>() { + public Observable call(String key) { + return asyncBucket.get(key); + } + }); + + final List docs = new ArrayList<>(); + try { + asyncBulkGet.toBlocking().forEach(new Action1() { + public void call(JsonDocument doc) { + docs.add(doc); + } + }); + } catch (Exception e) { + logger.error("Error during bulk get", e); + } + + return docs; + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java new file mode 100644 index 0000000000..5b12af7003 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java @@ -0,0 +1,16 @@ +package com.baeldung.couchbase.spring.service; + +public interface CrudService { + + void create(T t); + + T read(String id); + + T readFromReplica(String id); + + void update(T t); + + void delete(String id); + + boolean exists(String id); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java new file mode 100644 index 0000000000..f63bb8691b --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java @@ -0,0 +1,10 @@ +package com.baeldung.couchbase.spring.service; + +import com.couchbase.client.java.document.JsonDocument; + +public interface JsonDocumentConverter { + + JsonDocument toDocument(T t); + + T fromDocument(JsonDocument doc); +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java new file mode 100644 index 0000000000..b91c131912 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java @@ -0,0 +1,29 @@ +package com.baeldung.couchbase.spring.service; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import com.couchbase.client.java.Bucket; + +@Service +@Qualifier("TutorialBucketService") +public class TutorialBucketService implements BucketService { + + @Autowired + private ClusterService couchbase; + + private Bucket bucket; + + @PostConstruct + private void init() { + bucket = couchbase.openBucket("baeldung-tutorial", ""); + } + + @Override + public Bucket getBucket() { + return bucket; + } +} diff --git a/couchbase/src/main/resources/application.properties b/couchbase/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/couchbase/src/main/resources/logback.xml b/couchbase/src/main/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/couchbase/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java new file mode 100644 index 0000000000..3079fc928a --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java @@ -0,0 +1,13 @@ +package com.baeldung.couchbase.async; + +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public abstract class AsyncIntegrationTest { +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java new file mode 100644 index 0000000000..efc3e9957f --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.async; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = { "com.baeldung.couchbase.async" }) +public class AsyncIntegrationTestConfig { +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java new file mode 100644 index 0000000000..565aaed5da --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java @@ -0,0 +1,216 @@ +package com.baeldung.couchbase.async.person; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import com.baeldung.couchbase.async.AsyncIntegrationTest; +import com.baeldung.couchbase.async.person.Person; +import com.baeldung.couchbase.async.person.PersonCrudService; +import com.baeldung.couchbase.async.person.PersonDocumentConverter; +import com.baeldung.couchbase.async.service.BucketService; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.document.JsonDocument; + +public class PersonCrudServiceIntegrationTest extends AsyncIntegrationTest { + + @Autowired + private PersonCrudService personService; + + @Autowired + @Qualifier("TutorialBucketService") + private BucketService bucketService; + + @Autowired + private PersonDocumentConverter converter; + + private Bucket bucket; + + @PostConstruct + private void init() { + bucket = bucketService.getBucket(); + } + + @Test + public final void givenRandomPerson_whenCreate_thenPersonPersisted() { + // create person + Person person = randomPerson(); + personService.create(person); + + // check results + assertNotNull(person.getId()); + assertNotNull(bucket.get(person.getId())); + + // cleanup + bucket.remove(person.getId()); + } + + @Test + public final void givenId_whenRead_thenReturnsPerson() { + // create and insert person document + String id = insertRandomPersonDocument().id(); + + // read person and check results + assertNotNull(personService.read(id)); + + // cleanup + bucket.remove(id); + } + + @Test + public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() { + // create and insert person document + JsonDocument doc = insertRandomPersonDocument(); + + // update person + Person expected = converter.fromDocument(doc); + String updatedHomeTown = RandomStringUtils.randomAlphabetic(12); + expected.setHomeTown(updatedHomeTown); + personService.update(expected); + + // check results + JsonDocument actual = bucket.get(expected.getId()); + assertNotNull(actual); + assertNotNull(actual.content()); + assertEquals(expected.getHomeTown(), actual.content().getString("homeTown")); + + // cleanup + bucket.remove(expected.getId()); + } + + @Test + public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() { + // create and insert person document + String id = insertRandomPersonDocument().id(); + + // delete person and check results + personService.delete(id); + assertNull(bucket.get(id)); + } + + @Test + public final void givenIds_whenReadBulk_thenReturnsOnlyPersonsWithMatchingIds() { + List ids = new ArrayList<>(); + + // add some person documents + for (int i = 0; i < 5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + // perform bulk read + List persons = personService.readBulk(ids); + + // check results + for (Person person : persons) { + assertTrue(ids.contains(person.getId())); + } + + // cleanup + for (String id : ids) { + bucket.remove(id); + } + } + + @Test + public final void givenPersons_whenInsertBulk_thenPersonsAreInserted() { + + // create some persons + List persons = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + persons.add(randomPerson()); + } + + // perform bulk insert + personService.createBulk(persons); + + // check results + for (Person person : persons) { + assertNotNull(bucket.get(person.getId())); + } + + // cleanup + for (Person person : persons) { + bucket.remove(person.getId()); + } + } + + @Test + public final void givenPersons_whenUpdateBulk_thenPersonsAreUpdated() { + + List ids = new ArrayList<>(); + + // add some person documents + for (int i = 0; i < 5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + // load persons from Couchbase + List persons = new ArrayList<>(); + for (String id : ids) { + persons.add(converter.fromDocument(bucket.get(id))); + } + + // modify persons + for (Person person : persons) { + person.setHomeTown(RandomStringUtils.randomAlphabetic(10)); + } + + // perform bulk update + personService.updateBulk(persons); + + // check results + for (Person person : persons) { + JsonDocument doc = bucket.get(person.getId()); + assertEquals(person.getName(), doc.content().getString("name")); + assertEquals(person.getHomeTown(), doc.content().getString("homeTown")); + } + + // cleanup + for (String id : ids) { + bucket.remove(id); + } + } + + @Test + public void givenIds_whenDeleteBulk_thenPersonsAreDeleted() { + + List ids = new ArrayList<>(); + + // add some person documents + for (int i = 0; i < 5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + // perform bulk delete + personService.deleteBulk(ids); + + // check results + for (String id : ids) { + assertNull(bucket.get(id)); + } + + } + + private JsonDocument insertRandomPersonDocument() { + Person expected = randomPersonWithId(); + JsonDocument doc = converter.toDocument(expected); + return bucket.insert(doc); + } + + private Person randomPerson() { + return Person.Builder.newInstance().name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build(); + } + + private Person randomPersonWithId() { + return Person.Builder.newInstance().id(UUID.randomUUID().toString()).name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build(); + } +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java new file mode 100644 index 0000000000..d0db5d37a3 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.couchbase.async.service; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +import com.baeldung.couchbase.async.AsyncIntegrationTest; +import com.baeldung.couchbase.async.AsyncIntegrationTestConfig; +import com.baeldung.couchbase.async.service.ClusterService; +import com.couchbase.client.java.Bucket; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public class ClusterServiceIntegrationTest extends AsyncIntegrationTest { + + @Autowired + private ClusterService couchbaseService; + + private Bucket defaultBucket; + + @Test + public void whenOpenBucket_thenBucketIsNotNull() throws Exception { + defaultBucket = couchbaseService.openBucket("default", ""); + assertNotNull(defaultBucket); + assertFalse(defaultBucket.isClosed()); + defaultBucket.close(); + } +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java new file mode 100644 index 0000000000..00d462e32a --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java @@ -0,0 +1,150 @@ +package com.baeldung.couchbase.mapreduce; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.view.ViewResult; +import com.couchbase.client.java.view.ViewRow; + +public class StudentGradeServiceIntegrationTest { + private static final Logger logger = LoggerFactory.getLogger(StudentGradeServiceIntegrationTest.class); + + static StudentGradeService studentGradeService; + static Set gradeIds = new HashSet<>(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + studentGradeService = new StudentGradeService(new StudentGradeKeyGenerator()); + insertStudentGrade(new StudentGrade("John Doe", "History", 80, 3)); + insertStudentGrade(new StudentGrade("Jane Doe", "History", 89, 3)); + insertStudentGrade(new StudentGrade("Bob Smith", "History", 90, 3)); + insertStudentGrade(new StudentGrade("Mary Jones", "History", 92, 3)); + insertStudentGrade(new StudentGrade("Jane Doe", "Math", 59, 3)); + insertStudentGrade(new StudentGrade("Bob Smith", "Math", 91, 3)); + insertStudentGrade(new StudentGrade("Mary Jones", "Math", 86, 3)); + insertStudentGrade(new StudentGrade("John Doe", "Science", 85, 4)); + insertStudentGrade(new StudentGrade("Bob Smith", "Science", 97, 4)); + insertStudentGrade(new StudentGrade("Mary Jones", "Science", 84, 4)); + } + + private static void insertStudentGrade(StudentGrade studentGrade) { + try { + String id = studentGradeService.insert(studentGrade); + gradeIds.add(id); + } catch (DuplicateKeyException e) { + } + } + + @Test + public final void whenFindAll_thenSuccess() { + List docs = studentGradeService.findAll(); + printDocuments(docs); + } + + @Test + public final void whenFindByCourse_thenSuccess() { + List docs = studentGradeService.findByCourse("History"); + printDocuments(docs); + } + + @Test + public final void whenFindByCourses_thenSuccess() { + List docs = studentGradeService.findByCourses("History", "Science"); + printDocuments(docs); + } + + @Test + public final void whenFindByGradeInRange_thenSuccess() { + List docs = studentGradeService.findByGradeInRange(80, 89, true); + printDocuments(docs); + } + + @Test + public final void whenFindByGradeLessThan_thenSuccess() { + List docs = studentGradeService.findByGradeLessThan(60); + printDocuments(docs); + } + + @Test + public final void whenFindByGradeGreaterThan_thenSuccess() { + List docs = studentGradeService.findByGradeGreaterThan(90); + printDocuments(docs); + } + + @Test + public final void whenFindByCourseAndGradeInRange_thenSuccess() { + List docs = studentGradeService.findByCourseAndGradeInRange("Math", 80, 89, true); + printDocuments(docs); + } + + @Test + public final void whenFindTopGradesByCourse_thenSuccess() { + List docs = studentGradeService.findTopGradesByCourse("Science", 2); + printDocuments(docs); + } + + @Test + public final void whenCountStudentsByCourse_thenSuccess() { + Map map = studentGradeService.countStudentsByCourse(); + printMap(map); + } + + @Test + public final void whenSumCreditHoursByStudent_thenSuccess() { + Map map = studentGradeService.sumCreditHoursByStudent(); + printMap(map); + } + + @Test + public final void whenSumGradePointsByStudent_thenSuccess() { + Map map = studentGradeService.sumGradePointsByStudent(); + printMap(map); + } + + @Test + public final void whenCalculateGpaByStudent_thenSuccess() { + Map map = studentGradeService.calculateGpaByStudent(); + printGpaMap(map); + } + + private void printMap(Map map) { + for(Map.Entry entry : map.entrySet()) { + logger.info(entry.getKey() + "=" + entry.getValue()); + } + } + + private void printGpaMap(Map map) { + for(Map.Entry entry : map.entrySet()) { + logger.info(entry.getKey() + "=" + entry.getValue()); + } + } + + private void printDocuments(List docs) { + for(JsonDocument doc : docs) { + String key = doc.id(); + logger.info(key + " = " + doc.content().toString()); + } + } + + private void printViewResultDocuments(ViewResult result) { + for(ViewRow row : result.allRows()) { + JsonDocument doc = row.document(); + String key = doc.id(); + logger.info(key + "=" + doc.content().toString()); + } + } + + private void printViewResultRows(ViewResult result) { + for(ViewRow row : result.allRows()) { + logger.info(row.toString()); + } + } +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java new file mode 100644 index 0000000000..ef7e31b224 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.n1ql; + +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 org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.TimeUnit; + +@Configuration +@ComponentScan(basePackages = { "com.baeldung.couchbase.n1ql" }) +public class IntegrationTestConfig { + + @Bean + public Cluster cluster() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder() + .connectTimeout(60000) + .build(); + return CouchbaseCluster.create(env, "127.0.0.1"); + } + + +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java new file mode 100644 index 0000000000..8112d7d222 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java @@ -0,0 +1,248 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +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.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.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import rx.Observable; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static com.baeldung.couchbase.n1ql.CodeSnippets.extractJsonResult; +import static com.couchbase.client.java.query.Select.select; +import static com.couchbase.client.java.query.dsl.Expression.*; +import static org.junit.Assert.assertNotNull; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { IntegrationTestConfig.class }) +public class N1QLIntegrationTest { + + + @Autowired + private Cluster cluster; + + @Autowired + private BucketFactory bucketFactory; + + @Test + public void givenAutowiredCluster_whenNotNull_thenNotNull() { + assertNotNull(cluster); + } + + @Test + public void givenBucketFactory_whenGetTestBucket_thenNotNull() { + assertNotNull(bucketFactory.getTestBucket()); + } + + @Test + public void givenBucketFactory_whenGetTravelSampleBucket_thenNotNull() { + assertNotNull(bucketFactory.getTravelSampleBucket()); + } + + @Test + public void givenDocument_whenInsert_thenResult() { + Bucket bucket = bucketFactory.getTestBucket(); + JsonObject personObj = JsonObject.create() + .put("name", "John") + .put("email", "john@doe.com") + .put("interests", JsonArray.from("Java", "Nigerian Jollof")); + + String id = UUID.randomUUID().toString(); + JsonDocument doc = JsonDocument.create(id, personObj); + bucket.insert(doc); + assertNotNull(bucket.get(id)); + } + + @Test + public void whenBasicSelectQuery_thenGetQueryResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + N1qlQueryResult result + = bucket.query(N1qlQuery.simple("SELECT * FROM test")); + + result.forEach(System.out::println); + + System.out.println("result count: " + result.info().resultCount()); + System.out.println("error count: " + result.info().errorCount()); + } + + @Test + public void givenSelectStatement_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query = "SELECT name FROM `travel-sample` " + + "WHERE type = 'airport' LIMIT 100"; + N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query)); + + System.out.println("Result Count " + result1.info().resultCount()); + + N1qlQueryRow row = result1.allRows().get(0); + JsonObject rowJson = row.value(); + System.out.println("Name in First Row " + rowJson.get("name")); + + } + + @Test + public void givenSelectStatement2_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject pVal = JsonObject.create().put("type", "airport"); + String query = "SELECT * FROM `travel-sample` " + + "WHERE type = $type LIMIT 100"; + N1qlQueryResult r2 = bucket.query(N1qlQuery.parameterized(query, pVal)); + + System.out.println(r2.allRows()); + + List list = extractJsonResult(r2); + System.out.println( + list.get(0).get("travel-sample").get("airportname").asText()); + } + + @Test + public void givenSelectDSL_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + Statement statement = select("*") + .from(i("travel-sample")) + .where(x("type").eq(s("airport"))) + .limit(100); + N1qlQueryResult r3 = bucket.query(N1qlQuery.simple(statement)); + + List list2 = extractJsonResult(r3); + System.out.println("First Airport Name: " + list2.get(0).get("travel-sample").get("airportname").asText()); + + } + + @Test + public void givenSelectStatementWithOperators_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query2 = "SELECT t.city, " + + "t.airportname || \" (\" || t.faa || \")\" AS portname_faa " + + "FROM `travel-sample` t " + + "WHERE t.type=\"airport\"" + + "AND t.country LIKE '%States'" + + "AND t.geo.lat >= 70 " + + "LIMIT 2"; + N1qlQueryResult r4 = bucket.query(N1qlQuery.simple(query2)); + List list3 = extractJsonResult(r4); + System.out.println("First Doc : " + list3.get(0)); + } + + @Test + public void givenSelectStatementWithDSL2_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + Statement st2 = select( + x("t.city, t.airportname") + .concat(s(" (")).concat(x("t.faa")).concat(s(")")).as("portname_faa")) + .from(i("travel-sample").as("t")) + .where( x("t.type").eq(s("airport")) + .and(x("t.country").like(s("%States"))) + .and(x("t.geo.lat").gte(70))) + .limit(2); + N1qlQueryResult r5 = bucket.query(N1qlQuery.simple(st2)); + List list5 = extractJsonResult(r5); + System.out.println("First Doc : " + list5.get(0)); + System.out.println("Query from Statement2: " + st2.toString()); + } + + @Test + public void givenInsertStatement_whenQuery_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query = "INSERT INTO `travel-sample` (KEY, VALUE) " + + " VALUES(" + + "\"cust1293\", " + + "{\"id\":\"1293\",\"name\":\"Sample Airline\", \"type\":\"airline\"})" + + " RETURNING META().id as docid, *"; + N1qlQueryResult r1 = bucket.query(N1qlQuery.simple(query)); + r1.forEach(System.out::println); + } + + @Test + public void givenDocument_whenInsert_thenResults() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject ob = JsonObject.create() + .put("id", "1293") + .put("name", "Sample Airline") + .put("type", "airline"); + bucket.insert(JsonDocument.create("cust1295", ob)); + } + + @Test + public void givenDocuments_whenBatchInsert_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + + List documents = IntStream.rangeClosed(0,10) + .mapToObj( i -> { + JsonObject content = JsonObject.create() + .put("id", i) + .put("type", "airline") + .put("name", "Sample Airline " + i); + return JsonDocument.create("cust_" + i, content); + }) + .collect(Collectors.toList()); + + List r5 = Observable + .from(documents) + .flatMap(doc -> bucket.async().insert(doc)) + .toList() + .last() + .toBlocking() + .single(); + + r5.forEach(System.out::println); + } + + @Test + public void givenUpdateStatement_whenQuery_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query2 = "UPDATE `travel-sample` USE KEYS \"cust_1\" " + + "SET name=\"Sample Airline Updated\" RETURNING name"; + N1qlQueryResult result = bucket.query(N1qlQuery.simple(query2)); + result.forEach(System.out::println); + } + + @Test + public void givenDocument_whenUpsert_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject o2 = JsonObject.create() + .put("name", "Sample Airline Updated"); + bucket.upsert(JsonDocument.create("cust_1", o2)); + } + + @Test + public void givenUnestUpdateStatement_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query3 = "UPDATE `travel-sample` USE KEYS \"cust_2\" " + + "UNSET name RETURNING *"; + N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query3)); + result1.forEach(System.out::println); + } + + @Test + public void givenDeleteStatement_whenQuery_thenDelete() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query4 = "DELETE FROM `travel-sample` USE KEYS \"cust_50\""; + N1qlQueryResult result4 = bucket.query(N1qlQuery.simple(query4)); + } + + @Test + public void givenDeleteStatement2_whenQuery_thenDelete() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query5 = "DELETE FROM `travel-sample` WHERE id = 0 RETURNING *"; + N1qlQueryResult result5 = bucket.query(N1qlQuery.simple(query5)); + } + + +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java new file mode 100644 index 0000000000..9c0b0a50c1 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java @@ -0,0 +1,13 @@ +package com.baeldung.couchbase.spring; + +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { IntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public abstract class IntegrationTest { +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java new file mode 100644 index 0000000000..d814b31a07 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.spring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = { "com.baeldung.couchbase.spring" }) +public class IntegrationTestConfig { +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java new file mode 100644 index 0000000000..ec15be1acc --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.couchbase.spring.person; + +import static org.junit.Assert.*; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.baeldung.couchbase.spring.IntegrationTest; + +public class PersonCrudServiceIntegrationTest extends IntegrationTest { + + private static final String CLARK_KENT = "Clark Kent"; + private static final String SMALLVILLE = "Smallville"; + private static final String CLARK_KENT_ID = "Person:ClarkKent"; + + private Person clarkKent; + + @Autowired + private PersonCrudService personService; + + @PostConstruct + private void init() { + clarkKent = personService.read(CLARK_KENT_ID); + if (clarkKent == null) { + clarkKent = buildClarkKent(); + personService.create(clarkKent); + } + } + + @Test + public final void givenRandomPerson_whenCreate_thenPersonPersisted() { + Person person = randomPerson(); + personService.create(person); + String id = person.getId(); + assertNotNull(personService.read(id)); + } + + @Test + public final void givenClarkKentId_whenRead_thenReturnsClarkKent() { + Person person = personService.read(CLARK_KENT_ID); + assertNotNull(person); + } + + @Test + public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() { + Person expected = randomPerson(); + personService.create(expected); + String updatedHomeTown = RandomStringUtils.randomAlphabetic(12); + expected.setHomeTown(updatedHomeTown); + personService.update(expected); + Person actual = personService.read(expected.getId()); + assertNotNull(actual); + assertEquals(expected.getHomeTown(), actual.getHomeTown()); + } + + @Test + public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() { + Person person = randomPerson(); + personService.create(person); + String id = person.getId(); + personService.delete(id); + assertNull(personService.read(id)); + } + + private Person buildClarkKent() { + return Person.Builder.newInstance().id(CLARK_KENT_ID).name(CLARK_KENT).homeTown(SMALLVILLE).build(); + } + + private Person randomPerson() { + return Person.Builder.newInstance().name(RandomStringUtils.randomAlphabetic(10)).homeTown(RandomStringUtils.randomAlphabetic(10)).build(); + } +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java new file mode 100644 index 0000000000..ead247dfbc --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.couchbase.spring.service; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +import com.baeldung.couchbase.spring.IntegrationTest; +import com.baeldung.couchbase.spring.IntegrationTestConfig; +import com.couchbase.client.java.Bucket; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { IntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public class ClusterServiceIntegrationTest extends IntegrationTest { + + @Autowired + private ClusterService couchbaseService; + + private Bucket defaultBucket; + + @Test + public void whenOpenBucket_thenBucketIsNotNull() throws Exception { + defaultBucket = couchbaseService.openBucket("default", ""); + assertNotNull(defaultBucket); + assertFalse(defaultBucket.isClosed()); + defaultBucket.close(); + } +} diff --git a/couchbase/src/test/resources/logback.xml b/couchbase/src/test/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/couchbase/src/test/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file