├── .gitignore
├── LICENSE
├── README.md
├── api-gateway
├── .classpath
├── .gitignore
├── .project
├── .settings
│ ├── gradle
│ │ ├── org.springsource.ide.eclipse.gradle.core.import.prefs
│ │ ├── org.springsource.ide.eclipse.gradle.core.prefs
│ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs
│ └── org.eclipse.jdt.core.prefs
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservice
│ │ └── gateway
│ │ ├── Application.java
│ │ └── config
│ │ └── OAuthConfiguration.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
├── auth-server
├── .classpath
├── .gitignore
├── .project
├── .settings
│ ├── gradle
│ │ ├── org.springsource.ide.eclipse.gradle.core.import.prefs
│ │ ├── org.springsource.ide.eclipse.gradle.core.prefs
│ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs
│ └── org.eclipse.jdt.core.prefs
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservice
│ │ └── auth
│ │ ├── Application.java
│ │ ├── api
│ │ └── AuthUserController.java
│ │ └── config
│ │ ├── OAuthConfiguration.java
│ │ └── ResourceServerConfiguration.java
│ └── resources
│ ├── application.yml
│ ├── bootstrap.yml
│ └── schema.sql
├── build-all-projects.sh
├── comments-webservice
├── .gitignore
├── .project
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservices
│ │ └── comments
│ │ ├── Application.java
│ │ ├── apis
│ │ └── CommentsController.java
│ │ ├── config
│ │ └── CommentsConfiguration.java
│ │ └── dtos
│ │ └── CommentDTO.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
├── config-server
├── .classpath
├── .gitignore
├── .project
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservices
│ │ └── config
│ │ └── Application.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
├── docker-compose.yml
├── docker-image-all-projects.sh
├── images
├── Application_Components.jpg
├── Decentralized Goverance.png
├── OAuth2 abstract protocol flow.png
└── Target_Architecture.jpg
├── task-webservice
├── .classpath
├── .gitignore
├── .project
├── .settings
│ ├── gradle
│ │ ├── org.springsource.ide.eclipse.gradle.core.import.prefs
│ │ ├── org.springsource.ide.eclipse.gradle.core.prefs
│ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs
│ └── org.eclipse.jdt.core.prefs
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservices
│ │ └── task
│ │ ├── Application.java
│ │ ├── apis
│ │ ├── CommentsService.java
│ │ └── TaskController.java
│ │ ├── config
│ │ ├── OAuthClientConfiguration.java
│ │ └── TaskConfiguration.java
│ │ ├── dtos
│ │ └── TaskDTO.java
│ │ └── model
│ │ ├── CommentCollectionResource.java
│ │ └── CommentResource.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
├── understanding_notes.pages
├── user-webservice
├── .classpath
├── .gitignore
├── .project
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservices
│ │ └── user
│ │ ├── Application.java
│ │ ├── apis
│ │ └── UserController.java
│ │ ├── config
│ │ └── UserConfiguration.java
│ │ └── dto
│ │ └── UserDTO.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
├── web-portal
├── .classpath
├── .gitignore
├── .project
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── public
│ ├── css
│ │ └── bootstrap.min.css
│ ├── index.html
│ ├── js
│ │ ├── app
│ │ │ ├── controller
│ │ │ │ ├── homeController.js
│ │ │ │ ├── navController.js
│ │ │ │ ├── taskController.js
│ │ │ │ └── userController.js
│ │ │ ├── oauthapp.js
│ │ │ └── services
│ │ │ │ └── dataservice.js
│ │ └── libs
│ │ │ ├── angular-route.min.js
│ │ │ └── angular.min.js
│ └── views
│ │ ├── home.html
│ │ ├── task-comments.html
│ │ ├── task-details.html
│ │ ├── task.html
│ │ └── user.html
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── rohitghatol
│ │ └── microservices
│ │ └── portal
│ │ └── Application.java
│ └── resources
│ ├── application.yml
│ └── bootstrap.yml
└── webservice-registry
├── .classpath
├── .gitignore
├── .project
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
└── main
├── java
└── com
│ └── rohitghatol
│ └── microservices
│ └── registry
│ └── Application.java
└── resources
├── application.yml
└── bootstrap.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 |
14 | build
15 | bin
16 | .settings
17 | .gradle
18 | .DS_Store
19 | .classpath
20 |
--------------------------------------------------------------------------------
/api-gateway/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/api-gateway/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | api-gateway
4 |
5 |
6 |
7 | org.springsource.ide.eclipse.gradle.core.nature
8 | org.eclipse.jdt.core.javanature
9 |
10 |
11 |
12 | org.eclipse.jdt.core.javabuilder
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/api-gateway/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences
2 | #Mon Apr 06 13:25:59 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | enableDependendencyManagement=true
10 | projects=;
11 |
--------------------------------------------------------------------------------
/api-gateway/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences
2 | #Mon Apr 06 13:26:03 PDT 2015
3 | org.springsource.ide.eclipse.gradle.linkedresources=
4 | org.springsource.ide.eclipse.gradle.rootprojectloc=
5 |
--------------------------------------------------------------------------------
/api-gateway/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences
2 | #Mon Apr 06 13:26:02 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | useHierarchicalNames=false
10 |
--------------------------------------------------------------------------------
/api-gateway/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #
2 | #Tue Apr 07 15:03:53 PDT 2015
3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
4 | org.eclipse.jdt.core.compiler.compliance=1.7
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
10 | eclipse.preferences.version=1
11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
12 | org.eclipse.jdt.core.compiler.source=1.7
13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
14 |
--------------------------------------------------------------------------------
/api-gateway/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | The api-gateway application acts the router and authentication and authorization endpoint.
4 |
5 | The Zuul api gateway solves a very common use case where a UI application wants to proxy calls to one or more back end services. This feature is useful for a user interface to proxy to the backend services it requires, avoiding the need to manage CORS and authentication concerns independently for all the backends.For example in our application `/api/user/**` endpoint is mapped to the `user-webservice`.
6 |
7 | It also knows how to invoke the authorization server in case the user is not authenticated. Once the authentication is complete, it relays the OAuth2 token to the respective services so that they can find the authenticated user and provide services.
8 |
9 | ##Pre-requisites
10 |
11 | ### Projects that need to be started before
12 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
13 | * [webserver-registry](/../../blob/master/webservice-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
14 |
15 | ### Running the application
16 | * Build the application by running the `./gradlew clean build` gradle command at the "task-webservice" project root folder on the terminal.
17 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-api-gateway-0.0.1.jar` command at the terminal.
18 |
19 | ## External Configuration
20 | Please refer to [user webservice](/../../blob/master/user-webservice/README.md) for details on how the external configuration works. Note that there is separate configuration file for each Spring application; the application should refer to it's own .yml file for configuration.
--------------------------------------------------------------------------------
/api-gateway/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | seurityVersion = '2.0.7.RELEASE'
6 | }
7 | repositories {
8 | mavenCentral()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
14 | classpath 'se.transmode.gradle:gradle-docker:1.2'
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 | jar {
24 | baseName = 'sample-api-gateway'
25 | version = '0.0.1'
26 | }
27 |
28 | repositories {
29 | mavenCentral()
30 | jcenter()
31 | }
32 | dependencies {
33 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
34 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
35 | compile("org.springframework.boot:spring-boot-starter-data-jpa:${project.bootVersion}")
36 | compile("mysql:mysql-connector-java:5.1.30")
37 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
38 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
39 | compile("org.springframework.cloud:spring-cloud-starter-zuul:${project.cloudVersion}")
40 | compile("org.springframework.cloud:spring-cloud-starter-security:${project.cloudVersion}")
41 |
42 | compile("org.springframework.boot:spring-boot-starter-security:${project.bootVersion}")
43 | compile("org.springframework.security.oauth:spring-security-oauth2:${project.seurityVersion}")
44 |
45 | testCompile group: 'junit', name: 'junit', version: '4.+'
46 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
47 | }
48 |
49 | /**
50 | * These values(group & mainClassName) are required by the gradle docker plugin.
51 | *
52 | * The "group" value feeds into the docker tag and is required if you want to push the images
53 | * to docker hub.
54 | *
55 | * The "mainClassName" value tells which class has the "main" entry point for running the
56 | * Spring boot application.
57 | */
58 | group = 'anilallewar'
59 | mainClassName = 'com.rohitghatol.microservice.gateway.Application'
60 |
61 | sourceCompatibility = 1.7
62 | targetCompatibility = 1.7
63 |
64 | distDocker {
65 | exposePort 8080
66 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
67 | }
68 |
69 | /**
70 | * On Mac, docker can't be connected locally since it is running in a separate VM.
71 | *
72 | * NOTE: If you have not added your TLS certs to boot2docker; you would need to change
73 | * docker to run the API on HTTP; while boot2docker 1.3 comes with TLS enabled. Hence
74 | * you need to run the following command "$(docker run sequenceiq/socat)" at the docker
75 | * prompt so that this image maps the api to HTTP port. You can check that it is working
76 | * correctly using the command "curl http://192.168.59.103:2375/_ping"
77 | *
78 | *
79 | * In order to change docker to run the remote API, we need to set the following flags:
80 | * 1. useApi true => Use the Docker Remote API instead of a locally installed docker binary.
81 | * 2. hostUrl => set the URL used to contact the Docker server. Defaults to http://localhost:2375
82 | */
83 | docker {
84 | useApi true
85 | hostUrl 'http://192.168.59.103:2375'
86 | baseImage = 'java:7'
87 | }
88 |
89 | bootRun {
90 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n','-Dspring.profiles.active=dev']
91 | }
92 |
93 | run {
94 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n','-Dspring.profiles.active=dev']
95 | }
96 |
97 |
98 | task createWrapper(type: Wrapper) {
99 | gradleVersion = '2.0'
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/api-gateway/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:52:39 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/api-gateway/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/api-gateway/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/api-gateway/src/main/java/com/rohitghatol/microservice/gateway/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservice.gateway;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
9 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
10 | import org.springframework.cloud.security.oauth2.resource.EnableOAuth2Resource;
11 | import org.springframework.cloud.security.oauth2.sso.EnableOAuth2Sso;
12 | import org.springframework.context.annotation.ComponentScan;
13 | import org.springframework.context.annotation.Configuration;
14 |
15 |
16 | /**
17 | * The Main Spring Boot Application class which does the following
18 | *
19 | *
Act as a Eureka client; this behavior is provided by the
20 | * {@link EnableEurekaClient} annotation. The Eureka server URL is provided by
21 | * the external configuration provided by the config server.
22 | *
Act as Zuul reverse proxy; this behavior is provided by the
23 | * {@link EnableZuulProxy} annotation. Annotating the application with
24 | * {@link EnableZuulProxy} forwards local calls to the appropriate service. By
25 | * convention, a service with the Eureka ID "users", will receive requests from
26 | * the proxy located at /users (with the prefix stripped).
27 | *
Enable OAuth2 single sign on (SSO) using the {@link EnableOAuth2Sso}
28 | * annotation.
29 | *
30 | *
If your app has a Spring Cloud Zuul embedded reverse proxy (using
31 | * {@link EnableZuulProxy}) then you can ask it to forward OAuth2 access tokens
32 | * downstream to the services it is proxying.
33 | *
If you also add the {@link EnableOAuth2Sso} annotation; then it will (in
34 | * addition to loggin the user in and grabbing a token) pass the authentication
35 | * token downstream to the /proxy/* services.
36 | *
If those services are implemented with {@link EnableOAuth2Resource} then
37 | * they will get a valid token in the correct header.
38 | *
39 | *
40 | *
Note that all these annotations work in conjunction with properties
41 | * defined in the external configuration files specified by the config server.
42 | *
43 | *
44 | *
45 | * @author rohitghatol
46 | */
47 |
48 | @Configuration
49 | @ComponentScan
50 | @EnableAutoConfiguration
51 | @EnableZuulProxy
52 | @EnableEurekaClient
53 | @EnableOAuth2Sso
54 | public class Application {
55 |
56 | /**
57 | * The main method.
58 | *
59 | * @param args
60 | * the arguments
61 | */
62 | public static void main(String[] args) {
63 | SpringApplication.run(Application.class, args);
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/api-gateway/src/main/java/com/rohitghatol/microservice/gateway/config/OAuthConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservice.gateway.config;
2 |
3 | import java.io.IOException;
4 |
5 | import javax.servlet.Filter;
6 | import javax.servlet.FilterChain;
7 | import javax.servlet.ServletException;
8 | import javax.servlet.http.Cookie;
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | import org.springframework.cloud.security.oauth2.sso.OAuth2SsoConfigurerAdapter;
13 | import org.springframework.context.annotation.Configuration;
14 | import org.springframework.http.HttpMethod;
15 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
16 | import org.springframework.security.web.csrf.CsrfFilter;
17 | import org.springframework.security.web.csrf.CsrfToken;
18 | import org.springframework.security.web.csrf.CsrfTokenRepository;
19 | import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
20 | import org.springframework.stereotype.Component;
21 | import org.springframework.web.filter.OncePerRequestFilter;
22 | import org.springframework.web.util.WebUtils;
23 |
24 |
25 | /**
26 | * The Class OAuthConfiguration that sets up the OAuth2 single sign on
27 | * configuration and the web security associated with it.
28 | */
29 | @Configuration
30 | @Component
31 | public class OAuthConfiguration extends OAuth2SsoConfigurerAdapter {
32 |
33 | private static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";
34 | private static final String CSRF_ANGULAR_HEADER_NAME = "X-XSRF-TOKEN";
35 |
36 | @Override
37 | public void match(RequestMatchers matchers) {
38 | matchers.anyRequest();
39 | }
40 |
41 | /**
42 | * Define the security that applies to the proxy
43 | */
44 | @Override
45 | public void configure(HttpSecurity http) throws Exception {
46 | http
47 | .authorizeRequests()
48 | //Allow access to all static resources without authentication
49 | .antMatchers("/","/**/*.html").permitAll()
50 | .anyRequest().authenticated()
51 | .antMatchers(HttpMethod.GET, "/api/user/**","/api/task/**").access("#oauth2.hasScope('read')")
52 | .antMatchers(HttpMethod.OPTIONS, "/api/user/**","/api/task/**").access("#oauth2.hasScope('read')")
53 | .antMatchers(HttpMethod.POST, "/api/user/**","/api/task/**").access("#oauth2.hasScope('write')")
54 | .antMatchers(HttpMethod.PUT, "/api/user/**","/api/task/**").access("#oauth2.hasScope('write')")
55 | .antMatchers(HttpMethod.PATCH, "/api/user/**","/api/task/**").access("#oauth2.hasScope('write')")
56 | .antMatchers(HttpMethod.DELETE, "/api/user/**","/api/task/**").access("#oauth2.hasScope('write')")
57 | .and().csrf().csrfTokenRepository(this.getCSRFTokenRepository())
58 | .and().addFilterAfter(this.createCSRFHeaderFilter(), CsrfFilter.class);
59 | }
60 |
61 | /**
62 | * Spring security offers in-built protection for cross site request forgery
63 | * (CSRF) by needing a custom token in the header for any requests that are
64 | * NOT safe i.e. modify the resources from the server e.g. POST, PUT & PATCH
65 | * etc.
66 | *
67 | *
68 | * This protection is achieved using cookies that send a custom value (would
69 | * remain same for the session) in the first request and then the front-end
70 | * would send back the value as a custom header.
71 | *
72 | *
73 | * In this method we create a filter that is applied to the web security as
74 | * follows:
75 | *
76 | *
Spring security provides the CSRF token value as a request attribute;
77 | * so we extract it from there.
78 | *
If we have the token, Angular wants the cookie name to be
79 | * "XSRF-TOKEN". So we add the cookie if it's not there and set the path for
80 | * the cookie to be "/" which is root. In more complicated cases, this might
81 | * have to be the context root of the api gateway.
82 | *
We forward the request to the next filter in the chain
83 | *
84 | *
85 | * The request-to-cookie filter that we add needs to be after the
86 | * csrf() filter so that the request attribute for CsrfToken
87 | * has been already added before we start to process it.
88 | *
89 | * @return
90 | */
91 | private Filter createCSRFHeaderFilter() {
92 | return new OncePerRequestFilter() {
93 | @Override
94 | protected void doFilterInternal(HttpServletRequest request,
95 | HttpServletResponse response, FilterChain filterChain)
96 | throws ServletException, IOException {
97 | CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
98 | .getName());
99 | if (csrf != null) {
100 | Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME);
101 | String token = csrf.getToken();
102 | if (cookie == null || token != null
103 | && !token.equals(cookie.getValue())) {
104 | cookie = new Cookie(CSRF_COOKIE_NAME, token);
105 | cookie.setPath("/");
106 | response.addCookie(cookie);
107 | }
108 | }
109 | filterChain.doFilter(request, response);
110 | }
111 | };
112 | }
113 |
114 | /**
115 | * Angular sends the CSRF token in a custom header named "X-XSRF-TOKEN"
116 | * rather than the default "X-CSRF-TOKEN" that Spring security expects.
117 | * Hence we are now telling Spring security to expect the token in the
118 | * "X-XSRF-TOKEN" header.
119 | *
120 | * This customization is added to the csrf() filter.
121 | *
122 | * @return
123 | */
124 | private CsrfTokenRepository getCSRFTokenRepository() {
125 | HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
126 | repository.setHeaderName(CSRF_ANGULAR_HEADER_NAME);
127 | return repository;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/api-gateway/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | org:
4 | springframework:
5 | security: DEBUG
--------------------------------------------------------------------------------
/api-gateway/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: api-gateway
4 | cloud:
5 | config:
6 | uri: http://localhost:8888
7 |
8 | ---
9 |
10 | spring:
11 | profiles: docker
12 | cloud:
13 | config:
14 | uri: http://192.168.59.103:8888
--------------------------------------------------------------------------------
/auth-server/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/auth-server/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | auth-server
4 |
5 |
6 |
7 | org.springsource.ide.eclipse.gradle.core.nature
8 | org.eclipse.jdt.core.javanature
9 |
10 |
11 |
12 | org.eclipse.jdt.core.javabuilder
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/auth-server/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences
2 | #Mon Apr 06 13:25:59 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | enableDependendencyManagement=true
10 | projects=;
11 |
--------------------------------------------------------------------------------
/auth-server/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences
2 | #Mon Apr 06 13:26:03 PDT 2015
3 | org.springsource.ide.eclipse.gradle.linkedresources=
4 | org.springsource.ide.eclipse.gradle.rootprojectloc=
5 |
--------------------------------------------------------------------------------
/auth-server/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences
2 | #Mon Apr 06 13:26:02 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | useHierarchicalNames=false
10 |
--------------------------------------------------------------------------------
/auth-server/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #
2 | #Tue Apr 07 12:01:04 PDT 2015
3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
4 | org.eclipse.jdt.core.compiler.compliance=1.7
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
10 | eclipse.preferences.version=1
11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
12 | org.eclipse.jdt.core.compiler.source=1.7
13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
14 |
--------------------------------------------------------------------------------
/auth-server/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | seurityVersion = '2.0.7.RELEASE'
6 | }
7 | repositories {
8 | mavenCentral()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
14 | classpath 'se.transmode.gradle:gradle-docker:1.2'
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 |
24 | jar {
25 | baseName = 'sample-auth-server'
26 | version = '0.0.1'
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | jcenter()
32 | }
33 | dependencies {
34 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
35 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
36 | compile("org.springframework.boot:spring-boot-starter-data-jpa:${project.bootVersion}")
37 | compile("mysql:mysql-connector-java:5.1.30")
38 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
39 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
40 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
41 |
42 | compile("org.springframework.cloud:spring-cloud-starter-security:${project.cloudVersion}")
43 | compile("org.springframework.boot:spring-boot-starter-security:${project.bootVersion}")
44 | compile("org.springframework.security.oauth:spring-security-oauth2:${project.seurityVersion}")
45 |
46 | testCompile group: 'junit', name: 'junit', version: '4.+'
47 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
48 | }
49 |
50 | group = 'anilallewar'
51 | mainClassName = 'com.rohitghatol.microservice.auth.Application'
52 |
53 | sourceCompatibility = 1.7
54 | targetCompatibility = 1.7
55 |
56 |
57 | distDocker {
58 | exposePort 8899
59 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
60 | }
61 |
62 | docker {
63 | useApi true
64 | hostUrl 'http://192.168.59.103:2375'
65 | baseImage = 'java:7'
66 | }
67 |
68 | bootRun {
69 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4100,suspend=n','-Dspring.profiles.active=dev']
70 | }
71 |
72 | run {
73 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4100,suspend=n','-Dspring.profiles.active=dev']
74 | }
75 |
76 | task createWrapper(type: Wrapper) {
77 | gradleVersion = '2.0'
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/auth-server/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:53:22 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/auth-server/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/auth-server/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/auth-server/src/main/java/com/rohitghatol/microservice/auth/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservice.auth;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
9 | import org.springframework.context.annotation.ComponentScan;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
12 |
13 | /**
14 | * The Main Spring Boot Application class that starts the authorization
15 | * server.
16 | *
17 | *
18 | * Note that the server is also a Eureka client so as to register with the
19 | * Eureka server and be auto-discovered by other Eureka clients.
20 | *
21 | * @author rohitghatol
22 | */
23 |
24 | @ComponentScan
25 | @EnableAutoConfiguration
26 | @EnableEurekaClient
27 | public class Application {
28 |
29 | /**
30 | * The main method.
31 | *
32 | * @param args
33 | * the arguments
34 | */
35 | public static void main(String[] args) {
36 | SpringApplication.run(Application.class, args);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/auth-server/src/main/java/com/rohitghatol/microservice/auth/api/AuthUserController.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservice.auth.api;
2 |
3 | import java.security.Principal;
4 |
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | /**
9 | * REST endpoint to be used by other micro-services using SSO to validate the
10 | * authentication of the logged in user.
11 | *
12 | * @author anilallewar
13 | *
14 | */
15 | @RestController
16 | @RequestMapping("/")
17 | public class AuthUserController {
18 |
19 | /**
20 | * Return the principal identifying the logged in user
21 | * @param user
22 | * @return
23 | */
24 | @RequestMapping("/me")
25 | public Principal getCurrentLoggedInUser(Principal user) {
26 | return user;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/auth-server/src/main/java/com/rohitghatol/microservice/auth/config/OAuthConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservice.auth.config;
2 |
3 | import javax.sql.DataSource;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.core.Ordered;
9 | import org.springframework.core.annotation.Order;
10 | import org.springframework.security.authentication.AuthenticationManager;
11 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
12 | import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
14 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
15 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
16 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
17 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
18 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
19 | import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
20 | import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
21 | import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
22 |
23 | /**
24 | * The Class OAuth2Config defines the authorization server that would
25 | * authenticate the user and define the client that seeks authorization on the
26 | * resource owner's behalf.
27 | */
28 | @Configuration
29 | @EnableAuthorizationServer
30 | public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {
31 |
32 | @Autowired
33 | private AuthenticationManager auth;
34 |
35 | @Autowired
36 | private DataSource dataSource;
37 |
38 | private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
39 |
40 | /**
41 | * The OAuth2 tokens are defined in the datasource defined in the
42 | * auth-server.yml file stored in the Spring Cloud config
43 | * github repository.
44 | *
45 | * @return
46 | */
47 | @Bean
48 | public JdbcTokenStore tokenStore() {
49 | return new JdbcTokenStore(dataSource);
50 | }
51 |
52 | @Bean
53 | protected AuthorizationCodeServices authorizationCodeServices() {
54 | return new JdbcAuthorizationCodeServices(dataSource);
55 | }
56 |
57 | @Override
58 | public void configure(AuthorizationServerSecurityConfigurer security)
59 | throws Exception {
60 | security.passwordEncoder(passwordEncoder);
61 | }
62 |
63 | /**
64 | * We set our authorization storage feature specifying that we would use the
65 | * JDBC store for token and authorization code storage.
66 | *
67 | *
68 | * We also attach the {@link AuthenticationManager} so that password grants
69 | * can be processed.
70 | */
71 | @Override
72 | public void configure(AuthorizationServerEndpointsConfigurer endpoints)
73 | throws Exception {
74 | endpoints.authorizationCodeServices(authorizationCodeServices())
75 | .authenticationManager(auth).tokenStore(tokenStore())
76 | .approvalStoreDisabled();
77 | }
78 |
79 | /**
80 | * Setup the client application which attempts to get access to user's
81 | * account after user permission.
82 | */
83 | @Override
84 | public void configure(ClientDetailsServiceConfigurer clients)
85 | throws Exception {
86 |
87 | clients.jdbc(dataSource)
88 | .passwordEncoder(passwordEncoder)
89 | .withClient("client")
90 | .authorizedGrantTypes("authorization_code", "client_credentials",
91 | "refresh_token","password", "implicit")
92 | .authorities("ROLE_CLIENT")
93 | .resourceIds("apis")
94 | .scopes("read")
95 | .secret("secret")
96 | .accessTokenValiditySeconds(300);
97 |
98 | }
99 |
100 | /**
101 | * Configure the {@link AuthenticationManagerBuilder} with initial
102 | * configuration to setup users.
103 | *
104 | * @author anilallewar
105 | *
106 | */
107 | @Configuration
108 | @Order(Ordered.LOWEST_PRECEDENCE - 20)
109 | protected static class AuthenticationManagerConfiguration extends
110 | GlobalAuthenticationConfigurerAdapter {
111 |
112 | @Autowired
113 | private DataSource dataSource;
114 |
115 | /**
116 | * Setup 2 users with different roles
117 | */
118 | @Override
119 | public void init(AuthenticationManagerBuilder auth) throws Exception {
120 | // @formatter:off
121 | auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
122 | .password("secret").roles("USER");
123 | auth.jdbcAuthentication().dataSource(dataSource).withUser("anil")
124 | .password("password").roles("ADMIN");
125 | // @formatter:on
126 | }
127 | }
128 |
129 | }
--------------------------------------------------------------------------------
/auth-server/src/main/java/com/rohitghatol/microservice/auth/config/ResourceServerConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservice.auth.config;
5 |
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
9 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
10 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
11 | import org.springframework.stereotype.Component;
12 |
13 | /**
14 | * Since the "me" endpoint needs to be protected to be accessed only after the
15 | * OAuth2 authentication is successful; the server also becomes a resource
16 | * server.
17 | *
18 | * @author anilallewar
19 | *
20 | */
21 | @Configuration
22 | @EnableResourceServer
23 | public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
24 |
25 | /**
26 | * Configure security to allow access to the /me endpoint only if the OAuth
27 | * authorization returns "read" scope.
28 | *
29 | *
30 | * If you look at
31 | * {@link OAuthConfiguration#configure(org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer)}
32 | * to check that by default the authorization server allows "read" scope
33 | * only.
34 | */
35 | @Override
36 | public void configure(HttpSecurity http) throws Exception {
37 | // @formatter:off
38 | http
39 | .requestMatchers().antMatchers("/me")
40 | .and()
41 | .authorizeRequests()
42 | .antMatchers("/me").access("#oauth2.hasScope('read')");
43 | // @formatter:on
44 | }
45 |
46 | /**
47 | * Id of the resource that you are letting the client have access to.
48 | * Supposing you have another api ("say api2"), then you can customize the
49 | * access within resource server to define what api is for what resource id.
50 | *
51 | *
52 | *
53 | * So suppose you have 2 APIs, then you can define 2 resource servers.
54 | *
55 | *
Client 1 has been configured for access to resourceid1, so he can
56 | * only access "api1" if the resource server configures the resourceid to
57 | * "api1".
58 | *
Client 1 can't access resource server 2 since it has configured the
59 | * resource id to "api2"
60 | *
61 | *
62 | *
63 | */
64 | @Override
65 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
66 | resources.resourceId("apis");
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/auth-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | org:
4 | springframework:
5 | security: DEBUG
--------------------------------------------------------------------------------
/auth-server/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: auth-server
4 | cloud:
5 | config:
6 | uri: http://localhost:8888
7 |
8 | ---
9 |
10 | spring:
11 | profiles: docker
12 | cloud:
13 | config:
14 | uri: http://192.168.59.103:8888
15 |
--------------------------------------------------------------------------------
/auth-server/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 |
2 | DROP TABLE IF EXISTS `ClientDetails`;
3 | CREATE TABLE `ClientDetails` (
4 | `appId` varchar(256) NOT NULL,
5 | `resourceIds` varchar(256) DEFAULT NULL,
6 | `appSecret` varchar(256) DEFAULT NULL,
7 | `scope` varchar(256) DEFAULT NULL,
8 | `grantTypes` varchar(256) DEFAULT NULL,
9 | `redirectUrl` varchar(256) DEFAULT NULL,
10 | `authorities` varchar(256) DEFAULT NULL,
11 | `access_token_validity` int(11) DEFAULT NULL,
12 | `refresh_token_validity` int(11) DEFAULT NULL,
13 | `additionalInformation` varchar(4096) DEFAULT NULL,
14 | PRIMARY KEY (`appId`)
15 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
16 |
17 |
18 |
19 |
20 | DROP TABLE IF EXISTS `authorities`;
21 | CREATE TABLE `authorities` (
22 | `username` varchar(50) NOT NULL,
23 | `authority` varchar(50) NOT NULL,
24 | UNIQUE KEY `ix_auth_username` (`username`,`authority`)
25 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
26 |
27 |
28 |
29 | DROP TABLE IF EXISTS `oauth_access_token`;
30 | CREATE TABLE `oauth_access_token` (
31 | `token_id` varchar(256) DEFAULT NULL,
32 | `token` blob,
33 | `authentication_id` varchar(256) DEFAULT NULL,
34 | `user_name` varchar(256) DEFAULT NULL,
35 | `client_id` varchar(256) DEFAULT NULL,
36 | `authentication` blob,
37 | `refresh_token` varchar(256) DEFAULT NULL
38 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
39 |
40 |
41 |
42 | DROP TABLE IF EXISTS `oauth_client_details`;
43 | CREATE TABLE `oauth_client_details` (
44 | `client_id` varchar(256) NOT NULL,
45 | `resource_ids` varchar(256) DEFAULT NULL,
46 | `client_secret` varchar(256) DEFAULT NULL,
47 | `scope` varchar(256) DEFAULT NULL,
48 | `authorized_grant_types` varchar(256) DEFAULT NULL,
49 | `web_server_redirect_uri` varchar(256) DEFAULT NULL,
50 | `authorities` varchar(256) DEFAULT NULL,
51 | `access_token_validity` int(11) DEFAULT NULL,
52 | `refresh_token_validity` int(11) DEFAULT NULL,
53 | `additional_information` varchar(4096) DEFAULT NULL,
54 | `autoapprove` varchar(256) DEFAULT NULL,
55 | PRIMARY KEY (`client_id`)
56 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
57 |
58 |
59 |
60 | DROP TABLE IF EXISTS `oauth_code`;
61 | CREATE TABLE `oauth_code` (
62 | `code` varchar(256) DEFAULT NULL,
63 | `authentication` blob
64 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
65 |
66 |
67 | DROP TABLE IF EXISTS `oauth_refresh_token`;
68 | CREATE TABLE `oauth_refresh_token` (
69 | `token_id` varchar(256) DEFAULT NULL,
70 | `token` blob,
71 | `authentication` blob
72 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
73 |
74 | DROP TABLE IF EXISTS `users`;
75 | CREATE TABLE `users` (
76 | `username` varchar(50) NOT NULL,
77 | `password` varchar(50) NOT NULL,
78 | `enabled` tinyint(1) NOT NULL,
79 | PRIMARY KEY (`username`)
80 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
81 |
82 |
--------------------------------------------------------------------------------
/build-all-projects.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd api-gateway; ./gradlew clean build; cd ..
4 | cd auth-server; ./gradlew clean build; cd ..
5 | cd config-server; ./gradlew clean build; cd ..
6 | cd task-webservice; ./gradlew clean build; cd ..
7 | cd user-webservice; ./gradlew clean build; cd ..
8 | cd web-portal; ./gradlew clean build; cd ..
9 | cd webservice-registry; ./gradlew clean build; cd ..
10 | cd comments-webservice; ./gradlew clean build; cd ..
11 |
--------------------------------------------------------------------------------
/comments-webservice/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | .DS_Store
4 | /.gradle/
5 |
--------------------------------------------------------------------------------
/comments-webservice/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | comments-webservice
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.springsource.ide.eclipse.gradle.core.nature
16 | org.eclipse.jdt.core.javanature
17 |
18 |
19 |
20 | 1438821709492
21 |
22 | 22
23 |
24 | org.eclipse.ui.ide.multiFilter
25 | 1.0-name-matches-false-false-.DS_Store
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/comments-webservice/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This application provides the **comments** related functionality and serves as one component. It defines the REST endpoints that are used to provide comment functionality.
4 |
5 | Note that this component is only used internally by the "task" microservice and is NOT actually exposed at the API gateway level.
6 |
7 | ##Pre-requisites
8 |
9 | ### Projects that need to be started before
10 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
11 | * [webserver-registry](/../../blob/master/webservice-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
12 |
13 | ### Running the application
14 | * Build the application by running the `./gradlew clean build` gradle command at the "comments-webservice" project root folder on the terminal.
15 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-comments-webservice-0.0.1.jar` command at the terminal.
16 |
17 | ## External Configuration
18 | Please refer to [user webservice](/../../blob/master/user-webservice/README.md) for details on how the external configuration works. Note that there is separate configuration file for each Spring application; the application should refer to it's own .yml file for configuration.
--------------------------------------------------------------------------------
/comments-webservice/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | seurityVersion = '2.0.7.RELEASE'
6 | }
7 | repositories {
8 | mavenCentral()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
14 | classpath 'se.transmode.gradle:gradle-docker:1.2'
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 |
24 | jar {
25 | baseName = 'sample-comments-webservice'
26 | version = '0.0.1'
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | jcenter()
32 | }
33 | dependencies {
34 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
35 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
36 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
37 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
38 | compile("org.springframework.cloud:spring-cloud-starter-hystrix:${project.cloudVersion}")
39 |
40 | compile("org.springframework.cloud:spring-cloud-starter-security:${project.cloudVersion}")
41 | compile("org.springframework.boot:spring-boot-starter-security:${project.bootVersion}")
42 | compile("org.springframework.security.oauth:spring-security-oauth2:${project.seurityVersion}")
43 |
44 | testCompile group: 'junit', name: 'junit', version: '4.+'
45 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
46 | }
47 |
48 | group = 'anilallewar'
49 | mainClassName = 'com.rohitghatol.microservices.comments.Application'
50 |
51 | sourceCompatibility = 1.7
52 | targetCompatibility = 1.7
53 |
54 | distDocker {
55 | exposePort 8080
56 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
57 | }
58 |
59 | docker {
60 | useApi true
61 | hostUrl 'http://192.168.59.103:2375'
62 | baseImage = 'java:7'
63 | }
64 |
65 | bootRun {
66 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4400,suspend=n','-Dspring.profiles.active=dev']
67 | }
68 |
69 | run {
70 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4400,suspend=n','-Dspring.profiles.active=dev']
71 | }
72 |
73 | task createWrapper(type: Wrapper) {
74 | gradleVersion = '2.0'
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/comments-webservice/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:51:06 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/comments-webservice/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/comments-webservice/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/comments-webservice/src/main/java/com/rohitghatol/microservices/comments/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.comments;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
9 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
10 | import org.springframework.cloud.security.oauth2.resource.EnableOAuth2Resource;
11 | import org.springframework.context.annotation.ComponentScan;
12 |
13 | /**
14 | * The boot application class that defines the spring boot application to have
15 | * the following properties
16 | *
17 | *
18 | *
19 | *
Act as a Eureka client; this behavior is provided by the
20 | * {@link EnableEurekaClient} annotation. The Eureka server URL is provided by
21 | * the external configuration provided by the config server.
22 | *
The security is enabled to be covered by OAuth2 access token using the
23 | * {@link EnableOAuth2Resource} annotation. The URL from where the user would be
24 | * authenticated is provided by the
25 | * spring.oauth2.resource.userInfoUri property defined in the
26 | * external configuration.
27 | *
{@link EnableEurekaClient} makes the app into both a Eureka "instance" (i.e. it
28 | * registers itself) and a "client" (i.e. it can query the registry to locate
29 | * other services).
30 | *
Note that all these annotations work in conjunction with properties
31 | * defined in the external configuration files specified by the config server.
32 | *
33 | *
34 | *
35 | * @author rohitghatol
36 | *
37 | */
38 | @EnableAutoConfiguration
39 | @ComponentScan
40 | @EnableEurekaClient
41 | @EnableOAuth2Resource
42 | public class Application {
43 | public static void main(String[] args) {
44 |
45 | SpringApplication.run(Application.class,args);
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/comments-webservice/src/main/java/com/rohitghatol/microservices/comments/apis/CommentsController.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.comments.apis;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | import org.springframework.web.bind.annotation.PathVariable;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import com.rohitghatol.microservices.comments.dtos.CommentDTO;
15 |
16 | /**
17 | * REST endpoint for the comments functionality
18 | *
19 | *
20 | * Note that this endpoint is supposed to be consumed by the Task webservice and
21 | * is not accessible to the general public; i.e. the api-gateway doesn't handle
22 | * requests for comments-webservice.
23 | *
24 | * @author anilallewar
25 | *
26 | */
27 | @RestController
28 | @RequestMapping("/comments")
29 | public class CommentsController {
30 |
31 | private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
32 |
33 | private List comments = null;
34 |
35 | /**
36 | * Public constructor to initialize the comments and handle the
37 | * ParseException
38 | *
39 | * @throws ParseException
40 | */
41 | public CommentsController() throws ParseException {
42 | this.comments = Arrays.asList(new CommentDTO("task11", "comment on task11", formatter.parse("2015-04-23")),
43 | new CommentDTO("task12", "comment on task12", formatter.parse("2015-05-12")),
44 | new CommentDTO("task11", "new comment on task11", formatter.parse("2015-04-27")),
45 | new CommentDTO("task21", "comment on task21", formatter.parse("2015-01-15")),
46 | new CommentDTO("task22", "comment on task22", formatter.parse("2015-03-05")));
47 | }
48 |
49 | /**
50 | * Get comments for specific taskid that is passed in the path.
51 | *
52 | * @param taskId
53 | * @return
54 | */
55 | @RequestMapping(value = "/{taskId}", method = RequestMethod.GET, headers = "Accept=application/json")
56 | public List getCommentsByTaskId(@PathVariable("taskId") String taskId) {
57 | List commentListToReturn = new ArrayList();
58 | for (CommentDTO currentComment : comments) {
59 | if (currentComment.getTaskId().equalsIgnoreCase(taskId)) {
60 | commentListToReturn.add(currentComment);
61 | }
62 | }
63 |
64 | return commentListToReturn;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/comments-webservice/src/main/java/com/rohitghatol/microservices/comments/config/CommentsConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.comments.config;
5 |
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpMethod;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
10 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
11 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
12 |
13 | /**
14 | * Resource server configuration defining what endpoints are protected.
15 | *
16 | * @author anilallewar
17 | *
18 | */
19 | @Configuration
20 | @EnableResourceServer
21 | public class CommentsConfiguration extends ResourceServerConfigurerAdapter {
22 |
23 | /**
24 | * Provide security so that endpoints are only served if the request is
25 | * already authenticated.
26 | */
27 | @Override
28 | public void configure(HttpSecurity http) throws Exception {
29 | // @formatter:off
30 | http.requestMatchers()
31 | .antMatchers("/**")
32 | .and()
33 | .authorizeRequests()
34 | .anyRequest()
35 | .authenticated()
36 | .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
37 | .antMatchers(HttpMethod.OPTIONS, "/**").access("#oauth2.hasScope('read')")
38 | .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
39 | .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
40 | .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
41 | .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')");
42 | // @formatter:on
43 | }
44 |
45 | /**
46 | * Id of the resource that you are letting the client have access to.
47 | * Supposing you have another api ("say api2"), then you can customize the
48 | * access within resource server to define what api is for what resource id.
49 | *
50 | *
51 | *
52 | * So suppose you have 2 APIs, then you can define 2 resource servers.
53 | *
54 | *
Client 1 has been configured for access to resourceid1, so he can
55 | * only access "api1" if the resource server configures the resourceid to
56 | * "api1".
57 | *
Client 1 can't access resource server 2 since it has configured the
58 | * resource id to "api2"
59 | *
60 | *
61 | *
62 | */
63 | @Override
64 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
65 | resources.resourceId("apis");
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/comments-webservice/src/main/java/com/rohitghatol/microservices/comments/dtos/CommentDTO.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.comments.dtos;
5 |
6 | import java.io.IOException;
7 | import java.util.Date;
8 |
9 | import com.fasterxml.jackson.core.JsonGenerator;
10 | import com.fasterxml.jackson.core.JsonProcessingException;
11 | import com.fasterxml.jackson.databind.JsonSerializer;
12 | import com.fasterxml.jackson.databind.SerializerProvider;
13 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
14 |
15 | /**
16 | * Represents comments on Task.
17 | *
18 | * @author anilallewar
19 | */
20 | public class CommentDTO {
21 |
22 | /** The task id. */
23 | private String taskId;
24 |
25 | /** The last name. */
26 | private String comment;
27 |
28 | /** The completed. */
29 | private Date posted;
30 |
31 | /**
32 | * Instantiates a new task dto.
33 | */
34 | public CommentDTO() {
35 | super();
36 |
37 | }
38 |
39 | /**
40 | * Instantiates a new task dto.
41 | *
42 | * @param taskId
43 | * the task id
44 | * @param description
45 | * the description
46 | */
47 | public CommentDTO(String taskId, String comment, Date posted) {
48 | super();
49 | this.taskId = taskId;
50 | this.comment = comment;
51 | this.posted = posted;
52 | }
53 |
54 | /**
55 | * @return the taskId
56 | */
57 | public String getTaskId() {
58 | return taskId;
59 | }
60 |
61 | /**
62 | * @param taskId
63 | * the taskId to set
64 | */
65 | public void setTaskId(String taskId) {
66 | this.taskId = taskId;
67 | }
68 |
69 | /**
70 | * @return the comment
71 | */
72 | public String getComment() {
73 | return comment;
74 | }
75 |
76 | /**
77 | * @param comment
78 | * the comment to set
79 | */
80 | public void setComment(String comment) {
81 | this.comment = comment;
82 | }
83 |
84 | /**
85 | * @return the posted
86 | */
87 | @JsonSerialize(using = CustomDateToLongSerializer.class)
88 | public Date getPosted() {
89 | return posted;
90 | }
91 |
92 | /**
93 | * @param posted
94 | * the posted to set
95 | */
96 | public void setPosted(Date posted) {
97 | this.posted = posted;
98 | }
99 |
100 | /*
101 | * (non-Javadoc)
102 | *
103 | * @see java.lang.Object#hashCode()
104 | */
105 | @Override
106 | public int hashCode() {
107 | final int prime = 31;
108 | int result = 1;
109 | result = prime * result + ((comment == null) ? 0 : comment.hashCode());
110 | result = prime * result + ((posted == null) ? 0 : posted.hashCode());
111 | result = prime * result + ((taskId == null) ? 0 : taskId.hashCode());
112 | return result;
113 | }
114 |
115 | /*
116 | * (non-Javadoc)
117 | *
118 | * @see java.lang.Object#equals(java.lang.Object)
119 | */
120 | @Override
121 | public boolean equals(Object obj) {
122 | if (this == obj)
123 | return true;
124 | if (obj == null)
125 | return false;
126 | if (getClass() != obj.getClass())
127 | return false;
128 | CommentDTO other = (CommentDTO) obj;
129 | if (comment == null) {
130 | if (other.comment != null)
131 | return false;
132 | } else if (!comment.equals(other.comment))
133 | return false;
134 | if (posted == null) {
135 | if (other.posted != null)
136 | return false;
137 | } else if (!posted.equals(other.posted))
138 | return false;
139 | if (taskId == null) {
140 | if (other.taskId != null)
141 | return false;
142 | } else if (!taskId.equals(other.taskId))
143 | return false;
144 | return true;
145 | }
146 |
147 | /*
148 | * (non-Javadoc)
149 | *
150 | * @see java.lang.Object#toString()
151 | */
152 | @Override
153 | public String toString() {
154 | return "CommentDTO [taskId=" + taskId + ", comment=" + comment + ", posted=" + posted + "]";
155 | }
156 |
157 | }
158 |
159 | /**
160 | * Custom date serializer that converts the date to long before sending it out
161 | *
162 | * @author anilallewar
163 | *
164 | */
165 | class CustomDateToLongSerializer extends JsonSerializer {
166 |
167 | @Override
168 | public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider)
169 | throws IOException, JsonProcessingException {
170 | jgen.writeNumber(value.getTime());
171 | }
172 | }
--------------------------------------------------------------------------------
/comments-webservice/src/main/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/comments-webservice/src/main/resources/application.yml
--------------------------------------------------------------------------------
/comments-webservice/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 |
4 | # Name of the service that is using with Zuul routes to forward specific requests to this service
5 | name: comments-webservice
6 | cloud:
7 | config:
8 |
9 | # Define the URL from where this service would pick up it's external configuration. Note that it is
10 | # pointing to the config-server aplication
11 | uri: http://localhost:8888
12 |
13 | ---
14 |
15 | spring:
16 | profiles: docker
17 | cloud:
18 | config:
19 | uri: http://192.168.59.103:8888
--------------------------------------------------------------------------------
/config-server/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/config-server/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | config-server
4 |
5 |
6 |
7 | org.springsource.ide.eclipse.gradle.core.nature
8 | org.eclipse.jdt.core.javanature
9 |
10 |
11 |
12 | org.eclipse.jdt.core.javabuilder
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/config-server/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This application loads and makes the **external configuration** available to rest of the applications. Note that the external configuration can be hosted either on GitHub or on local file system.
4 |
5 | The respective applications pick up the configuration based on a `.yml` file defined in the configuration by matching the service's `spring.application.name` property defined in the `bootstrap.yml` file.
6 |
7 | ##Pre-requisites
8 |
9 | ### Projects that need to be started before
10 | * This is the first application that needs to run since it pulls the configuration information(like what port to run etc) that is needed by rest of the applications to start.
11 |
12 | ### Running the application
13 | * Build the application by running the `./gradlew clean build` gradle command at the "config-server" project root folder on the terminal.
14 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-config-server-0.0.1.jar` command at the terminal.
15 |
--------------------------------------------------------------------------------
/config-server/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | }
6 | repositories {
7 | mavenCentral()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
13 | classpath 'se.transmode.gradle:gradle-docker:1.2'
14 | }
15 | }
16 |
17 | apply plugin: 'eclipse'
18 | apply plugin: 'spring-boot'
19 | apply plugin: 'java'
20 | apply plugin: 'docker'
21 |
22 |
23 | jar {
24 | baseName = 'sample-config-server'
25 | version = '0.0.1'
26 | }
27 |
28 | repositories {
29 | mavenCentral()
30 | jcenter()
31 | }
32 | dependencies {
33 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
34 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
35 | compile("org.springframework.cloud:spring-cloud-config-server:1.0.0.RELEASE")
36 |
37 | testCompile group: 'junit', name: 'junit', version: '4.+'
38 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
39 | }
40 |
41 | group = 'anilallewar'
42 | mainClassName = 'com.rohitghatol.microservices.config.Application'
43 |
44 | sourceCompatibility = 1.7
45 | targetCompatibility = 1.7
46 |
47 |
48 | distDocker {
49 | exposePort 8888
50 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
51 | }
52 |
53 | docker {
54 | useApi true
55 | hostUrl 'http://192.168.59.103:2375'
56 | baseImage = 'java:7'
57 | }
58 |
59 | task createWrapper(type: Wrapper) {
60 | gradleVersion = '2.0'
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/config-server/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/config-server/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/config-server/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:50:40 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/config-server/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/config-server/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/config-server/src/main/java/com/rohitghatol/microservices/config/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.config;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.config.server.EnableConfigServer;
9 | import org.springframework.context.annotation.ComponentScan;
10 |
11 |
12 | /**
13 | * The Main Spring Boot Application class.
14 | *
15 | *
16 | * The {@link EnableConfigServer} annotation defines that this application will
17 | * serve as the REST based API for providing external configuration.
18 | *
19 | *
20 | * The external repository from where the configuration will be picked up is
21 | * defined in the {@linkplain application.yml} file.
22 | *
23 | * @author rohitghatol
24 | */
25 | @EnableAutoConfiguration
26 | @EnableConfigServer
27 | @ComponentScan
28 | public class Application {
29 |
30 | /**
31 | * The main method.
32 | *
33 | * @param args the arguments
34 | */
35 | public static void main(String[] args) {
36 | SpringApplication.run(Application.class, args);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/config-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | config:
4 | server:
5 | git:
6 | uri: https://github.com/anilallewar/sample-config
7 | # While in development mode, you can configure the config server to pick up configuration files from
8 | # the file system
9 |
10 | # uri: file://Users/anilallewar/Documents/Anil Allewar/Trainings/Code Samples/Enterprise Java/Micro Services/sample-config
11 |
12 | # Defines the port where the config server is running so that rest of the services can pick up
13 | # their external configurations
14 | server:
15 | port: 8888
--------------------------------------------------------------------------------
/config-server/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: configserver
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | configserver:
2 | image: anilallewar/config-server
3 | restart: always
4 |
5 | eurekaregistry:
6 | image: anilallewar/webservice-registry
7 | restart: always
8 | ports:
9 | - "8761:8761"
10 | links:
11 | - configserver
12 |
13 | authserver:
14 | image: anilallewar/auth-server
15 | restart: always
16 | ports:
17 | - "8899:8899"
18 | links:
19 | - configserver
20 |
21 | apigateway:
22 | image: anilallewar/api-gateway
23 | restart: always
24 | links:
25 | - eurekaregistry
26 | - authserver
27 | - configserver
28 |
29 | webportal:
30 | image: anilallewar/web-portal
31 | restart: always
32 | links:
33 | - eurekaregistry
34 | - configserver
35 |
36 | userwebservice:
37 | image: anilallewar/user-webservice
38 | restart: always
39 | links:
40 | - eurekaregistry
41 | - authserver
42 | - configserver
43 |
44 | taskwebservice:
45 | image: anilallewar/task-webservice
46 | restart: always
47 | links:
48 | - eurekaregistry
49 | - authserver
50 | - configserver
51 |
52 | commentswebservice:
53 | image: anilallewar/comments-webservice
54 | restart: always
55 | links:
56 | - eurekaregistry
57 | - authserver
58 | - configserver
--------------------------------------------------------------------------------
/docker-image-all-projects.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd api-gateway; ./gradlew clean build distDocker; cd ..
4 | cd auth-server; ./gradlew clean build distDocker; cd ..
5 | cd config-server; ./gradlew clean build distDocker; cd ..
6 | cd task-webservice; ./gradlew clean build distDocker; cd ..
7 | cd user-webservice; ./gradlew clean build distDocker; cd ..
8 | cd web-portal; ./gradlew clean build distDocker; cd ..
9 | cd webservice-registry; ./gradlew clean build distDocker; cd ..
10 | cd comments-webservice; ./gradlew clean build distDocker; cd ..
--------------------------------------------------------------------------------
/images/Application_Components.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/images/Application_Components.jpg
--------------------------------------------------------------------------------
/images/Decentralized Goverance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/images/Decentralized Goverance.png
--------------------------------------------------------------------------------
/images/OAuth2 abstract protocol flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/images/OAuth2 abstract protocol flow.png
--------------------------------------------------------------------------------
/images/Target_Architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/images/Target_Architecture.jpg
--------------------------------------------------------------------------------
/task-webservice/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/task-webservice/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | task-webservice
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.springsource.ide.eclipse.gradle.core.nature
16 | org.eclipse.jdt.core.javanature
17 |
18 |
19 |
20 | 1438895288093
21 |
22 | 22
23 |
24 | org.eclipse.ui.ide.multiFilter
25 | 1.0-name-matches-false-false-.DS_Store
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/task-webservice/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences
2 | #Mon Apr 06 13:25:59 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | enableDependendencyManagement=true
10 | projects=;
11 |
--------------------------------------------------------------------------------
/task-webservice/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences
2 | #Mon Apr 06 13:26:03 PDT 2015
3 | org.springsource.ide.eclipse.gradle.linkedresources=
4 | org.springsource.ide.eclipse.gradle.rootprojectloc=
5 |
--------------------------------------------------------------------------------
/task-webservice/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs:
--------------------------------------------------------------------------------
1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences
2 | #Mon Apr 06 13:26:02 PDT 2015
3 | addResourceFilters=true
4 | afterTasks=afterEclipseImport;
5 | beforeTasks=cleanEclipse;eclipse;
6 | enableAfterTasks=true
7 | enableBeforeTasks=true
8 | enableDSLD=false
9 | useHierarchicalNames=false
10 |
--------------------------------------------------------------------------------
/task-webservice/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #
2 | #Mon Apr 06 19:41:01 PDT 2015
3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
4 | org.eclipse.jdt.core.compiler.compliance=1.7
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
10 | eclipse.preferences.version=1
11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
12 | org.eclipse.jdt.core.compiler.source=1.7
13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
14 |
--------------------------------------------------------------------------------
/task-webservice/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This application provides the **task** related functionality and serves as one component. It defines the REST endpoints that are used to provide task functionality.
4 |
5 | This micro-service also provides an example of to call another OAuth2 protected service from within this service using OAuth2 client configuration. The OAuth2 bearer token that has been passed to the task service is propogated to the "comments" service to get the comments for the given task.
6 |
7 | ##Pre-requisites
8 |
9 | ### Projects that need to be started before
10 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
11 | * [webserver-registry](/../../blob/master/webservice-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
12 |
13 | ### Running the application
14 | * Build the application by running the `./gradlew clean build` gradle command at the "task-webservice" project root folder on the terminal.
15 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-task-webservice-0.0.1.jar` command at the terminal.
16 |
17 | ## External Configuration
18 | Please refer to [user webservice](/../../blob/master/user-webservice/README.md) for details on how the external configuration works. Note that there is separate configuration file for each Spring application; the application should refer to it's own .yml file for configuration.
--------------------------------------------------------------------------------
/task-webservice/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | seurityVersion = '2.0.7.RELEASE'
6 | }
7 | repositories {
8 | mavenCentral()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
14 | classpath 'se.transmode.gradle:gradle-docker:1.2'
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 |
24 | jar {
25 | baseName = 'sample-task-webservice'
26 | version = '0.0.1'
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | jcenter()
32 | }
33 | dependencies {
34 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
35 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
36 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
37 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
38 | compile("org.springframework.cloud:spring-cloud-starter-hystrix:${project.cloudVersion}")
39 |
40 | compile("org.springframework.cloud:spring-cloud-starter-security:${project.cloudVersion}")
41 | compile("org.springframework.boot:spring-boot-starter-security:${project.bootVersion}")
42 | compile("org.springframework.security.oauth:spring-security-oauth2:${project.seurityVersion}")
43 |
44 | testCompile group: 'junit', name: 'junit', version: '4.+'
45 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
46 | }
47 |
48 | group = 'anilallewar'
49 | mainClassName = 'com.rohitghatol.microservices.task.Application'
50 |
51 | sourceCompatibility = 1.7
52 | targetCompatibility = 1.7
53 |
54 | distDocker {
55 | exposePort 8080
56 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
57 | }
58 |
59 | docker {
60 | useApi true
61 | hostUrl 'http://192.168.59.103:2375'
62 | baseImage = 'java:7'
63 | }
64 |
65 | bootRun {
66 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4300,suspend=n','-Dspring.profiles.active=dev']
67 | }
68 |
69 | run {
70 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4300,suspend=n','-Dspring.profiles.active=dev']
71 | }
72 |
73 | task createWrapper(type: Wrapper) {
74 | gradleVersion = '2.0'
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/task-webservice/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:53:39 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/task-webservice/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/task-webservice/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.task;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
9 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
10 | import org.springframework.cloud.security.oauth2.resource.EnableOAuth2Resource;
11 | import org.springframework.context.annotation.ComponentScan;
12 |
13 | /**
14 | * The boot application class that defines the spring boot application to have
15 | * the following properties
16 | *
17 | *
18 | *
19 | *
Act as a Eureka client; this behavior is provided by the
20 | * {@link EnableEurekaClient} annotation. The Eureka server URL is provided by
21 | * the external configuration provided by the config server.
22 | *
The security is enabled to be covered by OAuth2 access token using the
23 | * {@link EnableOAuth2Resource} annotation. The URL from where the user would be
24 | * authenticated is provided by the
25 | * spring.oauth2.resource.userInfoUri property defined in the
26 | * external configuration.
27 | *
{@link EnableEurekaClient} makes the app into both a Eureka "instance" (i.e. it
28 | * registers itself) and a "client" (i.e. it can query the registry to locate
29 | * other services).
30 | *
{@link EnableCircuitBreaker} allows the application to respond to
31 | + * failures on services it relies. For example consider that you have an
32 | + * "employee" service that uses the "address" service to get addresses. Now if
33 | + * the address service goes down, then we can provide a fallback method using
34 | + * the circuit breaker. Now the address would be sent back using the static
35 | + * value from the method till the "address" service comes back again.
36 | *
Note that all these annotations work in conjunction with properties
37 | * defined in the external configuration files specified by the config server.
38 | *
39 | *
40 | *
41 | * @author rohitghatol
42 | *
43 | */
44 | @EnableAutoConfiguration
45 | @ComponentScan
46 | @EnableEurekaClient
47 | @EnableOAuth2Resource
48 | @EnableCircuitBreaker
49 | public class Application {
50 | public static void main(String[] args) {
51 |
52 | SpringApplication.run(Application.class,args);
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/apis/CommentsService.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.task.apis;
2 |
3 | import java.util.Calendar;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.security.oauth2.client.OAuth2RestOperations;
7 | import org.springframework.stereotype.Component;
8 | import org.springframework.stereotype.Service;
9 |
10 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
11 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
12 | import com.rohitghatol.microservices.task.model.CommentCollectionResource;
13 | import com.rohitghatol.microservices.task.model.CommentResource;
14 |
15 | /**
16 | * The {@link HystrixCommand} works since Spring makes a proxy to intercept the
17 | * request and call the fallback method if the method errs.
18 | *
19 | *
20 | * Hence the {@link HystrixCommand} needs to be in separate {@link Component} or
21 | * {@link Service} stereotypes so that Spring can proxy them.
22 | *
23 | * @author anilallewar
24 | *
25 | */
26 | @Service
27 | public class CommentsService {
28 |
29 | @Autowired
30 | private OAuth2RestOperations restTemplate;
31 |
32 | /**
33 | * Returns the comments for the task; note that this applies a circuit
34 | * breaker that would return the default value if the comments-webservice
35 | * was down.
36 | *
37 | * Discussion on HystrixProperty
38 | *
39 | *
execution.isolation.strategy: The value of "SEMAPHORE" enables
40 | * Hystrix to use the current thread for executing this command. Since we
41 | * need to use the parent HttpRequest to pass the OAuth2 access token, we
42 | * are constrained in using the calling thread. The number of concurrent
43 | * requests that can be made to the command is limited by the semaphore(or
44 | * counter) value; default is 10.In a normal scenario, you would use
45 | * isolation strategy of "THREAD" that executes the Hystrix command in a
46 | * separate thread pool. This is desirable because it doesn't block the
47 | * calling thread and lets us handle faulty client libraries, client
48 | * performance considerations etc.
49 | *
circuitBreaker.requestVolumeThreshold:This property sets the
50 | * minimum number of requests in a rolling window that will trip the
51 | * circuit. For example, if the value is 20, then if only 19 requests are
52 | * received in the rolling window (say a window of 10 seconds) the circuit
53 | * will not trip open even if all 19 failed. We have a lower value in this
54 | * sample application so as to trip early.
55 | *
circuitBreaker.sleepWindowInMilliseconds:This property sets
56 | * the amount of time, after tripping the circuit, to reject requests before
57 | * allowing attempts again to determine if the circuit should again be
58 | * closed. We again have a lower value so that Hystrix tries to pass single
59 | * request to the called service quickly.
60 | *
61 | *
62 | * @param taskId
63 | * @return
64 | */
65 | @HystrixCommand(fallbackMethod = "getFallbackCommentsForTask", commandProperties = {
66 | @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
67 | @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
68 | @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "1000") })
69 | public CommentCollectionResource getCommentsForTask(String taskId) {
70 | // Get the comments for this task
71 | return restTemplate.getForObject(String.format("http://comments-webservice/comments/%s", taskId),
72 | CommentCollectionResource.class);
73 |
74 | }
75 |
76 | /**
77 | * Gets the default comments for task. Need to add the suppress warning
78 | * since the method is not directly used by the class.
79 | *
80 | * @return the default comments for task
81 | */
82 | @SuppressWarnings("unused")
83 | private CommentCollectionResource getFallbackCommentsForTask(String taskId) {
84 | // Get the default comments
85 | CommentCollectionResource comments = new CommentCollectionResource();
86 | comments.addComment(new CommentResource(taskId, "default comment", Calendar.getInstance().getTime()));
87 |
88 | return comments;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/apis/TaskController.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.task.apis;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | import com.rohitghatol.microservices.task.dtos.TaskDTO;
14 |
15 | /**
16 | * REST endpoint for the task functionality
17 | *
18 | * @author anilallewar
19 | *
20 | */
21 | @RestController
22 | @RequestMapping("/")
23 | public class TaskController {
24 |
25 | @Autowired
26 | private CommentsService commentsService;
27 |
28 | private List tasks = Arrays.asList(new TaskDTO("task11", "description11", "1"),
29 | new TaskDTO("task12", "description12", "1"), new TaskDTO("task13", "description13", "1"),
30 | new TaskDTO("task21", "description21", "2"), new TaskDTO("task22", "description22", "2"));
31 |
32 | /**
33 | * Get all tasks
34 | *
35 | * @return
36 | */
37 | @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/json")
38 | public List getTasks() {
39 | return tasks;
40 | }
41 |
42 | /**
43 | * Get tasks for specific taskid
44 | *
45 | * @param taskId
46 | * @return
47 | */
48 | @RequestMapping(value = "{taskId}", method = RequestMethod.GET, headers = "Accept=application/json")
49 | public TaskDTO getTaskByTaskId(@PathVariable("taskId") String taskId) {
50 | TaskDTO taskToReturn = null;
51 | for (TaskDTO currentTask : tasks) {
52 | if (currentTask.getTaskId().equalsIgnoreCase(taskId)) {
53 | taskToReturn = currentTask;
54 | break;
55 | }
56 | }
57 |
58 | if (taskToReturn != null) {
59 | taskToReturn.setComments(this.commentsService.getCommentsForTask(taskId));
60 | }
61 | return taskToReturn;
62 | }
63 |
64 | /**
65 | * Get tasks for specific user that is passed in
66 | *
67 | * @param taskId
68 | * @return
69 | */
70 | @RequestMapping(value = "/usertask/{userName}", method = RequestMethod.GET, headers = "Accept=application/json")
71 | public List getTasksByUserName(@PathVariable("userName") String userName) {
72 | List taskListToReturn = new ArrayList();
73 | for (TaskDTO currentTask : tasks) {
74 | if (currentTask.getUserName().equalsIgnoreCase(userName)) {
75 | taskListToReturn.add(currentTask);
76 | }
77 | }
78 |
79 | return taskListToReturn;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/config/OAuthClientConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.task.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.security.oauth2.client.OAuth2ClientContext;
7 | import org.springframework.security.oauth2.client.OAuth2RestOperations;
8 | import org.springframework.security.oauth2.client.OAuth2RestTemplate;
9 | import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
10 | import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
11 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
12 |
13 | /**
14 | * Configuration that sets up the OAuth2 client operation for making calls to
15 | * the comments-webservice.
16 | *
17 | * @author anilallewar
18 | *
19 | */
20 | @Configuration
21 | @EnableOAuth2Client
22 | public class OAuthClientConfiguration {
23 |
24 | @Value("${spring.oauth2.client.userAuthorizationUri}")
25 | private String authorizeUrl;
26 |
27 | @Value("${spring.oauth2.client.accessTokenUri}")
28 | private String tokenUrl;
29 |
30 | @Value("${spring.oauth2.client.clientId}")
31 | private String clientId;
32 |
33 | /**
34 | * RestTempate that relays the OAuth2 token passed to the task webservice.
35 | *
36 | * @param oauth2ClientContext
37 | * @return
38 | */
39 | @Bean
40 | public OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) {
41 | return new OAuth2RestTemplate(resource(), oauth2ClientContext);
42 | }
43 |
44 | /**
45 | * Setup details where the OAuth2 server is.
46 | * @return
47 | */
48 | @Bean
49 | protected OAuth2ProtectedResourceDetails resource() {
50 | AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
51 | resource.setAccessTokenUri(tokenUrl);
52 | resource.setUserAuthorizationUri(authorizeUrl);
53 | resource.setClientId(clientId);
54 | resource.setClientSecret("secret");
55 | return resource;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/config/TaskConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.task.config;
5 |
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpMethod;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
10 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
11 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
12 |
13 | /**
14 | * Resource server configuration defining what endpoints are protected.
15 | *
16 | * @author anilallewar
17 | *
18 | */
19 | @Configuration
20 | @EnableResourceServer
21 | public class TaskConfiguration extends ResourceServerConfigurerAdapter {
22 |
23 | /**
24 | * Provide security so that endpoints are only served if the request is
25 | * already authenticated.
26 | */
27 | @Override
28 | public void configure(HttpSecurity http) throws Exception {
29 | // @formatter:off
30 | http.requestMatchers()
31 | .antMatchers("/**")
32 | .and()
33 | .authorizeRequests()
34 | .anyRequest()
35 | .authenticated()
36 | .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
37 | .antMatchers(HttpMethod.OPTIONS, "/**").access("#oauth2.hasScope('read')")
38 | .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
39 | .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
40 | .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
41 | .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')");
42 | // @formatter:on
43 | }
44 |
45 | /**
46 | * Id of the resource that you are letting the client have access to.
47 | * Supposing you have another api ("say api2"), then you can customize the
48 | * access within resource server to define what api is for what resource id.
49 | *
50 | *
51 | *
52 | * So suppose you have 2 APIs, then you can define 2 resource servers.
53 | *
54 | *
Client 1 has been configured for access to resourceid1, so he can
55 | * only access "api1" if the resource server configures the resourceid to
56 | * "api1".
57 | *
Client 1 can't access resource server 2 since it has configured the
58 | * resource id to "api2"
59 | *
60 | *
61 | *
62 | */
63 | @Override
64 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
65 | resources.resourceId("apis");
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/dtos/TaskDTO.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.task.dtos;
5 |
6 | import com.rohitghatol.microservices.task.model.CommentCollectionResource;
7 |
8 | /**
9 | * Represents Todo Task.
10 | *
11 | * @author rohitghatol
12 | */
13 | public class TaskDTO {
14 |
15 | /** The task id. */
16 | private String taskId;
17 |
18 | /** The last name. */
19 | private String description;
20 |
21 | /** The completed. */
22 | private boolean completed;
23 |
24 | /** The user name with whom the task is associated. */
25 | private String userName;
26 |
27 | /** The comments. */
28 | private CommentCollectionResource comments;
29 |
30 | /**
31 | * Instantiates a new task dto.
32 | */
33 | public TaskDTO() {
34 | super();
35 |
36 | }
37 |
38 | /**
39 | * Instantiates a new task dto.
40 | *
41 | * @param taskId the task id
42 | * @param description the description
43 | */
44 | public TaskDTO(String taskId, String description, String userName) {
45 | super();
46 | this.taskId = taskId;
47 | this.description = description;
48 | this.completed = false;
49 | this.userName = userName;
50 | }
51 |
52 | /**
53 | * Gets the task id.
54 | *
55 | * @return the task id
56 | */
57 | public String getTaskId() {
58 | return taskId;
59 | }
60 |
61 | /**
62 | * Sets the task id.
63 | *
64 | * @param taskId the new task id
65 | */
66 | public void setTaskId(String taskId) {
67 | this.taskId = taskId;
68 | }
69 |
70 | /**
71 | * Gets the description.
72 | *
73 | * @return the description
74 | */
75 | public String getDescription() {
76 | return description;
77 | }
78 |
79 | /**
80 | * Sets the description.
81 | *
82 | * @param description the new description
83 | */
84 | public void setDescription(String description) {
85 | this.description = description;
86 | }
87 |
88 | /**
89 | * Checks if is completed.
90 | *
91 | * @return true, if is completed
92 | */
93 | public boolean isCompleted() {
94 | return completed;
95 | }
96 |
97 | /**
98 | * Sets the completed.
99 | *
100 | * @param completed the new completed
101 | */
102 | public void setCompleted(boolean completed) {
103 | this.completed = completed;
104 | }
105 |
106 |
107 | /**
108 | * @return the userName
109 | */
110 | public String getUserName() {
111 | return userName;
112 | }
113 |
114 | /**
115 | * @param userName the userName to set
116 | */
117 | public void setUserName(String userName) {
118 | this.userName = userName;
119 | }
120 |
121 | /**
122 | * @return the comments
123 | */
124 | public CommentCollectionResource getComments() {
125 | return comments;
126 | }
127 |
128 | /**
129 | * @param comments the comments to set
130 | */
131 | public void setComments(CommentCollectionResource comments) {
132 | this.comments = comments;
133 | }
134 |
135 | /* (non-Javadoc)
136 | * @see java.lang.Object#hashCode()
137 | */
138 | @Override
139 | public int hashCode() {
140 | final int prime = 31;
141 | int result = 1;
142 | result = prime * result + ((comments == null) ? 0 : comments.hashCode());
143 | result = prime * result + (completed ? 1231 : 1237);
144 | result = prime * result + ((description == null) ? 0 : description.hashCode());
145 | result = prime * result + ((taskId == null) ? 0 : taskId.hashCode());
146 | result = prime * result + ((userName == null) ? 0 : userName.hashCode());
147 | return result;
148 | }
149 |
150 | /* (non-Javadoc)
151 | * @see java.lang.Object#equals(java.lang.Object)
152 | */
153 | @Override
154 | public boolean equals(Object obj) {
155 | if (this == obj)
156 | return true;
157 | if (obj == null)
158 | return false;
159 | if (getClass() != obj.getClass())
160 | return false;
161 | TaskDTO other = (TaskDTO) obj;
162 | if (comments == null) {
163 | if (other.comments != null)
164 | return false;
165 | } else if (!comments.equals(other.comments))
166 | return false;
167 | if (completed != other.completed)
168 | return false;
169 | if (description == null) {
170 | if (other.description != null)
171 | return false;
172 | } else if (!description.equals(other.description))
173 | return false;
174 | if (taskId == null) {
175 | if (other.taskId != null)
176 | return false;
177 | } else if (!taskId.equals(other.taskId))
178 | return false;
179 | if (userName == null) {
180 | if (other.userName != null)
181 | return false;
182 | } else if (!userName.equals(other.userName))
183 | return false;
184 | return true;
185 | }
186 |
187 | /* (non-Javadoc)
188 | * @see java.lang.Object#toString()
189 | */
190 | @Override
191 | public String toString() {
192 | return "TaskDTO [taskId=" + taskId + ", description=" + description + ", completed=" + completed + ", userName="
193 | + userName + ", comments=" + comments + "]";
194 | }
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/model/CommentCollectionResource.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.task.model;
5 |
6 | import java.io.IOException;
7 | import java.util.ArrayList;
8 | import java.util.Date;
9 | import java.util.List;
10 |
11 | import com.fasterxml.jackson.core.JsonParser;
12 | import com.fasterxml.jackson.core.JsonProcessingException;
13 | import com.fasterxml.jackson.databind.DeserializationContext;
14 | import com.fasterxml.jackson.databind.JsonDeserializer;
15 | import com.fasterxml.jackson.databind.JsonNode;
16 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
17 |
18 | /**
19 | * @author anilallewar
20 | *
21 | */
22 | @JsonDeserialize(using = CommentsCollectionDeserializer.class)
23 | public class CommentCollectionResource {
24 | private List taskComments;
25 |
26 | /**
27 | * Adds the comment.
28 | *
29 | * @param comment
30 | * the comment
31 | */
32 | public void addComment(CommentResource comment) {
33 | if (this.taskComments == null) {
34 | this.taskComments = new ArrayList<>();
35 | }
36 | this.taskComments.add(comment);
37 | }
38 |
39 | /**
40 | * @return the taskComments
41 | */
42 | public List getTaskComments() {
43 | return taskComments;
44 | }
45 |
46 | /**
47 | * @param taskComments
48 | * the taskComments to set
49 | */
50 | public void setTaskComments(List taskComments) {
51 | this.taskComments = taskComments;
52 | }
53 |
54 | /*
55 | * (non-Javadoc)
56 | *
57 | * @see java.lang.Object#hashCode()
58 | */
59 | @Override
60 | public int hashCode() {
61 | final int prime = 31;
62 | int result = 1;
63 | result = prime * result + ((taskComments == null) ? 0 : taskComments.hashCode());
64 | return result;
65 | }
66 |
67 | /*
68 | * (non-Javadoc)
69 | *
70 | * @see java.lang.Object#equals(java.lang.Object)
71 | */
72 | @Override
73 | public boolean equals(Object obj) {
74 | if (this == obj)
75 | return true;
76 | if (obj == null)
77 | return false;
78 | if (getClass() != obj.getClass())
79 | return false;
80 | CommentCollectionResource other = (CommentCollectionResource) obj;
81 | if (taskComments == null) {
82 | if (other.taskComments != null)
83 | return false;
84 | } else if (!taskComments.equals(other.taskComments))
85 | return false;
86 | return true;
87 | }
88 |
89 | /*
90 | * (non-Javadoc)
91 | *
92 | * @see java.lang.Object#toString()
93 | */
94 | @Override
95 | public String toString() {
96 | return "CommentCollectionResource [taskComments=" + taskComments + "]";
97 | }
98 | }
99 |
100 | /**
101 | * Inner class to perform the de-serialization of the comments array
102 | *
103 | * @author anilallewar
104 | *
105 | */
106 | class CommentsCollectionDeserializer extends JsonDeserializer {
107 | @Override
108 | public CommentCollectionResource deserialize(JsonParser jp, DeserializationContext ctxt)
109 | throws IOException, JsonProcessingException {
110 | CommentCollectionResource commentArrayResource = new CommentCollectionResource();
111 | CommentResource commentResource = null;
112 |
113 | JsonNode jsonNode = jp.readValueAsTree();
114 |
115 | for (JsonNode childNode : jsonNode) {
116 | if (childNode.has(CommentResource.JP_TASKID)) {
117 | commentResource = new CommentResource();
118 | commentResource.setTaskId(childNode.get(CommentResource.JP_TASKID).asText());
119 | commentResource.setComment(childNode.get(CommentResource.JP_COMMENT).asText());
120 | commentResource.setPosted(new Date(childNode.get(CommentResource.JP_POSTED).asLong()));
121 |
122 | commentArrayResource.addComment(commentResource);
123 | }
124 | }
125 | return commentArrayResource;
126 |
127 | }
128 | }
--------------------------------------------------------------------------------
/task-webservice/src/main/java/com/rohitghatol/microservices/task/model/CommentResource.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.task.model;
2 |
3 | import java.io.IOException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 | import com.fasterxml.jackson.core.JsonGenerator;
9 | import com.fasterxml.jackson.core.JsonProcessingException;
10 | import com.fasterxml.jackson.databind.JsonSerializer;
11 | import com.fasterxml.jackson.databind.SerializerProvider;
12 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
13 |
14 | /**
15 | * Represents comments on Task.
16 | *
17 | * @author anilallewar
18 | */
19 | public class CommentResource {
20 |
21 | public static final String JP_TASKID = "taskId";
22 | public static final String JP_COMMENT = "comment";
23 | public static final String JP_POSTED = "posted";
24 |
25 | /** The task id. */
26 | private String taskId;
27 |
28 | /** The last name. */
29 | private String comment;
30 |
31 | /** The completed. */
32 | private Date posted;
33 |
34 | /**
35 | * Instantiates a new comment resource
36 | */
37 | public CommentResource() {
38 | super();
39 |
40 | }
41 |
42 | /**
43 | * Instantiates a new comment resource
44 | *
45 | * @param taskId
46 | * @param comment
47 | * @param posted
48 | */
49 | public CommentResource(String taskId, String comment, Date posted) {
50 | super();
51 | this.taskId = taskId;
52 | this.comment = comment;
53 | this.posted = posted;
54 | }
55 |
56 | /**
57 | * @return the taskId
58 | */
59 | @JsonProperty(JP_TASKID)
60 | public String getTaskId() {
61 | return taskId;
62 | }
63 |
64 | /**
65 | * @param taskId
66 | * the taskId to set
67 | */
68 | public void setTaskId(String taskId) {
69 | this.taskId = taskId;
70 | }
71 |
72 | /**
73 | * @return the comment
74 | */
75 | @JsonProperty(JP_COMMENT)
76 | public String getComment() {
77 | return comment;
78 | }
79 |
80 | /**
81 | * @param comment
82 | * the comment to set
83 | */
84 | public void setComment(String comment) {
85 | this.comment = comment;
86 | }
87 |
88 | /**
89 | * @return the posted
90 | */
91 | @JsonProperty(JP_POSTED)
92 | @JsonSerialize(using = CustomDateToStringSerializer.class)
93 | public Date getPosted() {
94 | return posted;
95 | }
96 |
97 | /**
98 | * @param posted
99 | * the posted to set
100 | */
101 | public void setPosted(Date posted) {
102 | this.posted = posted;
103 | }
104 |
105 | /*
106 | * (non-Javadoc)
107 | *
108 | * @see java.lang.Object#hashCode()
109 | */
110 | @Override
111 | public int hashCode() {
112 | final int prime = 31;
113 | int result = 1;
114 | result = prime * result + ((comment == null) ? 0 : comment.hashCode());
115 | result = prime * result + ((posted == null) ? 0 : posted.hashCode());
116 | result = prime * result + ((taskId == null) ? 0 : taskId.hashCode());
117 | return result;
118 | }
119 |
120 | /*
121 | * (non-Javadoc)
122 | *
123 | * @see java.lang.Object#equals(java.lang.Object)
124 | */
125 | @Override
126 | public boolean equals(Object obj) {
127 | if (this == obj)
128 | return true;
129 | if (obj == null)
130 | return false;
131 | if (getClass() != obj.getClass())
132 | return false;
133 | CommentResource other = (CommentResource) obj;
134 | if (comment == null) {
135 | if (other.comment != null)
136 | return false;
137 | } else if (!comment.equals(other.comment))
138 | return false;
139 | if (posted == null) {
140 | if (other.posted != null)
141 | return false;
142 | } else if (!posted.equals(other.posted))
143 | return false;
144 | if (taskId == null) {
145 | if (other.taskId != null)
146 | return false;
147 | } else if (!taskId.equals(other.taskId))
148 | return false;
149 | return true;
150 | }
151 |
152 | /*
153 | * (non-Javadoc)
154 | *
155 | * @see java.lang.Object#toString()
156 | */
157 | @Override
158 | public String toString() {
159 | return "CommentResource [taskId=" + taskId + ", comment=" + comment + ", posted=" + posted + "]";
160 | }
161 |
162 | }
163 |
164 | /**
165 | * Custom date serializer that converts the date to String before sending it out
166 | *
167 | * @author anilallewar
168 | *
169 | */
170 | class CustomDateToStringSerializer extends JsonSerializer {
171 |
172 | private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
173 |
174 | @Override
175 | public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider)
176 | throws IOException, JsonProcessingException {
177 | String dateString = dateFormat.format(value);
178 | jgen.writeString(dateString);
179 | }
180 | }
--------------------------------------------------------------------------------
/task-webservice/src/main/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/task-webservice/src/main/resources/application.yml
--------------------------------------------------------------------------------
/task-webservice/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 |
4 | # Name of the service that is using with Zuul routes to forward specific requests to this service
5 | name: task-webservice
6 | cloud:
7 | config:
8 |
9 | # Define the URL from where this service would pick up it's external configuration. Note that it is
10 | # pointing to the config-server aplication
11 | uri: http://localhost:8888
12 |
13 | ---
14 |
15 | spring:
16 | profiles: docker
17 | cloud:
18 | config:
19 | uri: http://192.168.59.103:8888
--------------------------------------------------------------------------------
/understanding_notes.pages:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/understanding_notes.pages
--------------------------------------------------------------------------------
/user-webservice/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/user-webservice/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | user-webservice
4 |
5 |
6 |
7 | org.springsource.ide.eclipse.gradle.core.nature
8 | org.eclipse.jdt.core.javanature
9 |
10 |
11 |
12 | org.eclipse.jdt.core.javabuilder
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/user-webservice/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This application provides the **user** related functionality and serves as one component. It defines the REST endpoints that are used to provide user functionality.
4 |
5 | ##Pre-requisites
6 |
7 | ### Projects that need to be started before
8 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
9 | * [webservice-registry](/../../blob/master/webservice-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
10 |
11 | ### Running the application
12 | * Build the application by running the `./gradlew clean build` gradle command at the "user-webservice" project root folder on the terminal.
13 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-user-webservice-0.0.1.jar` command at the terminal.
14 |
15 | ## External Configuration
16 | The project derives it's external configuration from the [config server](/../../blob/master/config-server/README.md) service. Note that we have defined the `spring.cloud.config.uri` in the `bootstrap.yml` file and that tells the application where to pick up the external confiurations. In our case, the URL points to the running [config server](/../../blob/master/config-server/README.md) server. You also need to have the `spring-cloud-config-client` dependency in the classpath so that the application can comsume the config server.
17 |
18 | A Spring Cloud application operates by creating a "bootstrap" context, which is a parent context for the main application. This bootstrap context loads properties from external sources (the config-server) and decrypts the properties if required.
19 |
20 | The bootstrap context for external configuration is located by convention at `bootstrap.yml` whereas the internal configuration is located by convention at `application.yml`. Note that you can also have `.properties` file instead of `.yml` files.
--------------------------------------------------------------------------------
/user-webservice/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | seurityVersion = '2.0.7.RELEASE'
6 | }
7 | repositories {
8 | mavenCentral()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
14 | classpath 'se.transmode.gradle:gradle-docker:1.2'
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 | jar {
24 | baseName = 'sample-user-webservice'
25 | version = '0.0.1'
26 | }
27 |
28 | repositories {
29 | mavenCentral()
30 | jcenter()
31 | }
32 | dependencies {
33 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
34 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
35 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
36 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
37 |
38 | compile("org.springframework.cloud:spring-cloud-starter-security:${project.cloudVersion}")
39 | compile("org.springframework.boot:spring-boot-starter-security:${project.bootVersion}")
40 | compile("org.springframework.security.oauth:spring-security-oauth2:${project.seurityVersion}")
41 |
42 | testCompile group: 'junit', name: 'junit', version: '4.+'
43 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
44 | }
45 |
46 | group = 'anilallewar'
47 | mainClassName = 'com.rohitghatol.microservices.user.Application'
48 |
49 | sourceCompatibility = 1.7
50 | targetCompatibility = 1.7
51 |
52 | distDocker {
53 | exposePort 8080
54 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
55 | }
56 |
57 | docker {
58 | useApi true
59 | hostUrl 'http://192.168.59.103:2375'
60 | baseImage = 'java:7'
61 | }
62 |
63 | bootRun {
64 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4200,suspend=n','-Dspring.profiles.active=dev']
65 | }
66 |
67 | run {
68 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4200,suspend=n','-Dspring.profiles.active=dev']
69 | }
70 |
71 | task createWrapper(type: Wrapper) {
72 | gradleVersion = '2.0'
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/user-webservice/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/user-webservice/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/user-webservice/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:52:58 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/user-webservice/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/user-webservice/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/user-webservice/src/main/java/com/rohitghatol/microservices/user/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.user;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
9 | import org.springframework.cloud.security.oauth2.resource.EnableOAuth2Resource;
10 | import org.springframework.context.annotation.ComponentScan;
11 |
12 | /**
13 | * The boot application class that defines the spring boot application to have
14 | * the following properties
15 | *
16 | *
17 | *
18 | *
Act as a Eureka client; this behavior is provided by the
19 | * {@link EnableEurekaClient} annotation. The Eureka server URL is provided by
20 | * the external configuration provided by the config server.
21 | *
The security is enabled to be covered by OAuth2 access token using the
22 | * {@link EnableOAuth2Resource} annotation. The URL from where the user would be
23 | * authenticated is provided by the
24 | * spring.oauth2.resource.userInfoUri property defined in the
25 | * external configuration.
26 | *
@EnableEurekaClient makes the app into both a Eureka "instance" (i.e. it
27 | * registers itself) and a "client" (i.e. it can query the registry to locate
28 | * other services).
29 | *
Note that all these annotations work in conjunction with properties
30 | * defined in the external configuration files specified by the config server.
31 | *
32 | *
33 | *
34 | * @author rohitghatol
35 | *
36 | */
37 | @EnableAutoConfiguration
38 | @ComponentScan
39 | @EnableEurekaClient
40 | @EnableOAuth2Resource
41 | public class Application {
42 | public static void main(String[] args) {
43 |
44 | SpringApplication.run(Application.class,args);
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/user-webservice/src/main/java/com/rohitghatol/microservices/user/apis/UserController.java:
--------------------------------------------------------------------------------
1 | package com.rohitghatol.microservices.user.apis;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RequestMethod;
10 | import org.springframework.web.bind.annotation.RestController;
11 |
12 | import com.rohitghatol.microservices.user.dto.UserDTO;
13 |
14 | /**
15 | * REST endpoint for the user functionality
16 | *
17 | * @author anilallewar
18 | *
19 | */
20 | @RestController
21 | @RequestMapping("/")
22 | public class UserController {
23 |
24 | @Value("${mail.domain}")
25 | private String mailDomain;
26 |
27 | private List users = Arrays.asList(new UserDTO("Anil", "Allewar", "1", "anil.allewar@" + mailDomain),
28 | new UserDTO("Rohit", "Ghatol", "2", "rohit.ghatol@" + mailDomain),
29 | new UserDTO("John", "Snow", "3", "john.snow@" + mailDomain));
30 |
31 | /**
32 | * Return all users
33 | *
34 | * @return
35 | */
36 | @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/json")
37 | public List getUsers() {
38 | return users;
39 | }
40 |
41 | /**
42 | * Return user associated with specific user name
43 | *
44 | * @param userName
45 | * @return
46 | */
47 | @RequestMapping(value = "{userName}", method = RequestMethod.GET, headers = "Accept=application/json")
48 | public UserDTO getUserByUserName(@PathVariable("userName") String userName) {
49 | UserDTO userDtoToReturn = null;
50 | for (UserDTO currentUser : users) {
51 | if (currentUser.getUserName().equalsIgnoreCase(userName)) {
52 | userDtoToReturn = currentUser;
53 | break;
54 | }
55 | }
56 |
57 | return userDtoToReturn;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/user-webservice/src/main/java/com/rohitghatol/microservices/user/config/UserConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.user.config;
5 |
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpMethod;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
10 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
11 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
12 |
13 | /**
14 | * Resource server configuration defining what endpoints are protected.
15 | *
16 | * @author anilallewar
17 | *
18 | */
19 | @Configuration
20 | @EnableResourceServer
21 | public class UserConfiguration extends ResourceServerConfigurerAdapter {
22 |
23 | /**
24 | * Provide security so that endpoints are only served if the request is
25 | * already authenticated.
26 | */
27 | @Override
28 | public void configure(HttpSecurity http) throws Exception {
29 | // @formatter:off
30 | http.requestMatchers()
31 | .antMatchers("/**")
32 | .and()
33 | .authorizeRequests()
34 | .anyRequest()
35 | .authenticated()
36 | .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
37 | .antMatchers(HttpMethod.OPTIONS, "/**").access("#oauth2.hasScope('read')")
38 | .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
39 | .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
40 | .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
41 | .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')");
42 | // @formatter:on
43 | }
44 |
45 | /**
46 | * Id of the resource that you are letting the client have access to.
47 | * Supposing you have another api ("say api2"), then you can customize the
48 | * access within resource server to define what api is for what resource id.
49 | *
50 | *
51 | *
52 | * So suppose you have 2 APIs, then you can define 2 resource servers.
53 | *
54 | *
Client 1 has been configured for access to resourceid1, so he can
55 | * only access "api1" if the resource server configures the resourceid to
56 | * "api1".
57 | *
Client 1 can't access resource server 2 since it has configured the
58 | * resource id to "api2"
59 | *
60 | *
61 | *
62 | */
63 | @Override
64 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
65 | resources.resourceId("apis");
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/user-webservice/src/main/java/com/rohitghatol/microservices/user/dto/UserDTO.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.user.dto;
5 |
6 |
7 | /**
8 | * Represents User identified by username
9 | *
10 | * @author rohitghatol
11 | */
12 | public class UserDTO {
13 |
14 | /** The first name. */
15 | private String firstName;
16 |
17 | /** The last name. */
18 | private String lastName;
19 |
20 | /** The user name. */
21 | private String userName;
22 |
23 | /** The email address. */
24 | private String emailAddress;
25 |
26 | /**
27 | * Instantiates a new user dto.
28 | */
29 | public UserDTO() {
30 | super();
31 | // TODO Auto-generated constructor stub
32 | }
33 |
34 | /**
35 | * Instantiates a new user dto.
36 | *
37 | * @param firstName the first name
38 | * @param lastName the last name
39 | * @param userName the user name
40 | * @param emailAddress the email address
41 | */
42 | public UserDTO(String firstName, String lastName, String userName,
43 | String emailAddress) {
44 | super();
45 | this.firstName = firstName;
46 | this.lastName = lastName;
47 | this.userName = userName;
48 | this.emailAddress = emailAddress;
49 | }
50 |
51 | /**
52 | * Gets the first name.
53 | *
54 | * @return the first name
55 | */
56 | public String getFirstName() {
57 | return firstName;
58 | }
59 |
60 | /**
61 | * Sets the first name.
62 | *
63 | * @param firstName the new first name
64 | */
65 | public void setFirstName(String firstName) {
66 | this.firstName = firstName;
67 | }
68 |
69 | /**
70 | * Gets the last name.
71 | *
72 | * @return the last name
73 | */
74 | public String getLastName() {
75 | return lastName;
76 | }
77 |
78 | /**
79 | * Sets the last name.
80 | *
81 | * @param lastName the new last name
82 | */
83 | public void setLastName(String lastName) {
84 | this.lastName = lastName;
85 | }
86 |
87 | /**
88 | * Gets the user name.
89 | *
90 | * @return the user name
91 | */
92 | public String getUserName() {
93 | return userName;
94 | }
95 |
96 | /**
97 | * Sets the user name.
98 | *
99 | * @param userName the new user name
100 | */
101 | public void setUserName(String userName) {
102 | this.userName = userName;
103 | }
104 |
105 | /**
106 | * Gets the email address.
107 | *
108 | * @return the email address
109 | */
110 | public String getEmailAddress() {
111 | return emailAddress;
112 | }
113 |
114 | /**
115 | * Sets the email address.
116 | *
117 | * @param emailAddress the new email address
118 | */
119 | public void setEmailAddress(String emailAddress) {
120 | this.emailAddress = emailAddress;
121 | }
122 |
123 | /* (non-Javadoc)
124 | * @see java.lang.Object#hashCode()
125 | */
126 | @Override
127 | public int hashCode() {
128 | final int prime = 31;
129 | int result = 1;
130 | result = prime * result
131 | + ((emailAddress == null) ? 0 : emailAddress.hashCode());
132 | result = prime * result
133 | + ((firstName == null) ? 0 : firstName.hashCode());
134 | result = prime * result
135 | + ((lastName == null) ? 0 : lastName.hashCode());
136 | result = prime * result
137 | + ((userName == null) ? 0 : userName.hashCode());
138 | return result;
139 | }
140 |
141 | /* (non-Javadoc)
142 | * @see java.lang.Object#equals(java.lang.Object)
143 | */
144 | @Override
145 | public boolean equals(Object obj) {
146 | if (this == obj)
147 | return true;
148 | if (obj == null)
149 | return false;
150 | if (getClass() != obj.getClass())
151 | return false;
152 | UserDTO other = (UserDTO) obj;
153 | if (emailAddress == null) {
154 | if (other.emailAddress != null)
155 | return false;
156 | } else if (!emailAddress.equals(other.emailAddress))
157 | return false;
158 | if (firstName == null) {
159 | if (other.firstName != null)
160 | return false;
161 | } else if (!firstName.equals(other.firstName))
162 | return false;
163 | if (lastName == null) {
164 | if (other.lastName != null)
165 | return false;
166 | } else if (!lastName.equals(other.lastName))
167 | return false;
168 | if (userName == null) {
169 | if (other.userName != null)
170 | return false;
171 | } else if (!userName.equals(other.userName))
172 | return false;
173 | return true;
174 | }
175 |
176 | /* (non-Javadoc)
177 | * @see java.lang.Object#toString()
178 | */
179 | @Override
180 | public String toString() {
181 | return "UserDTO [firstName=" + firstName + ", lastName=" + lastName
182 | + ", userName=" + userName + ", emailAddress=" + emailAddress
183 | + "]";
184 | }
185 |
186 |
187 | }
188 |
--------------------------------------------------------------------------------
/user-webservice/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | org:
4 | springframework:
5 | security: DEBUG
--------------------------------------------------------------------------------
/user-webservice/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 |
4 | # Name of the service that is using with Zuul routes to forward specific requests to this service
5 | name: user-webservice
6 | cloud:
7 | config:
8 |
9 | # Define the URL from where this service would pick up it's external configuration. Note that it is
10 | # pointing to the config-server aplication
11 | uri: http://localhost:8888
12 |
13 | ---
14 |
15 | spring:
16 | profiles: docker
17 | cloud:
18 | config:
19 | uri: http://192.168.59.103:8888
--------------------------------------------------------------------------------
/web-portal/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/web-portal/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/web-portal/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | web-portal
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.springsource.ide.eclipse.gradle.core.nature
16 | org.eclipse.jdt.core.javanature
17 |
18 |
19 |
--------------------------------------------------------------------------------
/web-portal/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This is a Single Page Application(SPA) that has the user facing UI beinng used in the application. It uses the following technologies
4 | * Angular - (base, routes)
5 | * Bootstrap for CSS and layout
6 | * Gradle for build - we could have used grunt/gulp instead
7 |
8 | It is perfectly acceptable to have the SPA not start using the Spring boot application. You would only need to change the Zuul route to forward the request to the actual SPA hosted URL.
9 |
10 | ##Pre-requisites
11 |
12 | ### Projects that need to be started before
13 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
14 | * [webserver-registry](/../../blob/master/webservice-registry/README.md) - For starting the Eureka server since the authorization server also is a micro-service that needs to be registered with Eureka server.
15 |
16 | ### Running the application
17 | * Build the application by running the `./gradlew clean build` gradle command at the "web-portal" project root folder on the terminal.
18 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-web-portal-0.0.1.jar` command at the terminal.
19 |
20 | ## External Configuration
21 | Please refer to [user webservice](/../../blob/master/user-webservice/README.md) for details on how the external configuration works. Note that there is separate configuration file for each Spring application; the application should refer to it's own .yml file for configuration.
22 |
--------------------------------------------------------------------------------
/web-portal/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | }
6 | repositories {
7 | mavenCentral()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
13 | classpath 'se.transmode.gradle:gradle-docker:1.2'
14 | }
15 | }
16 |
17 | apply plugin: 'eclipse'
18 | apply plugin: 'spring-boot'
19 | apply plugin: 'java'
20 | apply plugin: 'docker'
21 |
22 | mainClassName = 'com.rohitghatol.microservices.portal.Application'
23 |
24 | jar {
25 | baseName = 'sample-web-portal'
26 | version = '0.0.1'
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | jcenter()
32 | }
33 | dependencies {
34 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
35 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
36 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
37 | compile("org.springframework.cloud:spring-cloud-starter-eureka:${project.cloudVersion}")
38 |
39 | testCompile group: 'junit', name: 'junit', version: '4.+'
40 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
41 | }
42 |
43 | group = 'anilallewar'
44 | mainClassName = 'com.rohitghatol.microservices.portal.Application'
45 |
46 | sourceCompatibility = 1.7
47 | targetCompatibility = 1.7
48 |
49 | bootRun {
50 | jvmArgs = ['-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=4010,suspend=n','-Dspring.profiles.active=dev']
51 | }
52 |
53 | distDocker {
54 | exposePort 8080
55 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
56 | }
57 |
58 | docker {
59 | useApi true
60 | hostUrl 'http://192.168.59.103:2375'
61 | baseImage = 'java:7'
62 | }
63 |
64 | task createWrapper(type: Wrapper) {
65 | gradleVersion = '2.0'
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/web-portal/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:54:04 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/web-portal/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/web-portal/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/web-portal/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | OAuth Demo with bootstrap
6 |
7 |
17 |
18 |
19 |
20 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/web-portal/public/js/app/controller/homeController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('oauthApp')
4 | .controller('homeCtrl', function () {});
5 |
--------------------------------------------------------------------------------
/web-portal/public/js/app/controller/navController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('oauthApp')
4 | .controller('navigationCtrl', ['$rootScope', '$scope', '$http', '$location', 'dataService', function ($rootScope, $scope, $http, $location, dataService) {
5 |
6 | var assignAuthenticationStatus = function (data) {
7 | if (data.name) {
8 | $rootScope.userAuthenticated = true;
9 | $rootScope.loggedInUserName = data.name;
10 | } else {
11 | $rootScope.userAuthenticated = false;
12 | }
13 | };
14 |
15 | var handleError = function (error) {
16 | console.log(error);
17 | $rootScope.userAuthenticated = false;
18 | };
19 |
20 | dataService.getLoggedInUser().then(assignAuthenticationStatus, handleError);
21 |
22 | $scope.logout = function () {
23 | $http.post('logout', {}).success(function () {
24 | $rootScope.userAuthenticated = false;
25 | $location.path("/");
26 | }).error(function (data) {
27 | $rootScope.userAuthenticated = false;
28 | });
29 | }
30 | }]);
31 |
--------------------------------------------------------------------------------
/web-portal/public/js/app/controller/taskController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @ngdoc function
5 | * @name oauthApp.controller:UserCtrl
6 | * @description
7 | * # PreviewPlaceHolderCtrl
8 | * Controller of the alertApp
9 | */
10 | angular.module('oauthApp')
11 | .controller('taskCtrl', function ($scope, $location, $http, dataService) {
12 |
13 | // Assigns data from the task service into "token"
14 | // variables in controller scope.
15 | var assignAllTaskDataToScope = function (data) {
16 | $scope.taskDataArray = data;
17 | };
18 |
19 | var logError = function (error) {
20 | console.log(error);
21 | };
22 |
23 | // Assign data for a single user
24 | var assignTaskDataToScope = function (data) {
25 | $scope.taskData = data;
26 | };
27 |
28 | var assignUserTaskDataToScope = function (data) {
29 | $scope.taskDataForUser = data;
30 | };
31 |
32 | // Method exposed to get specific task data
33 | this.getTaskDataByTaskId = function (taskId) {
34 | dataService.getTaskDataByTaskId(taskId)
35 | .then(assignTaskDataToScope, logError);
36 | };
37 |
38 | // Method exposed to get specific task data
39 | this.getTaskDataByUserName = function (userName) {
40 | dataService.getTaskDataByUserName(userName)
41 | .then(assignUserTaskDataToScope, logError);
42 | };
43 |
44 | //When the script loads, get all the user's data
45 | dataService.getAllTaskData()
46 | .then(assignAllTaskDataToScope, logError);
47 | });
48 |
--------------------------------------------------------------------------------
/web-portal/public/js/app/controller/userController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @ngdoc function
5 | * @name oauthApp.controller:UserCtrl
6 | * @description
7 | * # PreviewPlaceHolderCtrl
8 | * Controller of the alertApp
9 | */
10 | angular.module('oauthApp')
11 | .controller('userCtrl', function ($scope, $location, $http, dataService) {
12 |
13 | // Assigns data from the user service into "token"
14 | // variables in controller scope.
15 | var assignAllUserDataToScope = function (data) {
16 | $scope.userDataArray = data;
17 | };
18 |
19 | var logError = function (error) {
20 | console.log(error);
21 | };
22 |
23 | // Assign data for a single user
24 | var assignUserDataToScope = function (data) {
25 | $scope.userData = data;
26 | };
27 |
28 | // Method exposed to get specific user data
29 | this.getUserDataByUserName = function (userName) {
30 | dataService.getUserDataByUserName(userName)
31 | .then(assignUserDataToScope, logError);
32 | };
33 |
34 | //When the script loads, get all the user's data
35 | dataService.getAllUserData()
36 | .then(assignAllUserDataToScope, logError);
37 | });
--------------------------------------------------------------------------------
/web-portal/public/js/app/oauthapp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('oauthApp', ['ngRoute'])
4 | .config(function ($routeProvider, $httpProvider) {
5 | $routeProvider.when('/', {
6 | templateUrl: 'views/home.html',
7 | controller: 'homeCtrl'
8 | }).when('/user', {
9 | templateUrl: 'views/user.html',
10 | controller: 'userCtrl',
11 | controllerAs: 'userController'
12 | }).when('/task', {
13 | templateUrl: 'views/task.html',
14 | controller: 'taskCtrl',
15 | controllerAs: 'taskController'
16 | }).otherwise('/');
17 |
18 | //Custom header is needed starting angular 1.3; else Spring security might pop authentication dialog
19 | // by sending the WWW-Authenticate header field in the 401 Unauhorized HTTP response
20 | $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
21 | })
22 | .directive("taskComments", function () {
23 | return {
24 | restrict: 'E',
25 | scope: {
26 | taskComments: '=comments'
27 | },
28 | templateUrl: "views/task-comments.html"
29 | };
30 | })
31 | .directive("taskDetails", function () {
32 | return {
33 | restrict: 'E',
34 | templateUrl: "views/task-details.html"
35 | };
36 | });
37 |
--------------------------------------------------------------------------------
/web-portal/public/js/app/services/dataservice.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @ngdoc service
5 | * @name alertApp.dataService
6 | * @description
7 | * # dataService
8 | * Factory in the alertApp.
9 | */
10 | angular.module('oauthApp')
11 | .factory('dataService', function ($http, $q) {
12 | // We always use this angular service within the preview context
13 | var userApi = '/api/user';
14 |
15 | var taskApi = '/api/task';
16 |
17 | var loggedInUserApi = '/api/loggedinuser/me';
18 |
19 | // This method makes the REST call and the response is parsed by
20 | // Angular.js by default to convert to JSON. If the response is
21 | // successfully parsed then the JSON is available as an 'object'
22 | var makeRestCall = function (url) {
23 | return $http.get(url)
24 | .then(function (response) {
25 |
26 | if (typeof response.data === 'object') {
27 | return response.data;
28 | } else {
29 | // invalid response
30 | return $q.reject(response.data);
31 | }
32 |
33 | }, function (response) {
34 | // something went wrong
35 | return $q.reject(response.data);
36 | });
37 | };
38 |
39 | return {
40 | getAllUserData: function () {
41 | // Make call to the api to get all users
42 | return makeRestCall(userApi);
43 | },
44 |
45 | getAllTaskData: function () {
46 | // Make call to the api to get all tasks
47 | return makeRestCall(taskApi);
48 | },
49 |
50 | getUserDataByUserName: function (userName) {
51 | // Make call to the api to get user details by user name
52 | return makeRestCall(userApi + '/' + userName);
53 | },
54 |
55 | getTaskDataByTaskId: function (taskId) {
56 | // Make call to theapi to get task details by task id
57 | return makeRestCall(taskApi + '/' + taskId);
58 | },
59 |
60 | getTaskDataByUserName: function (userName) {
61 | return makeRestCall(taskApi + '/' + 'usertask' + '/' + userName);
62 | },
63 |
64 | getLoggedInUser: function () {
65 | // Make call to get the current logged in user
66 | return makeRestCall(loggedInUserApi);
67 | }
68 | };
69 | });
--------------------------------------------------------------------------------
/web-portal/public/js/libs/angular-route.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.16
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(n,e,A){'use strict';function x(s,g,k){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);h&&(h.$destroy(),h=null);l&&(k.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){k.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});h=d.scope=b;h.$emit("$viewContentLoaded");h.$eval(u)}else y()}
7 | var h,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,k){return{restrict:"ECA",priority:-400,link:function(a,c){var b=k.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){},
8 | {prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},k=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;k.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var k={};this.when=function(a,c){k[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b=
9 | "/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";k[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,h){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart",
10 | d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=h.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl=
11 | b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(k,function(f,k){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var h=1,p=g.length;h
--------------------------------------------------------------------------------
/web-portal/src/main/java/com/rohitghatol/microservices/portal/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.portal;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
9 | import org.springframework.context.annotation.ComponentScan;
10 | import org.springframework.context.annotation.Configuration;
11 |
12 | /**
13 | * The boot application class that defines the spring boot application to have
14 | * the following properties
15 | *
16 | *
17 | *
18 | *
Act as a Eureka client; this behavior is provided by the
19 | * {@link EnableEurekaClient} annotation. The Eureka server URL is provided by
20 | * the external configuration provided by the config server.
21 | *
No security is defined for this application since it's the client facing
22 | * UI application.
23 | *
All the UI artifacts are stored under the "public" folder at
24 | * the root.
25 | *
26 | *
27 | * @author rohitghatol
28 | *
29 | */
30 | @EnableAutoConfiguration
31 | @ComponentScan
32 | @Configuration
33 | @EnableEurekaClient
34 | public class Application {
35 | public static void main(String[] args) {
36 |
37 | SpringApplication.run(Application.class,args);
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/web-portal/src/main/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/web-portal/src/main/resources/application.yml
--------------------------------------------------------------------------------
/web-portal/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: web-portal
4 | cloud:
5 | config:
6 | uri: http://localhost:8888
7 |
8 | ---
9 |
10 | spring:
11 | profiles: docker
12 | cloud:
13 | config:
14 | uri: http://192.168.59.103:8888
--------------------------------------------------------------------------------
/webservice-registry/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /bin/
3 | /.gradle/
4 |
--------------------------------------------------------------------------------
/webservice-registry/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | webservice-registry
4 |
5 |
6 |
7 | org.springsource.ide.eclipse.gradle.core.nature
8 | org.eclipse.jdt.core.javanature
9 |
10 |
11 |
12 | org.eclipse.jdt.core.javabuilder
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/webservice-registry/README.md:
--------------------------------------------------------------------------------
1 | #Overview
2 |
3 | This application provides the **Eureka Server** that provides service discivery and enables all Eureka clients to discover each other.
4 |
5 | When a client registers with Eureka, it provides meta-data about itself such as host and port, health indicator URL, home page etc. Eureka receives heartbeat messages from each instance belonging to a service. If the heartbeat fails over a configurable timetable, the instance is normally removed from the registry.
6 |
7 | ##Pre-requisites
8 |
9 | ### Projects that need to be started before
10 | * [config server](/../../blob/master/config-server/README.md) - For pulling the configuration information
11 |
12 | ### Running the application
13 | * Build the application by running the `./gradlew clean build` gradle command at the "webservice-registry" project root folder on the terminal.
14 | * If you want to run the application as jar file, then run `java -jar build/libs/sample-webservice-registry-0.0.1.jar` command at the terminal.
15 |
16 | ## External Configuration
17 | Please refer to [user webservice](/../../blob/master/user-webservice/README.md) for details on how the external configuration works. Note that there is separate configuration file for each Spring application; the application should refer to it's own .yml file for configuration.
--------------------------------------------------------------------------------
/webservice-registry/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | project.ext {
3 | bootVersion = '1.2.3.RELEASE'
4 | cloudVersion = '1.0.0.RELEASE'
5 | }
6 | repositories {
7 | mavenCentral()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
13 | classpath 'se.transmode.gradle:gradle-docker:1.2'
14 | classpath "io.spring.gradle:dependency-management-plugin:1.0.2.RELEASE"
15 | }
16 | }
17 |
18 | apply plugin: 'eclipse'
19 | apply plugin: 'spring-boot'
20 | apply plugin: 'java'
21 | apply plugin: 'docker'
22 |
23 | apply plugin: "io.spring.dependency-management"
24 |
25 | dependencyManagement {
26 | imports {
27 | mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:1.0.0.RELEASE'
28 | }
29 | }
30 |
31 | springBoot {
32 | requiresUnpack = ['com.netflix.eureka:eureka-core','com.netflix.eureka:eureka-client']
33 | }
34 |
35 | jar {
36 | baseName = 'sample-webservice-registry'
37 | version = '0.0.1'
38 | }
39 |
40 | repositories {
41 | mavenCentral()
42 | jcenter()
43 | }
44 | dependencies {
45 | compile("org.springframework.boot:spring-boot-starter-web:${project.bootVersion}")
46 | compile("org.springframework.boot:spring-boot-starter-actuator:${project.bootVersion}")
47 | compile("org.springframework.cloud:spring-cloud-config-client:${project.cloudVersion}")
48 | compile("org.springframework.cloud:spring-cloud-starter-eureka-server:${project.cloudVersion}")
49 |
50 | testCompile group: 'junit', name: 'junit', version: '4.+'
51 | testCompile 'org.springframework:spring-test:4.0.6.RELEASE'
52 | }
53 |
54 | group = 'anilallewar'
55 | mainClassName = 'com.rohitghatol.microservices.registry.Application'
56 |
57 | sourceCompatibility = 1.7
58 | targetCompatibility = 1.7
59 |
60 | distDocker {
61 | exposePort 8761
62 | setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
63 | }
64 |
65 | docker {
66 | useApi true
67 | hostUrl 'http://192.168.59.103:2375'
68 | baseImage = 'java:7'
69 | }
70 |
71 | task createWrapper(type: Wrapper) {
72 | gradleVersion = '2.0'
73 | }
74 |
--------------------------------------------------------------------------------
/webservice-registry/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 26 20:52:02 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
7 |
--------------------------------------------------------------------------------
/webservice-registry/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/webservice-registry/src/main/java/com/rohitghatol/microservices/registry/Application.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.rohitghatol.microservices.registry;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
9 | import org.springframework.context.annotation.ComponentScan;
10 | import org.springframework.context.annotation.Configuration;
11 |
12 | /**
13 | * The Main Spring Boot Application class that starts the Eureka discovery
14 | * server since the application is annotated with {@link EnableEurekaServer}.
15 | *
16 | *
17 | *
18 | * Note that all these annotations work in conjunction with properties defined
19 | * in the external configuration files specified by the config server.
20 | *
21 | * @author rohitghatol
22 | */
23 |
24 | @EnableEurekaServer
25 | @Configuration
26 | @ComponentScan
27 | @EnableAutoConfiguration
28 | public class Application {
29 |
30 | /**
31 | * The main method.
32 | *
33 | * @param args the arguments
34 | */
35 | public static void main(String[] args) {
36 | SpringApplication.run(Application.class, args);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/webservice-registry/src/main/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rohitghatol/spring-boot-microservices/a3c9df9350a07578df281949e6018d01ac37238e/webservice-registry/src/main/resources/application.yml
--------------------------------------------------------------------------------
/webservice-registry/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: webservice-registry
4 | cloud:
5 | config:
6 | uri: http://localhost:8888
7 |
8 | ---
9 |
10 | spring:
11 | profiles: docker
12 | cloud:
13 | config:
14 | uri: http://192.168.59.103:8888
15 |
--------------------------------------------------------------------------------