rename module to couchbase
This commit is contained in:
		
							parent
							
								
									0f74ad6f0b
								
							
						
					
					
						commit
						91c57354cc
					
				
							
								
								
									
										6
									
								
								couchbase/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								couchbase/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | # Created by .ignore support plugin (hsz.mobi) | ||||||
|  | 
 | ||||||
|  | # IntelliJ project files | ||||||
|  | .idea | ||||||
|  | *.iml | ||||||
|  | /target/ | ||||||
							
								
								
									
										51
									
								
								couchbase/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								couchbase/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
|  | ``` | ||||||
							
								
								
									
										233
									
								
								couchbase/mvnw
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								couchbase/mvnw
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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} "$@" | ||||||
							
								
								
									
										145
									
								
								couchbase/mvnw.cmd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								couchbase/mvnw.cmd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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% | ||||||
							
								
								
									
										82
									
								
								couchbase/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								couchbase/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <groupId>com.baeldung</groupId> | ||||||
|  |     <artifactId>couchbase-sdk</artifactId> | ||||||
|  |     <version>0.1-SNAPSHOT</version> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  |     <name>couchbase-sdk</name> | ||||||
|  |     <description>Couchbase SDK Tutorials</description> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-modules</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <!-- Couchbase SDK --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.couchbase.client</groupId> | ||||||
|  |             <artifactId>java-client</artifactId> | ||||||
|  |             <version>${couchbase.client.version}</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |           <groupId>com.fasterxml.jackson.core</groupId> | ||||||
|  |           <artifactId>jackson-databind</artifactId> | ||||||
|  |           <version>${jackson-version}</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <!-- Spring Context for Dependency Injection --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework</groupId> | ||||||
|  |             <artifactId>spring-context</artifactId> | ||||||
|  |             <version>${spring-framework.version}</version> | ||||||
|  |             <exclusions> | ||||||
|  |                 <exclusion> | ||||||
|  |                     <artifactId>commons-logging</artifactId> | ||||||
|  |                     <groupId>commons-logging</groupId> | ||||||
|  |                 </exclusion> | ||||||
|  |             </exclusions> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework</groupId> | ||||||
|  |             <artifactId>spring-context-support</artifactId> | ||||||
|  |             <version>${spring-framework.version}</version> | ||||||
|  |             <exclusions> | ||||||
|  |                 <exclusion> | ||||||
|  |                     <artifactId>commons-logging</artifactId> | ||||||
|  |                     <groupId>commons-logging</groupId> | ||||||
|  |                 </exclusion> | ||||||
|  |             </exclusions> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <!-- Test-Scoped Dependencies --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework</groupId> | ||||||
|  |             <artifactId>spring-test</artifactId> | ||||||
|  |             <version>${spring-framework.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.apache.commons</groupId> | ||||||
|  |             <artifactId>commons-lang3</artifactId> | ||||||
|  |             <version>${commons-lang3.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  |     <properties> | ||||||
|  |         <java.version>1.8</java.version> | ||||||
|  |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|  |         <couchbase.client.version>2.5.0</couchbase.client.version> | ||||||
|  |         <spring-framework.version>4.3.5.RELEASE</spring-framework.version> | ||||||
|  |         <commons-lang3.version>3.5</commons-lang3.version> | ||||||
|  |         <jackson-version>2.9.1</jackson-version> | ||||||
|  |     </properties> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package com.baeldung.couchbase.async; | ||||||
|  | 
 | ||||||
|  | public interface CouchbaseEntity { | ||||||
|  | 
 | ||||||
|  |     String getId(); | ||||||
|  | 
 | ||||||
|  |     void setId(String id); | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<Person> { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     public PersonCrudService(@Qualifier("TutorialBucketService") BucketService bucketService, PersonDocumentConverter converter) { | ||||||
|  |         super(bucketService, converter); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @PostConstruct | ||||||
|  |     private void init() { | ||||||
|  |         loadBucket(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<Person> { | ||||||
|  | 
 | ||||||
|  |     @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<T extends CouchbaseEntity> implements CrudService<T> { | ||||||
|  | 
 | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(AbstractCrudService.class); | ||||||
|  | 
 | ||||||
|  |     private BucketService bucketService; | ||||||
|  |     private Bucket bucket; | ||||||
|  |     private JsonDocumentConverter<T> converter; | ||||||
|  | 
 | ||||||
|  |     public AbstractCrudService(BucketService bucketService, JsonDocumentConverter<T> 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<JsonDocument> 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<T> readBulk(Iterable<String> ids) { | ||||||
|  |         final AsyncBucket asyncBucket = bucket.async(); | ||||||
|  |         Observable<JsonDocument> asyncOperation = Observable.from(ids).flatMap(new Func1<String, Observable<JsonDocument>>() { | ||||||
|  |             public Observable<JsonDocument> call(String key) { | ||||||
|  |                 return asyncBucket.get(key); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         final List<T> items = new ArrayList<T>(); | ||||||
|  |         try { | ||||||
|  |             asyncOperation.toBlocking().forEach(new Action1<JsonDocument>() { | ||||||
|  |                 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<T> items) { | ||||||
|  |         final AsyncBucket asyncBucket = bucket.async(); | ||||||
|  |         Observable.from(items).flatMap(new Func1<T, Observable<JsonDocument>>() { | ||||||
|  |             @SuppressWarnings("unchecked") | ||||||
|  |             @Override | ||||||
|  |             public Observable<JsonDocument> 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<T> items) { | ||||||
|  |         final AsyncBucket asyncBucket = bucket.async(); | ||||||
|  |         Observable.from(items).flatMap(new Func1<T, Observable<JsonDocument>>() { | ||||||
|  |             @SuppressWarnings("unchecked") | ||||||
|  |             @Override | ||||||
|  |             public Observable<JsonDocument> 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<String> ids) { | ||||||
|  |         final AsyncBucket asyncBucket = bucket.async(); | ||||||
|  |         Observable.from(ids).flatMap(new Func1<String, Observable<JsonDocument>>() { | ||||||
|  |             @SuppressWarnings("unchecked") | ||||||
|  |             @Override | ||||||
|  |             public Observable<JsonDocument> 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); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | package com.baeldung.couchbase.async.service; | ||||||
|  | 
 | ||||||
|  | import com.couchbase.client.java.Bucket; | ||||||
|  | 
 | ||||||
|  | public interface BucketService { | ||||||
|  | 
 | ||||||
|  |     Bucket getBucket(); | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  | } | ||||||
| @ -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<String, Bucket> 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); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | package com.baeldung.couchbase.async.service; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | public interface CrudService<T> { | ||||||
|  | 
 | ||||||
|  |     void create(T t); | ||||||
|  | 
 | ||||||
|  |     T read(String id); | ||||||
|  | 
 | ||||||
|  |     T readFromReplica(String id); | ||||||
|  | 
 | ||||||
|  |     void update(T t); | ||||||
|  | 
 | ||||||
|  |     void delete(String id); | ||||||
|  | 
 | ||||||
|  |     List<T> readBulk(Iterable<String> ids); | ||||||
|  | 
 | ||||||
|  |     void createBulk(Iterable<T> items); | ||||||
|  | 
 | ||||||
|  |     void updateBulk(Iterable<T> items); | ||||||
|  | 
 | ||||||
|  |     void deleteBulk(Iterable<String> ids); | ||||||
|  | 
 | ||||||
|  |     boolean exists(String id); | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | package com.baeldung.couchbase.async.service; | ||||||
|  | 
 | ||||||
|  | import com.couchbase.client.java.document.JsonDocument; | ||||||
|  | 
 | ||||||
|  | public interface JsonDocumentConverter<T> { | ||||||
|  | 
 | ||||||
|  |     JsonDocument toDocument(T t); | ||||||
|  | 
 | ||||||
|  |     T fromDocument(JsonDocument doc); | ||||||
|  | } | ||||||
| @ -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 ""; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<JsonDocument> 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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | package com.baeldung.couchbase.mapreduce; | ||||||
|  | 
 | ||||||
|  | public interface CouchbaseKeyGenerator<T> { | ||||||
|  | 
 | ||||||
|  |     String generateKey(T t); | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | package com.baeldung.couchbase.mapreduce; | ||||||
|  | 
 | ||||||
|  | @SuppressWarnings("serial") | ||||||
|  | public class DuplicateKeyException extends Exception { | ||||||
|  | 
 | ||||||
|  |     public DuplicateKeyException(String s) { | ||||||
|  |         super(s); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | package com.baeldung.couchbase.mapreduce; | ||||||
|  | 
 | ||||||
|  | import java.util.UUID; | ||||||
|  | 
 | ||||||
|  | public class RandomUUIDGenerator<T> implements CouchbaseKeyGenerator<T> { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String generateKey(T t) { | ||||||
|  |         return UUID.randomUUID().toString(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package com.baeldung.couchbase.mapreduce; | ||||||
|  | 
 | ||||||
|  | public class StudentGradeKeyGenerator implements CouchbaseKeyGenerator<StudentGrade> { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String generateKey(StudentGrade g) { | ||||||
|  |         return g.getName() + ":" + g.getCourse(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<StudentGrade> keyGenerator; | ||||||
|  |     final CouchbaseCluster cluster; | ||||||
|  |     final Bucket bucket; | ||||||
|  |     final ObjectMapper om = new ObjectMapper(); | ||||||
|  |     final StudentGradeQueryBuilder queryBuilder; | ||||||
|  |      | ||||||
|  |     public StudentGradeService(CouchbaseKeyGenerator<StudentGrade> 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<JsonDocument> findAll() { | ||||||
|  |         ViewQuery query = queryBuilder.findAll(); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private List<JsonDocument> extractDocuments(ViewResult result) { | ||||||
|  |         List<JsonDocument> docs = new ArrayList<>(); | ||||||
|  |         for(ViewRow row : result.allRows()) { | ||||||
|  |             JsonDocument doc = row.document(); | ||||||
|  |             docs.add(doc); | ||||||
|  |         } | ||||||
|  |         return docs; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public List<JsonDocument> findByCourse(String course) { | ||||||
|  |         ViewQuery query = queryBuilder.findByCourse(course); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public List<JsonDocument> findByCourses(String... courses) { | ||||||
|  |         ViewQuery query = queryBuilder.findByCourses(courses); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public List<JsonDocument> findByGradeInRange(int lower, int upper, boolean inclusiveEnd) { | ||||||
|  |         ViewQuery query = queryBuilder.findByGradeInRange(lower, upper, inclusiveEnd); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public List<JsonDocument> findByGradeLessThan(int upper) { | ||||||
|  |         ViewQuery query = queryBuilder.findByGradeLessThan(upper); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public List<JsonDocument> findByGradeGreaterThan(int lower) { | ||||||
|  |         ViewQuery query = queryBuilder.findByGradeGreaterThan(lower); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     public List<JsonDocument> 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<JsonDocument> findTopGradesByCourse(String course, int limit) { | ||||||
|  |         ViewQuery query = queryBuilder.findTopGradesByCourse(course, limit); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |         return extractDocuments(result); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public Map<String, Long> countStudentsByCourse() { | ||||||
|  |         ViewQuery query = ViewQuery.from("studentGrades", "countStudentsByCourse") | ||||||
|  |                 .reduce() | ||||||
|  |                 .groupLevel(1); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |          | ||||||
|  |         Map<String, Long> 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<String, Long> sumCreditHoursByStudent() { | ||||||
|  |         ViewQuery query = ViewQuery.from("studentGrades", "sumHoursByStudent") | ||||||
|  |                 .reduce() | ||||||
|  |                 .groupLevel(1); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |          | ||||||
|  |         Map<String, Long> 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<String, Long> sumGradePointsByStudent() { | ||||||
|  |         ViewQuery query = ViewQuery.from("studentGrades", "sumGradePointsByStudent") | ||||||
|  |                 .reduce() | ||||||
|  |                 .groupLevel(1); | ||||||
|  |         ViewResult result = bucket.query(query); | ||||||
|  |          | ||||||
|  |         Map<String, Long> 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<String, Float> calculateGpaByStudent() { | ||||||
|  |         Map<String, Long> creditHoursByStudent = sumCreditHoursByStudent(); | ||||||
|  |         Map<String, Long> gradePointsByStudent = sumGradePointsByStudent(); | ||||||
|  |          | ||||||
|  |         Map<String, Float> result = new HashMap<>(); | ||||||
|  |         for(Entry<String, Long> creditHoursEntry : creditHoursByStudent.entrySet()) { | ||||||
|  |             String name = creditHoursEntry.getKey(); | ||||||
|  |             long totalHours = creditHoursEntry.getValue(); | ||||||
|  |             long totalGradePoints = gradePointsByStudent.get(name); | ||||||
|  |             result.put(name, ((float) totalGradePoints / totalHours)); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<JsonNode> 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()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<Person> { | ||||||
|  | 
 | ||||||
|  |     @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<JsonDocument> 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); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<Person> { | ||||||
|  | 
 | ||||||
|  |     @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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package com.baeldung.couchbase.spring.service; | ||||||
|  | 
 | ||||||
|  | import com.couchbase.client.java.Bucket; | ||||||
|  | 
 | ||||||
|  | public interface BucketService { | ||||||
|  | 
 | ||||||
|  |     Bucket getBucket(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<JsonDocument> getDocuments(Bucket bucket, Iterable<String> keys); | ||||||
|  | 
 | ||||||
|  |     List<JsonDocument> getDocumentsAsync(AsyncBucket bucket, Iterable<String> keys); | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<String, Bucket> 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<JsonDocument> getDocuments(Bucket bucket, Iterable<String> keys) { | ||||||
|  |         List<JsonDocument> docs = new ArrayList<>(); | ||||||
|  |         for (String key : keys) { | ||||||
|  |             JsonDocument doc = bucket.get(key); | ||||||
|  |             if (doc != null) { | ||||||
|  |                 docs.add(doc); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return docs; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<JsonDocument> getDocumentsAsync(final AsyncBucket asyncBucket, Iterable<String> keys) { | ||||||
|  |         Observable<JsonDocument> asyncBulkGet = Observable.from(keys).flatMap(new Func1<String, Observable<JsonDocument>>() { | ||||||
|  |             public Observable<JsonDocument> call(String key) { | ||||||
|  |                 return asyncBucket.get(key); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         final List<JsonDocument> docs = new ArrayList<>(); | ||||||
|  |         try { | ||||||
|  |             asyncBulkGet.toBlocking().forEach(new Action1<JsonDocument>() { | ||||||
|  |                 public void call(JsonDocument doc) { | ||||||
|  |                     docs.add(doc); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             logger.error("Error during bulk get", e); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return docs; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | package com.baeldung.couchbase.spring.service; | ||||||
|  | 
 | ||||||
|  | public interface CrudService<T> { | ||||||
|  | 
 | ||||||
|  |     void create(T t); | ||||||
|  | 
 | ||||||
|  |     T read(String id); | ||||||
|  | 
 | ||||||
|  |     T readFromReplica(String id); | ||||||
|  | 
 | ||||||
|  |     void update(T t); | ||||||
|  | 
 | ||||||
|  |     void delete(String id); | ||||||
|  | 
 | ||||||
|  |     boolean exists(String id); | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | package com.baeldung.couchbase.spring.service; | ||||||
|  | 
 | ||||||
|  | import com.couchbase.client.java.document.JsonDocument; | ||||||
|  | 
 | ||||||
|  | public interface JsonDocumentConverter<T> { | ||||||
|  | 
 | ||||||
|  |     JsonDocument toDocument(T t); | ||||||
|  | 
 | ||||||
|  |     T fromDocument(JsonDocument doc); | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										0
									
								
								couchbase/src/main/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								couchbase/src/main/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										19
									
								
								couchbase/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								couchbase/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration> | ||||||
|  |     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>web - %date [%thread] %-5level %logger{36} - %message%n | ||||||
|  |             </pattern> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <logger name="org.springframework" level="WARN" /> | ||||||
|  |     <logger name="org.springframework.transaction" level="WARN" /> | ||||||
|  | 
 | ||||||
|  |     <!-- in order to debug some marshalling issues, this needs to be TRACE --> | ||||||
|  |     <logger name="org.springframework.web.servlet.mvc" level="WARN" /> | ||||||
|  | 
 | ||||||
|  |     <root level="INFO"> | ||||||
|  |         <appender-ref ref="STDOUT" /> | ||||||
|  |     </root> | ||||||
|  | </configuration> | ||||||
| @ -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 { | ||||||
|  | } | ||||||
| @ -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 { | ||||||
|  | } | ||||||
| @ -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<String> ids = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |         // add some person documents | ||||||
|  |         for (int i = 0; i < 5; i++) { | ||||||
|  |             ids.add(insertRandomPersonDocument().id()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // perform bulk read | ||||||
|  |         List<Person> 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<Person> 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<String> ids = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |         // add some person documents | ||||||
|  |         for (int i = 0; i < 5; i++) { | ||||||
|  |             ids.add(insertRandomPersonDocument().id()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // load persons from Couchbase | ||||||
|  |         List<Person> 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<String> 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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String> 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<JsonDocument> docs = studentGradeService.findAll(); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByCourse_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByCourse("History"); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByCourses_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByCourses("History", "Science"); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByGradeInRange_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByGradeInRange(80, 89, true); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByGradeLessThan_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByGradeLessThan(60); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByGradeGreaterThan_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByGradeGreaterThan(90); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindByCourseAndGradeInRange_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findByCourseAndGradeInRange("Math", 80, 89, true); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenFindTopGradesByCourse_thenSuccess() { | ||||||
|  |         List<JsonDocument> docs = studentGradeService.findTopGradesByCourse("Science", 2); | ||||||
|  |         printDocuments(docs); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenCountStudentsByCourse_thenSuccess() { | ||||||
|  |         Map<String, Long> map = studentGradeService.countStudentsByCourse(); | ||||||
|  |         printMap(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenSumCreditHoursByStudent_thenSuccess() { | ||||||
|  |         Map<String, Long> map = studentGradeService.sumCreditHoursByStudent(); | ||||||
|  |         printMap(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenSumGradePointsByStudent_thenSuccess() { | ||||||
|  |         Map<String, Long> map = studentGradeService.sumGradePointsByStudent(); | ||||||
|  |         printMap(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public final void whenCalculateGpaByStudent_thenSuccess() { | ||||||
|  |         Map<String, Float> map = studentGradeService.calculateGpaByStudent(); | ||||||
|  |         printGpaMap(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private void printMap(Map<String, Long> map) { | ||||||
|  |         for(Map.Entry<String, Long> entry : map.entrySet()) { | ||||||
|  |             logger.info(entry.getKey() + "=" + entry.getValue()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void printGpaMap(Map<String, Float> map) { | ||||||
|  |         for(Map.Entry<String, Float> entry : map.entrySet()) { | ||||||
|  |             logger.info(entry.getKey() + "=" + entry.getValue()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void printDocuments(List<JsonDocument> 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()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<JsonNode> 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<JsonNode> 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<JsonNode> 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<JsonNode> 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<JsonDocument> 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<JsonDocument> 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)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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 { | ||||||
|  | } | ||||||
| @ -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 { | ||||||
|  | } | ||||||
| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								couchbase/src/test/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								couchbase/src/test/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration> | ||||||
|  |     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>web - %date [%thread] %-5level %logger{36} - %message%n | ||||||
|  |             </pattern> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <logger name="org.springframework" level="WARN" /> | ||||||
|  |     <logger name="org.springframework.transaction" level="WARN" /> | ||||||
|  | 
 | ||||||
|  |     <!-- in order to debug some marshalling issues, this needs to be TRACE --> | ||||||
|  |     <logger name="org.springframework.web.servlet.mvc" level="WARN" /> | ||||||
|  | 
 | ||||||
|  |     <root level="INFO"> | ||||||
|  |         <appender-ref ref="STDOUT" /> | ||||||
|  |     </root> | ||||||
|  | </configuration> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user