Initial Version of Spring-Webflux

parents
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
\ No newline at end of file
# Spring Boot Webflux Reactive Mongo
This is a sample application that shows how to build a web application using
- Spring Boot 2
- Spring Webflux
- Spring Reactive Data MongoDb
<br/>
Please see the following pages for more details
- Spring Web Reactive <br/><a>http://docs.spring.io/spring-framework/docs/5.0.0.M1/spring-framework-reference/html/web-reactive.html</a>
- Spring Data Reactive <br/><a>https://spring.io/blog/2016/11/28/going-reactive-with-spring-data</a>
- Spring Functional Web Framework <br/><a>https://spring.io/blog/2016/09/22/new-in-spring-5-functional-web-framework</a>
## Running
In application.properties, configure appropriate values.
<br/>
<br/>
Run this using using the gradle wrapper included
```
./gradlew bootRun
```
.route(GET("/users/{id}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/users").and(accept(APPLICATION_JSON)), userHandler::getUsers)
.andRoute(POST("/users").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), userHandler::createUser)
.andRoute(PUT("/users/updateuser/{id}").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), userHandler::updateUser)
.andRoute(DELETE("/users/deleteuser/{id}"), userHandler::deleteUser)
And then go to http://localhost:8080 to test the API's.
`http://localhost:8080/users/1` : Get the User by passing the attribute id using GET
`http://localhost:8080/users` : Get the User Details using GET
`http://localhost:8080/users` : Create the User using POST
`http://localhost:8080/users/updateuser/{id}` : Update the User details using PUT
`http://localhost:8080/users/deleteuser/{id}` : Delete the User by passing the attribute id using DELETE
buildscript {
ext {
springBootVersion = '2.1.8.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
compile('org.springframework.boot:spring-boot-starter-webflux')
compileOnly('org.projectlombok:lombok')
/*testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}*/
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation 'io.projectreactor:reactor-test'
testImplementation('junit:junit:4.13')
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.2'
testCompile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
}
test {
useJUnitPlatform()
}
\ No newline at end of file
#Thu Sep 07 21:24:57 WIB 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1.zip
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
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
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
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
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save ( ) {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
applications:
- name: SpringWebFluxMongoDB
memory: 768M
instances: 1
path: build\libs\user-service-0.0.1-SNAPSHOT.jar
random-route: true
services:
- mongodb
buildpacks:
- https://github.com/cloudfoundry/java-buildpack.git
spring.data.mongodb.uri=mongodb://localhost:27017/oms
\ No newline at end of file
#spring:
# data:
# mongodb:
# uri: mongodb://harichandraprasad.nimmagadda@gmail.com:HariPriya4$@ds139956.mlab.com:39956/demo
# host: localhost
# port: 27017
# database: demo
\ No newline at end of file
lombok.anyConstructor.addConstructorProperties=true
config.stopBubbling = true
lombok.fieldDefaults.defaultPrivate = true
\ No newline at end of file
package com.nisum.ecommerce.oms;
import com.nisum.ecommerce.oms.model.User;
import com.nisum.ecommerce.oms.repository.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
/*@Bean
public CommandLineRunner user(UserRepository repository) {
final User hendi = new User(1, "Hendi", "Santika@gmail.com");
final User naruto = new User(2, "Uzumaki", "Naruto@gmail.com");
final User sasuke = new User(3, "Uchiha", "Sasuke@gmail.com");
final User sakura = new User(4, "Sakura", "Haruno@gmail.com");
final User kakashi = new User(5, "Hatake", "Kakashi@gmail.com");
repository.saveAll(Flux.just(hendi, naruto, sasuke, sakura, kakashi)).subscribe();
// repository.findByName("hendi").log().map(User::getName).subscribe(System.out::println);
//repository.findById("hendi").log().map(User::getId).subscribe(System.out::println);
return (args) -> {
// // save users
repository.save(new User(1, "Hendi", "Santika@gmail.com"));
repository.save(new User(2, "Uzumaki", "Naruto@gmail.com"));
repository.save(new User(3, "Uchiha", "Sasuke@gmail.com"));
repository.save(new User(4, "Sakura", "Haruno@gmail.com"));
repository.save(new User(5, "Hatake", "Kakashi@gmail.com"));
};
}*/
}
package com.nisum.ecommerce.oms.components;
import com.nisum.ecommerce.oms.handlers.UserHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
@Configuration
public class UserRouter {
@Bean
public RouterFunction<ServerResponse> routes(UserHandler userHandler) {
return RouterFunctions
.route(GET("/users/{id}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/users").and(accept(APPLICATION_JSON)), userHandler::getUsers)
.andRoute(POST("/users").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), userHandler::createUser)
.andRoute(PUT("/users/updateuser/{id}").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), userHandler::updateUser)
.andRoute(DELETE("/users/deleteuser/{id}"), userHandler::deleteUser)
.andRoute(GET("/users/events").and(accept(APPLICATION_JSON)), userHandler::getUserByEvents);
}
/* @Bean
public RouterFunction<ServerResponse> userRoutes(UserHandler userHandler) {
return RouterFunctions.route()
.path("/users", builder -> builder
.POST("", accept(APPLICATION_JSON), userHandler::createUser)
.GET("/{id}", accept(APPLICATION_JSON), userHandler::getUser)
.GET("", accept(APPLICATION_JSON), userHandler::getUsers))
.PUT("/updateuser/{id}", accept(APPLICATION_JSON), userHandler::updateUser)
.DELETE("/deleteuser/{id}", accept(APPLICATION_JSON), userHandler::deleteUser)
.GET("/{id}/events", accept(APPLICATION_JSON), userHandler::getUserByEvents)
.build();
}
*/
}
package com.nisum.ecommerce.oms.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@Configuration
@EnableWebFlux
public class CORSConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET, POST, PUT, DELETE")
.allowedHeaders("*");
}
}
package com.nisum.ecommerce.oms.handlers;
import com.nisum.ecommerce.oms.model.User;
import com.nisum.ecommerce.oms.model.UserEvents;
import com.nisum.ecommerce.oms.repository.UserRepository;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.Date;
import java.util.stream.Stream;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.BodyInserters.fromPublisher;
import static org.springframework.web.reactive.function.server.ServerResponse.notFound;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@Component
public class UserHandler {
private UserRepository userRepository;
public UserHandler(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Mono<ServerResponse> createUser(ServerRequest request) {
Mono<User> user = request.bodyToMono(User.class);
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(fromPublisher(user.flatMap(userRepository::save), User.class));
}
public Mono<ServerResponse> getUser(ServerRequest request) {
final int id = Integer.parseInt(request.pathVariable("id"));
final Mono<User> user = userRepository.findById(id);
return user.flatMap(usr -> ok().contentType(APPLICATION_JSON)
.body(fromPublisher(user, User.class)))
.switchIfEmpty(notFound().build());
}
public Mono<ServerResponse> getUsers(ServerRequest request) {
return ok().contentType(APPLICATION_JSON)
.body(fromPublisher(userRepository.findAll(), User.class));
}
/*public Mono<ServerResponse> deleteUser(ServerRequest request) {
final int userId = Integer.parseInt(request.pathVariable("id"));
final Mono<User> user = userRepository.findById(userId);
return user
.flatMap(existingUser ->
userRepository.deleteById(existingUser.getId())
.flatMap(usr -> ok().contentType(APPLICATION_JSON)
.body(fromPublisher(user, User.class))
.switchIfEmpty(notFound().build())
));
}*/
/*public Mono<ServerResponse> deleteUser(ServerRequest request) {
final int userId = Integer.parseInt(request.pathVariable("id"));
final Mono<User> user = userRepository.findById(userId);
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(user.flatMap(existingUser ->
userRepository.deleteById(existingUser.getId())), Void.class);
}*/
public Mono<ServerResponse> deleteUser(ServerRequest request) {
final int userId = Integer.parseInt(request.pathVariable("id"));
final Mono<User> user = userRepository.findById(userId);
return userRepository.findById(userId)
.flatMap(existingUser ->
userRepository.delete(existingUser)
.then(ServerResponse.ok().<Void>build())
).switchIfEmpty(notFound().build());
}
public Mono<ServerResponse> updateUser(ServerRequest request) {
/* final int userId = Integer.parseInt(request.pathVariable("id"));
final Mono<User> userRepositoryById = userRepository.findById(userId);*/
Mono<User> userMono = request.bodyToMono(User.class);
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(BodyInserters.fromPublisher(
userMono.flatMap(userRepository::save), User.class)
).switchIfEmpty(notFound().build());
}
public Mono<ServerResponse> getUserByEvents(ServerRequest serverRequest) {
Integer userId = Integer.valueOf(serverRequest.pathVariable("id"));
return ServerResponse.ok()
.contentType(MediaType.TEXT_EVENT_STREAM)
.body(
userRepository.findById(userId)
.flatMapMany(employee -> {
Flux<Long> intervalFlux = Flux.interval(Duration.ofSeconds(2));
Flux<UserEvents> employeeEventsFlux =
Flux.fromStream(Stream.generate(()-> new UserEvents(employee, new Date())));
return Flux.zip(intervalFlux,employeeEventsFlux).map(objects -> objects.getT2());
}), UserEvents.class
);
}
}
package com.nisum.ecommerce.oms.model;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Getter
@Setter
@Builder(toBuilder = true)
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "user")
public class User {
@Id
Integer id;
String name;
String email;
public User(String name) {
this.name = name;
}
/*public User(Integer id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}*/
/*
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
*/
}
package com.nisum.ecommerce.oms.model;
import java.util.Date;
public class UserEvents {
private User user;
private Date date;
public UserEvents(User user, Date date) {
this.user = user;
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "UserEvents{" +
"user=" + user +
", date=" + date +
'}';
}
}
package com.nisum.ecommerce.oms.repository;
import com.nisum.ecommerce.oms.model.User;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface UserRepository extends ReactiveMongoRepository<User, Integer> {
Flux<User> findAll();
Mono<User> findById(int id);
Mono<User> findByName(String name);
Mono<User> save(User user);
}
spring.data.mongodb.uri=mongodb://localhost:27017/oms
\ No newline at end of file
#spring:
# data:
# mongodb:
# uri: mongodb://harichandraprasad.nimmagadda@gmail.com:HariPriya4$@ds139956.mlab.com:39956/demo
# host: localhost
# port: 27017
# database: demo
\ No newline at end of file
package com.nisum.ecommerce.oms;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserApplicationTests {
@Test
public void contextLoads() {
}
}
package com.nisum.ecommerce.oms.controller;
import com.nisum.ecommerce.oms.components.UserRouter;
import com.nisum.ecommerce.oms.handlers.UserHandler;
import com.nisum.ecommerce.oms.model.User;
import com.nisum.ecommerce.oms.repository.UserRepository;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {UserRouter.class, UserHandler.class})
@WebFluxTest
public class TestUserHandlerComponent {
@Autowired
private ApplicationContext context;
@MockBean
private UserRepository userRepository;
private WebTestClient webTestClient;
@Before
public void setUp() {
webTestClient = WebTestClient.bindToApplicationContext(context).build();
}
@Test
public void testGetUserById() {
User user = User.builder().id(8).name("ABC").email("abc@xyz.com").build();
Mono<User> userMono = Mono.just(user);
when(userRepository.findById(8)).thenReturn(userMono);
webTestClient.get()
.uri("/users/8")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(userResponse -> {
Assertions.assertThat(userResponse.getId()).isEqualTo(8);
Assertions.assertThat(userResponse.getName()).isEqualTo("ABC");
Assertions.assertThat(userResponse.getEmail()).isEqualTo("abc@xyz.com");
}
);
}
@Test
public void testGetUsers() {
User user1 = User.builder().id(1).name("ABC").email("abc@xyz.com").build();
User user2 = User.builder().id(2).name("XYZ").email("xyz@abc.com").build();
when(userRepository.findAll()).thenReturn(Flux.just(user1, user2));
webTestClient.get()
.uri("/users")
.exchange()
.expectStatus().isOk()
.expectBodyList(User.class)
.value(userResponse -> {
Assertions.assertThat(userResponse.get(0).getId()).isEqualTo(1);
Assertions.assertThat(userResponse.get(0).getName()).isEqualTo("ABC");
Assertions.assertThat(userResponse.get(0).getEmail()).isEqualTo("abc@xyz.com");
Assertions.assertThat(userResponse.get(1).getId()).isEqualTo(2);
Assertions.assertThat(userResponse.get(1).getName()).isEqualTo("XYZ");
Assertions.assertThat(userResponse.get(1).getEmail()).isEqualTo("xyz@abc.com");
}
);
}
@Test
public void testCreateUser() {
User user = User.builder().id(1).name("ABC").email("abc@xyz.com").build();
Mono<User> UserMono = Mono.just(user);
when(userRepository.save(any())).thenReturn(UserMono);
webTestClient.post()
.uri("/users")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(userResponse -> {
Assertions.assertThat(userResponse.getId()).isEqualTo(1);
Assertions.assertThat(userResponse.getName()).isEqualTo("ABC");
Assertions.assertThat(userResponse.getEmail()).isEqualTo("abc@xyz.com");
}
);
}
@Test
public void testUpdateUser() {
User user = User.builder().id(1).name("ABC").email("abc@xyz.com").build();
Mono<User> UserMono = Mono.just(user);
when(userRepository.save(any())).thenReturn(UserMono);
webTestClient.put()
.uri("/users/updateuser/2")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(userResponse -> {
Assertions.assertThat(userResponse.getId()).isEqualTo(1);
Assertions.assertThat(userResponse.getName()).isEqualTo("ABC");
Assertions.assertThat(userResponse.getEmail()).isEqualTo("abc@xyz.com");
}
);
}
@Test
public void testDeleteUser() {
User user = User.builder().id(1).name("ABC").email("abc@xyz.com").build();
Mono<User> UserMono = Mono.just(user);
when(userRepository.save(any())).thenReturn(UserMono);
webTestClient.delete()
.uri("/users/deleteuser/1")
.exchange()
.expectStatus().isOk();
/* .expectBody(User.class)
.value(userResponse -> {
Assertions.assertThat(userResponse.getId()).isEqualTo(1);
Assertions.assertThat(userResponse.getName()).isEqualTo("ABC");
Assertions.assertThat(userResponse.getEmail()).isEqualTo("abc@xyz.com");
}
);*/
}
}
package com.nisum.ecommerce.oms.controller;
import com.nisum.ecommerce.oms.model.User;
import com.nisum.ecommerce.oms.repository.UserRepository;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.FluxExchangeResult;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import java.util.Collections;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class TestUserHandlerIntegration {
@Autowired
private WebTestClient webTestClient;
@Autowired
private UserRepository userRepository;
@Test
public void testCreateUserSuccess() {
User user = User.builder().id(6).name("Chandra").email("Chandra@gmail.com").build();
webTestClient.post().uri("/users")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.id").isNotEmpty()
.jsonPath("$.name").isEqualTo("Chandra")
.jsonPath("$.email").isEqualTo("Chandra@gmail.com");
}
@Test
public void testCreateUserFailure() {
User user = User.builder().id(6).name("Nisum").email("NisumTech@nisum.com").build();
webTestClient.post().uri("/users")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.id").isNotEmpty()
.jsonPath("$.name").isEqualTo("Technologies")
.jsonPath("$.email").isEqualTo("Technologies@nisum.com");
}
@Test
public void getUserByIdSuccessTest() {
User user = userRepository.save(new User(1,"Hello, World!", "test@gmail.com")).block();
webTestClient.get()
.uri("/users/{id}", Collections.singletonMap("id", user.getId()))
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(response ->
Assertions.assertThat(response.getResponseBody()).isNotNull());
}
@Test
public void getUserByIdErrorTest() {
User user = userRepository.save(new User(12,"Hello, World!", "test@gmail.com")).block();
webTestClient.get()
.uri("/users/{id}", Collections.singletonMap("id", user.getName()))
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(response ->
Assertions.assertThat(response.getResponseBody()).isNotNull());
}
@Test
public void getAllUsersTest() {
webTestClient.get().uri("/users")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBodyList(User.class);
/*this.webTestClient.get().uri("/users").exchange().expectStatus().isOk()
.expectBody(String.class)
.isEqualTo("Hello, World!");*/
/*this.webTestClient.get().uri("/users")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
//.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(String.class)
.isEqualTo("Hendi");
*/
/*webTestClient.post().uri("/users")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(User.builder().name("This is a Test Tweet").build()), User.class)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.id").isNotEmpty()
.jsonPath("$.text").isEqualTo("This is a Test Tweet");*/
/*
FluxExchangeResult<User> result = this.webTestClient.get()
.uri("/users")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.returnResult(User.class);;
//.expectBody(String.class).isEqualTo("Hendi");
Flux<User> eventFlux = result.getResponseBody();
StepVerifier.create(eventFlux)
.expectNextCount(10)
.thenCancel()
.verify();
*/
}
@Test
public void testUpdateUser() {
User user = userRepository.save(User.builder().id(1).name("Hendi").email("Santika@gmail.com").build()).block();
User newUserData = User.builder().id(1).name("Prasad Updated").email("PrasadUpdated@gmail.com").build();
webTestClient.put()
.uri("/users/updateuser/{id}", Collections.singletonMap("id", user.getId()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(newUserData), User.class)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.name").isEqualTo("Prasad Updated");
}
@Test
public void testDeleteUser() {
User user = userRepository.save(User.builder().id(1).name("Hendi").email("Santika@gmail.com").build()).block();
webTestClient.delete()
.uri("/users/deleteuser/{id}", Collections.singletonMap("id", user.getId()))
.exchange()
.expectStatus().isOk();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment