├── README.md ├── authentication-service ├── .gitattributes ├── .gitignore ├── README.md ├── build.gradle ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── auth │ │ │ ├── config │ │ │ ├── AuthorizationServerConfiguration.java │ │ │ ├── OAuth2SecurityConfiguration.java │ │ │ ├── OauthTokenEnhancer.java │ │ │ └── ResourceServerConfiguration.java │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── entity │ │ │ ├── Roles.java │ │ │ └── Users.java │ │ │ ├── exception │ │ │ ├── BaseException.java │ │ │ ├── NotFoundException.java │ │ │ └── handler │ │ │ │ └── GlobalExceptionHandler.java │ │ │ ├── model │ │ │ └── ErrorMessage.java │ │ │ ├── repository │ │ │ ├── BaseRepository.java │ │ │ ├── RolesRepository.java │ │ │ └── UsersRepository.java │ │ │ ├── server │ │ │ └── AuthenticationServer.java │ │ │ └── service │ │ │ ├── UserAuthenticationService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ ├── UserAuthenticationServiceImpl.java │ │ │ └── UserServiceImpl.java │ └── resources │ │ ├── application.properties │ │ ├── data.sql │ │ ├── logback-spring.xml │ │ └── schema.sql │ └── test │ ├── java │ └── com │ │ └── auth │ │ ├── controller │ │ └── UserControllerTest.java │ │ └── service │ │ └── UserServiceTest.java │ └── resources │ ├── application.properties │ ├── data.sql │ └── schema.sql ├── order-service ├── .gitattributes ├── .gitignore ├── build.gradle ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── order │ │ │ ├── controller │ │ │ └── OrderController.java │ │ │ ├── entity │ │ │ └── Orders.java │ │ │ ├── repository │ │ │ └── OrderRepository.java │ │ │ ├── service │ │ │ ├── OrderService.java │ │ │ └── impl │ │ │ │ └── OrderServiceImpl.java │ │ │ └── starter │ │ │ └── OrderServiceStarter.java │ └── resources │ │ ├── application.properties │ │ └── logback-spring.xml │ └── test │ ├── java │ └── com │ │ └── order │ │ ├── controller │ │ └── OrderControllerTest.java │ │ └── service │ │ └── OrderServiceTest.java │ └── resources │ └── application.properties ├── routing-server ├── .gitattributes ├── .gitignore ├── README.md ├── build.gradle ├── settings.gradle └── src │ └── main │ ├── java │ └── com │ │ └── gateway │ │ ├── config │ │ └── GatewaySecurityConfiguration.java │ │ ├── filter │ │ ├── CORSFilter.java │ │ └── GatewayFilter.java │ │ └── server │ │ └── GatewayServer.java │ └── resources │ ├── application.properties │ └── logback-spring.xml └── service-registrar ├── .gitattributes ├── .gitignore ├── README.md ├── build.gradle ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── service │ │ └── registrar │ │ └── ServiceRegistrationServer.java └── resources │ ├── application.properties │ └── logback-spring.xml └── test └── java └── com └── service └── registrar └── ServiceRegistrarTest.java /README.md: -------------------------------------------------------------------------------- 1 | # Microservice with spring boot, eureka, zuul and oauth 2 | 3 | This project demonstrate microservice architecture using spring boot, srping cloud, netfilx eureka, netflix zuul, and oauth. 4 | 5 | ## microservices_architecture 6 | Contains four component all of them are independently deployable applications. 7 | 8 | ### service-registrar 9 | This service maintain the registry of all the microservices that has been deployed. I have used netflix eureka in this project. To register service to `service-registrar` we need to specify property like below. 10 | 11 | ``` 12 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 13 | ``` 14 | 15 | ### routing-server or api gateway 16 | The client can make request to each of the microservices directily, to do that client needs to know all the endpoint addresses but there are challenges with this option. 17 | Things would have been easy for a client if we had a single entry point which routes the request to the appropriate backend service. 18 | To provide single entry point I have used netflix zuul, we need to configure zuul to route the request by specifying routes using properties under `zuul.routes.NAME` where NAME is the application name as per `spring.application.name` property. Below is the routing configuration for order-service. 19 | 20 | ``` 21 | zuul.routes.order-service.path=/order-api/** 22 | ``` 23 | ### authentication-service 24 | To access any resource authentication is required. Instead of using the resource owner's credentials to access protected 25 | resources, the client obtains an access token. 26 | 27 | #### Generate access token 28 | To generate access token basic authorization header with `client id` and `secret` encoded in `Base64` should be passed as authorization header. 29 | 30 | Name | Value | 31 | ------------- | ------------------------- 32 | Client Id | trusted-app 33 | Secret | password 34 | 35 | _request_ 36 | ``` 37 | POST /auth-api/oauth/token HTTP/1.1 38 | Accept: application/json;charset=UTF-8 39 | Authorization: Basic dHJ1c3RlZC1hcHA6cGFzc3dvcmQ= 40 | Host: localhost:8765 41 | Content-Type: application/x-www-form-urlencoded 42 | 43 | grant_type=password&username=demo&password=password 44 | ``` 45 | _response_ 46 | ``` 47 | { 48 | "access_token": "02db66a1-6bd0-4240-bed4-556ec3fdfc6c", 49 | "token_type": "bearer", 50 | "refresh_token": "06b8a0c8-5ef5-4b77-87ef-c7256bab7c17", 51 | "expires_in": 44512, 52 | "scope": "read write trust", 53 | "name": "Demo" 54 | } 55 | ```` 56 | 57 | - Resources can be access using access token either by passing access_token in url __?access_token=__ or by passing as authrization header __Authorization: Bearer __. This document will use Authorization header to access resources. 58 | 59 | #### order-service 60 | To access api of `order-service` the user needs to be authenticated via `authentication-service`. 61 | 62 | _request_ 63 | ``` 64 | GET /orders HTTP/1.1 65 | Accept: application/json;charset=UTF-8 66 | Authorization: Bearer 02db66a1-6bd0-4240-bed4-556ec3fdfc6c 67 | Host: localhost:8765 68 | Content-Type: application/json 69 | ``` 70 | -------------------------------------------------------------------------------- /authentication-service/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf 2 | *.java text eol=lf 3 | *.properties text eol=lf 4 | *.xml text eol=lf 5 | *.jsp text eol=lf 6 | *.html text eol=lf 7 | *.css text eol=lf 8 | *.js text eol=lf 9 | *.ftl text eol=lf 10 | -------------------------------------------------------------------------------- /authentication-service/.gitignore: -------------------------------------------------------------------------------- 1 | # Java class files 2 | *.class 3 | 4 | 5 | 6 | 7 | # Eclipse project files 8 | .classpath 9 | .project 10 | .settings/ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | #Gradle 19 | .gradletasknamecache 20 | .gradle/ 21 | build/ 22 | bin/ 23 | gradle/ 24 | gradlew 25 | gradlew.bat 26 | 27 | #log 28 | log 29 | /.gradle/ 30 | /build/ 31 | -------------------------------------------------------------------------------- /authentication-service/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansaritariq/microservices_architecture/dc72e9b92465228a3ec2d2a264081c0dd104a873/authentication-service/README.md -------------------------------------------------------------------------------- /authentication-service/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | apply plugin: 'java' 3 | apply plugin: 'org.springframework.boot' 4 | apply plugin: 'eclipse' 5 | 6 | buildscript { 7 | ext { 8 | springBootVersion = '1.5.3.RELEASE' 9 | } 10 | repositories { 11 | mavenCentral() 12 | } 13 | dependencies { 14 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 15 | } 16 | } 17 | 18 | sourceCompatibility = 1.8 19 | targetCompatibility = 1.8 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencyManagement { 25 | imports { 26 | mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1' 27 | } 28 | } 29 | 30 | dependencies { 31 | compile ('org.springframework.cloud:spring-cloud-starter-eureka') 32 | compile ('org.springframework.boot:spring-boot-starter-security') 33 | compile ('org.springframework.cloud:spring-cloud-starter-oauth2') 34 | compile ('org.springframework.boot:spring-boot-starter-data-jpa') 35 | compile ('org.springframework.boot:spring-boot-starter-web') 36 | compile("com.h2database:h2") 37 | testCompile('org.springframework.boot:spring-boot-starter-test') 38 | } 39 | jar { 40 | manifest { 41 | attributes "Main-Class": "com.auth.server.AuthenticationServer" 42 | } 43 | 44 | from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }){ 45 | exclude 'META-INF/MANIFEST.MF' 46 | exclude 'META-INF/*.SF' 47 | exclude 'META-INF/*.DSA' 48 | exclude 'META-INF/*.RSA' 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /authentication-service/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was auto generated by the Gradle buildInit task 3 | * by 'tariq.anwar' at '16/11/16 12:19 PM' with Gradle 2.14 4 | * 5 | * The settings file is used to specify which projects to include in your build. 6 | * In a single project build this file can be empty or even removed. 7 | * 8 | * Detailed information about configuring a multi-project build in Gradle can be found 9 | * in the user guide at https://docs.gradle.org/2.14/userguide/multi_project_builds.html 10 | */ 11 | 12 | /* 13 | // To declare projects as part of a multi-project build use the 'include' method 14 | include 'shared' 15 | include 'api' 16 | include 'services:webservice' 17 | */ 18 | 19 | rootProject.name = 'authentication-service' 20 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/config/AuthorizationServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.auth.config; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Primary; 12 | import org.springframework.security.authentication.AuthenticationManager; 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.token.AuthorizationServerTokenServices; 21 | import org.springframework.security.oauth2.provider.token.DefaultTokenServices; 22 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; 23 | import org.springframework.security.oauth2.provider.token.TokenStore; 24 | 25 | import com.auth.service.UserAuthenticationService; 26 | 27 | 28 | @Configuration 29 | @EnableAuthorizationServer 30 | public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 31 | 32 | private static String REALM = "MICRO_SERVICE_OAUTH"; 33 | 34 | @Autowired 35 | private TokenStore tokenStore; 36 | 37 | @Autowired 38 | private AuthorizationCodeServices authorizationCodeServices; 39 | 40 | 41 | @Autowired 42 | private UserAuthenticationService userAuthenticationServiceImpl; 43 | 44 | @Autowired 45 | @Qualifier("authenticationManagerBean") 46 | private AuthenticationManager authenticationManager; 47 | 48 | @Autowired 49 | private DataSource dataSource; 50 | 51 | @Autowired 52 | private BCryptPasswordEncoder passwordEncoder; 53 | 54 | @Autowired 55 | private TokenEnhancer tokenEnhancer; 56 | 57 | final static Logger logger = LoggerFactory.getLogger(AuthorizationServerConfiguration.class); 58 | 59 | 60 | @Override 61 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 62 | clients.jdbc(dataSource).passwordEncoder(passwordEncoder); 63 | 64 | } 65 | 66 | @Override 67 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 68 | 69 | endpoints.tokenStore(tokenStore).authorizationCodeServices(authorizationCodeServices) 70 | .userDetailsService(userAuthenticationServiceImpl) 71 | .authenticationManager(authenticationManager).tokenEnhancer(tokenEnhancer) 72 | .approvalStoreDisabled(); 73 | } 74 | 75 | @Override 76 | public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { 77 | security.realm(REALM + "/client").passwordEncoder(passwordEncoder); 78 | } 79 | 80 | @Bean 81 | @Primary 82 | public AuthorizationServerTokenServices tokenServices() { 83 | DefaultTokenServices tokenServices = new DefaultTokenServices(); 84 | tokenServices.setTokenStore(tokenStore); 85 | tokenServices.setSupportRefreshToken(true); 86 | tokenServices.setTokenEnhancer(tokenEnhancer); 87 | return tokenServices; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/config/OAuth2SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | 2 | package com.auth.config; 3 | 4 | import javax.sql.DataSource; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.security.authentication.AuthenticationManager; 10 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 13 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 15 | import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; 16 | import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; 17 | import org.springframework.security.oauth2.provider.token.TokenStore; 18 | import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; 19 | 20 | import com.auth.service.UserAuthenticationService; 21 | 22 | 23 | @Configuration 24 | @EnableWebSecurity 25 | public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter { 26 | 27 | @Autowired 28 | private UserAuthenticationService userAuthenticationServiceImpl; 29 | 30 | @Autowired 31 | private DataSource dataSource; 32 | 33 | @Override 34 | protected void configure(HttpSecurity http) throws Exception { 35 | http.csrf().disable().anonymous().disable().authorizeRequests().antMatchers("/oauth/token/**") 36 | .permitAll(); 37 | } 38 | 39 | @Override 40 | @Bean 41 | public AuthenticationManager authenticationManagerBean() throws Exception { 42 | return super.authenticationManagerBean(); 43 | } 44 | 45 | @Bean 46 | public TokenStore tokenStore() { 47 | return new JdbcTokenStore(dataSource); 48 | } 49 | 50 | @Bean 51 | public AuthorizationCodeServices authorizationCodeServices() { 52 | return new JdbcAuthorizationCodeServices(dataSource); 53 | } 54 | 55 | @Bean 56 | public DaoAuthenticationProvider authenticationProvider() { 57 | DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 58 | authenticationProvider.setUserDetailsService(userAuthenticationServiceImpl); 59 | authenticationProvider.setPasswordEncoder(passwordEncoder()); 60 | return authenticationProvider; 61 | } 62 | 63 | @Bean 64 | public BCryptPasswordEncoder passwordEncoder() { 65 | return new BCryptPasswordEncoder(8); 66 | } 67 | public static void main(String[] args) { 68 | System.out.println(new BCryptPasswordEncoder(8).encode("password")); 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/config/OauthTokenEnhancer.java: -------------------------------------------------------------------------------- 1 | package com.auth.config; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; 8 | import org.springframework.security.oauth2.common.OAuth2AccessToken; 9 | import org.springframework.security.oauth2.provider.OAuth2Authentication; 10 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; 11 | import org.springframework.stereotype.Component; 12 | 13 | import com.auth.entity.Users; 14 | import com.auth.service.UserService; 15 | 16 | @Component 17 | public class OauthTokenEnhancer implements TokenEnhancer { 18 | 19 | @Autowired 20 | private UserService userService; 21 | 22 | @Override 23 | public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, 24 | OAuth2Authentication authentication) { 25 | String userName = authentication.getName(); 26 | Users user = userService.findByUsername(userName); 27 | final Map additionalInfo = new HashMap<>(); 28 | additionalInfo.put("name", user.getFirstName()); 29 | ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); 30 | return accessToken; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/config/ResourceServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.auth.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 7 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 8 | 9 | @Configuration 10 | @EnableResourceServer 11 | public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{ 12 | private static final String RESOURCE_ID = "auth-server"; 13 | 14 | @Override 15 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 16 | resources.resourceId(RESOURCE_ID).stateless(false); 17 | } 18 | @Override 19 | public void configure(HttpSecurity http) throws Exception { 20 | http.anonymous().disable().authorizeRequests().anyRequest().authenticated(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.auth.controller; 2 | 3 | import java.security.Principal; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.auth.entity.Users; 12 | import com.auth.service.UserService; 13 | 14 | @RestController 15 | @RequestMapping(value = "/users") 16 | public class UserController { 17 | 18 | @Autowired 19 | private UserService userService; 20 | 21 | @GetMapping("/authenticate") 22 | public ResponseEntity user(Principal user) { 23 | return ResponseEntity.ok(user); 24 | } 25 | 26 | @GetMapping 27 | public ResponseEntity getUserByUsername(Principal principal){ 28 | Users user = userService.findByUsername(principal.getName()); 29 | return ResponseEntity.ok(user); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/entity/Roles.java: -------------------------------------------------------------------------------- 1 | package com.auth.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Set; 5 | 6 | import javax.persistence.CascadeType; 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.Id; 10 | import javax.persistence.ManyToMany; 11 | import javax.persistence.Table; 12 | import javax.persistence.UniqueConstraint; 13 | 14 | import com.fasterxml.jackson.annotation.JsonIgnore; 15 | 16 | @Entity 17 | @Table(name = "roles", 18 | uniqueConstraints = @UniqueConstraint(columnNames = {"role_id", "role_name"})) 19 | public class Roles implements Serializable { 20 | 21 | private static final long serialVersionUID = -3090658385114905175L; 22 | 23 | @Id 24 | @Column(name = "role_id", nullable = false, unique = true, columnDefinition = "smallint unsigned") 25 | private Integer roleId; 26 | 27 | @Column(name = "role_name", nullable = false, unique = true) 28 | private String roleName; 29 | 30 | @JsonIgnore 31 | @ManyToMany(cascade = {CascadeType.MERGE}, mappedBy = "roles") 32 | private Set users; 33 | 34 | public Integer getRoleId() { 35 | return roleId; 36 | } 37 | 38 | public void setRoleId(Integer roleId) { 39 | this.roleId = roleId; 40 | } 41 | 42 | public String getRoleName() { 43 | return roleName; 44 | } 45 | 46 | public void setRoleName(String roleName) { 47 | this.roleName = roleName; 48 | } 49 | 50 | public Set getUsers() { 51 | return users; 52 | } 53 | 54 | public void setUsers(Set users) { 55 | this.users = users; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/entity/Users.java: -------------------------------------------------------------------------------- 1 | package com.auth.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Set; 5 | 6 | import javax.persistence.CascadeType; 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.FetchType; 10 | import javax.persistence.Id; 11 | import javax.persistence.JoinColumn; 12 | import javax.persistence.JoinTable; 13 | import javax.persistence.ManyToMany; 14 | import javax.persistence.Table; 15 | 16 | import com.fasterxml.jackson.annotation.JsonIgnore; 17 | 18 | @Entity 19 | @Table(name = "users") 20 | public class Users implements Serializable { 21 | 22 | private static final long serialVersionUID = -3788391832239645648L; 23 | 24 | @Id 25 | @Column(name = "user_id", nullable = false, unique = true, columnDefinition = "int unsigned") 26 | private Integer userId; 27 | 28 | @Column(name = "user_name", nullable = false, unique = true, length = 45) 29 | private String userName; 30 | 31 | @JsonIgnore 32 | @Column(name = "password", nullable = false) 33 | private String password; 34 | 35 | @Column(name = "first_name", length = 45) 36 | private String firstName; 37 | 38 | @Column(name = "last_name", length = 45) 39 | private String lastName; 40 | 41 | @Column(name = "email", length = 45, unique =true) 42 | private String email; 43 | 44 | @Column(name = "mobile", length = 15, unique=true) 45 | private String mobile; 46 | 47 | @JsonIgnore 48 | @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 49 | @JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), 50 | inverseJoinColumns = @JoinColumn(name = "role_id")) 51 | private Set roles; 52 | 53 | public Integer getUserId() { 54 | return userId; 55 | } 56 | 57 | public void setUserId(Integer userId) { 58 | this.userId = userId; 59 | } 60 | 61 | public String getUserName() { 62 | return userName; 63 | } 64 | 65 | public void setUserName(String userName) { 66 | this.userName = userName; 67 | } 68 | 69 | public String getPassword() { 70 | return password; 71 | } 72 | 73 | public void setPassword(String password) { 74 | this.password = password; 75 | } 76 | 77 | public String getFirstName() { 78 | return firstName; 79 | } 80 | 81 | public void setFirstName(String firstName) { 82 | this.firstName = firstName; 83 | } 84 | 85 | public String getLastName() { 86 | return lastName; 87 | } 88 | 89 | public void setLastName(String lastName) { 90 | this.lastName = lastName; 91 | } 92 | 93 | public String getEmail() { 94 | return email; 95 | } 96 | 97 | public void setEmail(String email) { 98 | this.email = email; 99 | } 100 | 101 | public String getMobile() { 102 | return mobile; 103 | } 104 | 105 | public void setMobile(String mobile) { 106 | this.mobile = mobile; 107 | } 108 | 109 | public Set getRoles() { 110 | return roles; 111 | } 112 | 113 | public void setRoles(Set roles) { 114 | this.roles = roles; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/exception/BaseException.java: -------------------------------------------------------------------------------- 1 | package com.auth.exception; 2 | 3 | public class BaseException extends RuntimeException{ 4 | 5 | private static final long serialVersionUID = 2827308907740826575L; 6 | 7 | private String code; 8 | 9 | public BaseException(String message) { 10 | super(message); 11 | } 12 | public BaseException(String message, String code) { 13 | super(message); 14 | this.code = code; 15 | } 16 | public String getCode() { 17 | return code; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.auth.exception; 2 | 3 | public class NotFoundException extends BaseException { 4 | 5 | private static final long serialVersionUID = 7156525748893002528L; 6 | 7 | public NotFoundException(String message) { 8 | super(message); 9 | } 10 | 11 | public NotFoundException(String message, String code) { 12 | super(message, code); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/exception/handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.auth.exception.handler; 2 | 3 | import java.io.IOException; 4 | import java.sql.SQLException; 5 | 6 | import javax.persistence.EntityNotFoundException; 7 | import javax.validation.ConstraintViolationException; 8 | 9 | import org.hibernate.HibernateException; 10 | import org.hibernate.exception.DataException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.dao.DataIntegrityViolationException; 14 | import org.springframework.dao.EmptyResultDataAccessException; 15 | import org.springframework.http.HttpStatus; 16 | import org.springframework.http.converter.HttpMessageNotReadableException; 17 | import org.springframework.http.converter.HttpMessageNotWritableException; 18 | import org.springframework.orm.jpa.JpaSystemException; 19 | import org.springframework.web.HttpRequestMethodNotSupportedException; 20 | import org.springframework.web.bind.ServletRequestBindingException; 21 | import org.springframework.web.bind.annotation.ExceptionHandler; 22 | import org.springframework.web.bind.annotation.ResponseStatus; 23 | import org.springframework.web.bind.annotation.RestControllerAdvice; 24 | import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; 25 | import org.springframework.web.servlet.NoHandlerFoundException; 26 | 27 | import com.auth.exception.NotFoundException; 28 | import com.auth.model.ErrorMessage; 29 | import com.fasterxml.jackson.core.JsonParseException; 30 | import com.fasterxml.jackson.databind.JsonMappingException; 31 | 32 | 33 | @RestControllerAdvice 34 | public class GlobalExceptionHandler { 35 | 36 | private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); 37 | 38 | public static String getMessage(Exception e) { 39 | logger.error("Exception", e); 40 | return e.getCause() == null ? e.getMessage() : e.getCause().getMessage(); 41 | } 42 | 43 | @ResponseStatus(HttpStatus.NOT_FOUND) 44 | @ExceptionHandler(value = {NoHandlerFoundException.class, NotFoundException.class}) 45 | public ErrorMessage resourceNotFoundExceptionHandler(Exception e) { 46 | return new ErrorMessage(getMessage(e), "404"); 47 | } 48 | 49 | @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) 50 | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) 51 | public ErrorMessage methodNotSupportedException(Exception e) { 52 | return new ErrorMessage("Method Not Supported :" + getMessage(e), "405"); 53 | } 54 | 55 | @ResponseStatus(HttpStatus.BAD_REQUEST) 56 | @ExceptionHandler(value = {HttpMessageNotReadableException.class, 57 | MethodArgumentTypeMismatchException.class, ServletRequestBindingException.class}) 58 | public ErrorMessage badRequestExceptionHandler(Exception e) { 59 | return new ErrorMessage(getMessage(e), "400"); 60 | } 61 | 62 | @ResponseStatus(HttpStatus.CONFLICT) 63 | @ExceptionHandler( 64 | value = {DataIntegrityViolationException.class, ConstraintViolationException.class}) 65 | public ErrorMessage dataIntegrityExceptionHandler(Exception e) { 66 | return new ErrorMessage("Constraint voilation : " + getMessage(e), "409"); 67 | } 68 | 69 | @ResponseStatus(HttpStatus.BAD_REQUEST) 70 | @ExceptionHandler(value = {EmptyResultDataAccessException.class, EntityNotFoundException.class, 71 | HttpMessageNotWritableException.class}) 72 | public ErrorMessage emptyResultDataAccessExceptionHandler(Exception e) { 73 | return new ErrorMessage("Entity doesnot exist : " + getMessage(e), "400"); 74 | } 75 | 76 | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 77 | @ExceptionHandler(value = {DataException.class, SQLException.class, HibernateException.class, 78 | JpaSystemException.class, JsonMappingException.class, JsonParseException.class, 79 | IOException.class}) 80 | public ErrorMessage systemException(Exception e) { 81 | return new ErrorMessage("System error : " + getMessage(e), "500"); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/model/ErrorMessage.java: -------------------------------------------------------------------------------- 1 | package com.auth.model; 2 | 3 | import java.io.Serializable; 4 | 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | 7 | public class ErrorMessage implements Serializable{ 8 | 9 | private static final long serialVersionUID = -1325725054820828328L; 10 | 11 | @JsonProperty(value = "error") 12 | private String error; 13 | @JsonProperty(value = "error_description") 14 | private String errorDescription; 15 | 16 | public ErrorMessage(String error, String errorDescription) { 17 | this.error = error; 18 | this.errorDescription = errorDescription; 19 | } 20 | 21 | public String getError() { 22 | return error; 23 | } 24 | 25 | public void setError(String error) { 26 | this.error = error; 27 | } 28 | 29 | public String getErrorDescription() { 30 | return errorDescription; 31 | } 32 | 33 | public void setErrorDescription(String errorDescription) { 34 | this.errorDescription = errorDescription; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/repository/BaseRepository.java: -------------------------------------------------------------------------------- 1 | package com.auth.repository; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.repository.NoRepositoryBean; 7 | 8 | @NoRepositoryBean 9 | public interface BaseRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/repository/RolesRepository.java: -------------------------------------------------------------------------------- 1 | package com.auth.repository; 2 | 3 | import com.auth.entity.Roles; 4 | 5 | public interface RolesRepository extends BaseRepository{ 6 | 7 | } 8 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/repository/UsersRepository.java: -------------------------------------------------------------------------------- 1 | package com.auth.repository; 2 | 3 | import com.auth.entity.Users; 4 | 5 | public interface UsersRepository extends BaseRepository{ 6 | Users findByUserName(String username); 7 | } 8 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/server/AuthenticationServer.java: -------------------------------------------------------------------------------- 1 | package com.auth.server; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 9 | 10 | @SpringBootApplication 11 | @EnableDiscoveryClient 12 | @ComponentScan("com.auth") 13 | @EnableJpaRepositories(basePackages ={"com.auth.repository"}) 14 | @EntityScan(basePackages={"com.auth.entity"}) 15 | public class AuthenticationServer { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(AuthenticationServer.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/service/UserAuthenticationService.java: -------------------------------------------------------------------------------- 1 | package com.auth.service; 2 | 3 | import org.springframework.security.core.userdetails.UserDetailsService; 4 | 5 | public interface UserAuthenticationService extends UserDetailsService { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.auth.service; 2 | 3 | import com.auth.entity.Users; 4 | 5 | public interface UserService { 6 | Users findByUsername(String username); 7 | Users findByUserId(Integer userId); 8 | } 9 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/service/impl/UserAuthenticationServiceImpl.java: -------------------------------------------------------------------------------- 1 | 2 | package com.auth.service.impl; 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.security.core.GrantedAuthority; 12 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 13 | import org.springframework.security.core.userdetails.User; 14 | import org.springframework.security.core.userdetails.UserDetails; 15 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.transaction.annotation.Transactional; 18 | 19 | import com.auth.entity.Roles; 20 | import com.auth.entity.Users; 21 | import com.auth.service.UserAuthenticationService; 22 | import com.auth.service.UserService; 23 | 24 | @Service 25 | @Transactional 26 | public class UserAuthenticationServiceImpl implements UserAuthenticationService { 27 | 28 | private static Logger logger = LoggerFactory.getLogger(UserAuthenticationServiceImpl.class); 29 | 30 | @Autowired 31 | private UserService userService; 32 | 33 | @Override 34 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 35 | Users user = userService.findByUsername(username); 36 | if (user == null) { 37 | throw new UsernameNotFoundException("User not found"); 38 | } 39 | String password = user.getPassword(); 40 | Set roles = user.getRoles(); 41 | List userGrants = new ArrayList<>(); 42 | for(Roles role : roles){ 43 | GrantedAuthority userGrant = new SimpleGrantedAuthority(role.getRoleName()); 44 | userGrants.add(userGrant); 45 | } 46 | logger.info("user roles : {}", roles); 47 | return new User(username, password, userGrants); 48 | } 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /authentication-service/src/main/java/com/auth/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.auth.service.impl; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import com.auth.entity.Users; 7 | import com.auth.exception.NotFoundException; 8 | import com.auth.repository.UsersRepository; 9 | import com.auth.service.UserService; 10 | 11 | @Service 12 | public class UserServiceImpl implements UserService{ 13 | 14 | @Autowired 15 | private UsersRepository userRepository; 16 | 17 | @Override 18 | public Users findByUsername(String username) { 19 | Users user = userRepository.findByUserName(username); 20 | if(user == null){ 21 | throw new NotFoundException("User not found : "+username); 22 | } 23 | return user; 24 | } 25 | 26 | @Override 27 | public Users findByUserId(Integer userId) { 28 | Users user = userRepository.findOne(userId); 29 | if(user == null){ 30 | throw new NotFoundException("User not found : "+userId); 31 | } 32 | return user; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /authentication-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8787 2 | server.context-path=/auth-api 3 | spring.application.name=auth-server 4 | 5 | ################ DB Connection ################# 6 | spring.datasource.url=jdbc:h2:mem:auth_service 7 | spring.datasource.username= 8 | spring.datasource.password= 9 | spring.datasource.dataSourceClassName=org.h2.jdbcx.JdbcDataSource 10 | spring.datasource.schema=classpath:/schema.sql 11 | spring.datasource.data=classpath:/data.sql 12 | 13 | # JPA properties 14 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 15 | spring.jpa.database=H2 16 | spring.jpa.openInView=false 17 | spring.jpa.show_sql=true 18 | spring.jpa.generate-ddl=false 19 | spring.jpa.hibernate.ddl-auto=none 20 | 21 | # Discovery Server Access 22 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 23 | eureka.instance.preferIpAddress=true 24 | 25 | security.basic.enabled=false 26 | 27 | #To maintain oauth filter ordering 28 | security.oauth2.resource.filter-order=3 29 | -------------------------------------------------------------------------------- /authentication-service/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO oauth_client_details(client_id, client_secret, scope, authorized_grant_types, authorities, access_token_validity, refresh_token_validity) 2 | VALUES ('trusted-app', '$2a$08$V0jF.bqEvkO9EhpSEfXi5OZ2JAygrAyz/8X3BLCKHgc2pPyBi4Spy', 'read,write,trust', 'client_credentials,authorization_code,implicit,password,refresh_token','ROLE_CLIENT,ROLE_TRUSTED_CLIENT','45000', '45000'); 3 | 4 | INSERT INTO `users` (`user_id`, `email`, `first_name`, `last_name`, `mobile`, `password`, `user_name`) 5 | VALUES(123456,'demo@example.com', 'Demo', 'Example', '1234578632', '$2a$08$V0jF.bqEvkO9EhpSEfXi5OZ2JAygrAyz/8X3BLCKHgc2pPyBi4Spy', 'demo'); 6 | 7 | INSERT INTO `roles` (`role_id`, `role_name`) 8 | VALUES(1234, 'ROLE_DEMO'); 9 | 10 | INSERT INTO `user_roles` (`role_id`, `user_id`) 11 | VALUES(1234, 123456); -------------------------------------------------------------------------------- /authentication-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | ${FILE_LOG_PATTERN} 12 | 13 | 14 | 15 | ${LOG_FILE}.log 16 | 17 | ${FILE_LOG_PATTERN} 18 | 19 | 20 | 21 | ${LOG_FILE}.%d{yyyy-MM-dd}.gz 22 | 23 | 24 | - 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /authentication-service/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE oauth_client_details ( 2 | client_id VARCHAR(255) PRIMARY KEY, 3 | resource_ids VARCHAR(255), 4 | client_secret VARCHAR(255), 5 | scope VARCHAR(255), 6 | authorized_grant_types VARCHAR(255), 7 | web_server_redirect_uri VARCHAR(255), 8 | authorities VARCHAR(255), 9 | access_token_validity INTEGER, 10 | refresh_token_validity INTEGER, 11 | additional_information VARCHAR(255), 12 | autoapprove VARCHAR(255) 13 | ); 14 | 15 | CREATE TABLE oauth_client_token ( 16 | token_id VARCHAR(255), 17 | token BLOB, 18 | authentication_id VARCHAR(255), 19 | user_name VARCHAR(255), 20 | client_id VARCHAR(255) 21 | ); 22 | 23 | CREATE TABLE oauth_access_token ( 24 | token_id VARCHAR(255), 25 | token BLOB, 26 | authentication_id VARCHAR(255), 27 | user_name VARCHAR(255), 28 | client_id VARCHAR(255), 29 | authentication BLOB, 30 | refresh_token VARCHAR(255) 31 | ); 32 | CREATE TABLE oauth_refresh_token ( 33 | token_id VARCHAR(255), 34 | token BLOB, 35 | authentication BLOB 36 | ); 37 | CREATE TABLE oauth_code ( 38 | code VARCHAR(255), authentication BLOB 39 | ); 40 | 41 | CREATE TABLE `users` ( 42 | `user_id` int(10) unsigned NOT NULL, 43 | `email` varchar(45) DEFAULT NULL, 44 | `first_name` varchar(45) DEFAULT NULL, 45 | `last_name` varchar(45) DEFAULT NULL, 46 | `mobile` varchar(15) DEFAULT NULL, 47 | `password` varchar(255) NOT NULL, 48 | `user_name` varchar(45) NOT NULL, 49 | PRIMARY KEY (`user_id`), 50 | UNIQUE KEY `UK_k8d0f2n7n88w1a16yhua64onx` (`user_name`), 51 | UNIQUE KEY `UK_6dotkott2kjsp8vw4d0m25fb7` (`email`), 52 | UNIQUE KEY `UK_63cf888pmqtt5tipcne79xsbm` (`mobile`) 53 | ); 54 | 55 | CREATE TABLE `roles` ( 56 | `role_id` smallint(5) unsigned NOT NULL, 57 | `role_name` varchar(45) NOT NULL, 58 | PRIMARY KEY (`role_id`), 59 | UNIQUE KEY `UK3cyq9kgtpbol1tlouij82oufa` (`role_id`,`role_name`), 60 | UNIQUE KEY `UK_716hgxp60ym1lifrdgp67xt5k` (`role_name`) 61 | ); 62 | 63 | CREATE TABLE `user_roles` ( 64 | `user_id` int(10) unsigned NOT NULL, 65 | `role_id` smallint(5) unsigned NOT NULL, 66 | PRIMARY KEY (`user_id`,`role_id`), 67 | CONSTRAINT `FKh8ciramu9cc9q3qcqiv4ue8a6` FOREIGN KEY (`role_id`) REFERENCES `roles` (`role_id`), 68 | CONSTRAINT `FKhfh9dx7w3ubf1co1vdev94g3f` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) 69 | ); 70 | -------------------------------------------------------------------------------- /authentication-service/src/test/java/com/auth/controller/UserControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.auth.controller; 2 | 3 | import static org.mockito.Mockito.when; 4 | import static org.mockito.MockitoAnnotations.initMocks; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 8 | 9 | import java.security.Principal; 10 | 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | import org.mockito.InjectMocks; 15 | import org.mockito.Mock; 16 | import org.springframework.boot.test.context.SpringBootTest; 17 | import org.springframework.test.context.junit4.SpringRunner; 18 | import org.springframework.test.context.web.WebAppConfiguration; 19 | import org.springframework.test.web.servlet.MockMvc; 20 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 21 | 22 | import com.auth.entity.Users; 23 | import com.auth.server.AuthenticationServer; 24 | import com.auth.service.UserService; 25 | 26 | @RunWith(SpringRunner.class) 27 | @SpringBootTest(classes = AuthenticationServer.class) 28 | @WebAppConfiguration 29 | public class UserControllerTest { 30 | 31 | @InjectMocks 32 | private UserController userController; 33 | 34 | @Mock 35 | private UserService userService; 36 | 37 | private MockMvc mockMvc; 38 | 39 | @Before 40 | public void setup(){ 41 | initMocks(this); 42 | this.mockMvc = MockMvcBuilders.standaloneSetup(userController).build(); 43 | } 44 | @Test 45 | public void findByUsername() throws Exception{ 46 | Users user = getUser(); 47 | 48 | when(userService.findByUsername(user.getUserName())).thenReturn(user); 49 | 50 | mockMvc.perform(get("/users").principal(new Principal() { 51 | @Override 52 | public String getName() { 53 | return user.getUserName(); 54 | } 55 | })) 56 | .andExpect(jsonPath("$.userName").value(user.getUserName())) 57 | .andExpect(status().isOk()); 58 | } 59 | @Test 60 | public void authenticate() throws Exception{ 61 | Users user = getUser(); 62 | 63 | when(userService.findByUsername(user.getUserName())).thenReturn(user); 64 | mockMvc.perform(get("/users/authenticate").principal(new Principal() { 65 | @Override 66 | public String getName() { 67 | return user.getUserName(); 68 | } 69 | })) 70 | .andExpect(jsonPath("$.name").value(user.getUserName())) 71 | .andExpect(status().isOk()); 72 | } 73 | private Users getUser(){ 74 | 75 | Users user = new Users(); 76 | user.setUserName("nolan"); 77 | user.setEmail("christopher@test.com"); 78 | return user; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /authentication-service/src/test/java/com/auth/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.auth.service; 2 | 3 | import static org.mockito.Mockito.when; 4 | import static org.mockito.MockitoAnnotations.initMocks; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.mockito.InjectMocks; 10 | import org.mockito.Mock; 11 | 12 | import com.auth.entity.Users; 13 | import com.auth.repository.UsersRepository; 14 | import com.auth.service.impl.UserServiceImpl; 15 | 16 | public class UserServiceTest { 17 | 18 | @InjectMocks 19 | private UserServiceImpl userService; 20 | 21 | @Mock 22 | private UsersRepository userRepository; 23 | 24 | @Before 25 | public void setup(){ 26 | initMocks(this); 27 | } 28 | @Test 29 | public void findByUsername(){ 30 | Users user = getUser(); 31 | 32 | when(userRepository.findByUserName(user.getUserName())).thenReturn(user); 33 | Users foundUser = userService.findByUsername(user.getUserName()); 34 | Assert.assertEquals("User", user, foundUser); 35 | } 36 | @Test 37 | public void findByUserId(){ 38 | Users user = getUser(); 39 | 40 | when(userRepository.findOne(user.getUserId())).thenReturn(user); 41 | Users foundUser = userService.findByUserId(user.getUserId()); 42 | Assert.assertEquals("User id", user, foundUser); 43 | } 44 | private Users getUser(){ 45 | Users user = new Users(); 46 | user.setUserId(345678); 47 | user.setUserName("nolan"); 48 | user.setEmail("christopher@test.com"); 49 | return user; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /authentication-service/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8787 2 | server.context-path=/auth-api 3 | spring.application.name=auth-server 4 | 5 | ################ DB Connection ################# 6 | spring.datasource.url=jdbc:h2:mem:auth_service 7 | spring.datasource.username= 8 | spring.datasource.password= 9 | spring.datasource.dataSourceClassName=org.h2.jdbcx.JdbcDataSource 10 | spring.datasource.schema=classpath:/schema.sql 11 | spring.datasource.data=classpath:/data.sql 12 | 13 | # JPA properties 14 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 15 | spring.jpa.database=H2 16 | spring.jpa.openInView=false 17 | spring.jpa.show_sql=true 18 | spring.jpa.generate-ddl=false 19 | spring.jpa.hibernate.ddl-auto=none 20 | 21 | security.basic.enabled=false 22 | 23 | #To maintain oauth filter ordering 24 | security.oauth2.resource.filter-order=3 25 | 26 | #Disable client registration 27 | eureka.client.register-with-eureka=false 28 | eureka.client.fetch-registry=false -------------------------------------------------------------------------------- /authentication-service/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO oauth_client_details(client_id, client_secret, scope, authorized_grant_types, authorities, access_token_validity, refresh_token_validity) 2 | VALUES ('trusted-app', '$2a$08$V0jF.bqEvkO9EhpSEfXi5OZ2JAygrAyz/8X3BLCKHgc2pPyBi4Spy', 'read,write,trust', 'client_credentials,authorization_code,implicit,password,refresh_token','ROLE_CLIENT,ROLE_TRUSTED_CLIENT','45000', '45000'); 3 | 4 | INSERT INTO `users` (`user_id`, `email`, `first_name`, `last_name`, `mobile`, `password`, `user_name`) 5 | VALUES(123456,'demo@example.com', 'Demo', 'Example', '1234578632', '$2a$08$V0jF.bqEvkO9EhpSEfXi5OZ2JAygrAyz/8X3BLCKHgc2pPyBi4Spy', 'demo'); 6 | 7 | INSERT INTO `roles` (`role_id`, `role_name`) 8 | VALUES(1234, 'ROLE_DEMO'); 9 | 10 | INSERT INTO `user_roles` (`role_id`, `user_id`) 11 | VALUES(1234, 123456); -------------------------------------------------------------------------------- /authentication-service/src/test/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE oauth_client_details ( 2 | client_id VARCHAR(255) PRIMARY KEY, 3 | resource_ids VARCHAR(255), 4 | client_secret VARCHAR(255), 5 | scope VARCHAR(255), 6 | authorized_grant_types VARCHAR(255), 7 | web_server_redirect_uri VARCHAR(255), 8 | authorities VARCHAR(255), 9 | access_token_validity INTEGER, 10 | refresh_token_validity INTEGER, 11 | additional_information VARCHAR(255), 12 | autoapprove VARCHAR(255) 13 | ); 14 | 15 | CREATE TABLE oauth_client_token ( 16 | token_id VARCHAR(255), 17 | token BLOB, 18 | authentication_id VARCHAR(255), 19 | user_name VARCHAR(255), 20 | client_id VARCHAR(255) 21 | ); 22 | 23 | CREATE TABLE oauth_access_token ( 24 | token_id VARCHAR(255), 25 | token BLOB, 26 | authentication_id VARCHAR(255), 27 | user_name VARCHAR(255), 28 | client_id VARCHAR(255), 29 | authentication BLOB, 30 | refresh_token VARCHAR(255) 31 | ); 32 | CREATE TABLE oauth_refresh_token ( 33 | token_id VARCHAR(255), 34 | token BLOB, 35 | authentication BLOB 36 | ); 37 | CREATE TABLE oauth_code ( 38 | code VARCHAR(255), authentication BLOB 39 | ); 40 | 41 | CREATE TABLE `users` ( 42 | `user_id` int(10) unsigned NOT NULL, 43 | `email` varchar(45) DEFAULT NULL, 44 | `first_name` varchar(45) DEFAULT NULL, 45 | `last_name` varchar(45) DEFAULT NULL, 46 | `mobile` varchar(15) DEFAULT NULL, 47 | `password` varchar(255) NOT NULL, 48 | `user_name` varchar(45) NOT NULL, 49 | PRIMARY KEY (`user_id`), 50 | UNIQUE KEY `UK_k8d0f2n7n88w1a16yhua64onx` (`user_name`), 51 | UNIQUE KEY `UK_6dotkott2kjsp8vw4d0m25fb7` (`email`), 52 | UNIQUE KEY `UK_63cf888pmqtt5tipcne79xsbm` (`mobile`) 53 | ); 54 | 55 | CREATE TABLE `roles` ( 56 | `role_id` smallint(5) unsigned NOT NULL, 57 | `role_name` varchar(45) NOT NULL, 58 | PRIMARY KEY (`role_id`), 59 | UNIQUE KEY `UK3cyq9kgtpbol1tlouij82oufa` (`role_id`,`role_name`), 60 | UNIQUE KEY `UK_716hgxp60ym1lifrdgp67xt5k` (`role_name`) 61 | ); 62 | 63 | CREATE TABLE `user_roles` ( 64 | `user_id` int(10) unsigned NOT NULL, 65 | `role_id` smallint(5) unsigned NOT NULL, 66 | PRIMARY KEY (`user_id`,`role_id`), 67 | CONSTRAINT `FKh8ciramu9cc9q3qcqiv4ue8a6` FOREIGN KEY (`role_id`) REFERENCES `roles` (`role_id`), 68 | CONSTRAINT `FKhfh9dx7w3ubf1co1vdev94g3f` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) 69 | ); 70 | -------------------------------------------------------------------------------- /order-service/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf 2 | *.java text eol=lf 3 | *.properties text eol=lf 4 | *.xml text eol=lf 5 | *.jsp text eol=lf 6 | *.html text eol=lf 7 | *.css text eol=lf 8 | *.js text eol=lf 9 | *.ftl text eol=lf 10 | -------------------------------------------------------------------------------- /order-service/.gitignore: -------------------------------------------------------------------------------- 1 | # Java class files 2 | *.class 3 | 4 | 5 | 6 | 7 | # Eclipse project files 8 | .classpath 9 | .project 10 | .settings/ 11 | 12 | 13 | #Gradle 14 | .gradletasknamecache 15 | .gradle/ 16 | build/ 17 | bin/ 18 | gradle/ 19 | gradlew 20 | gradlew.bat 21 | 22 | #log 23 | log 24 | /.gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /order-service/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | apply plugin: 'java' 3 | apply plugin: 'org.springframework.boot' 4 | apply plugin: 'eclipse' 5 | 6 | buildscript { 7 | ext { 8 | springBootVersion = '1.5.3.RELEASE' 9 | } 10 | repositories { 11 | mavenCentral() 12 | } 13 | dependencies { 14 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 15 | } 16 | } 17 | 18 | sourceCompatibility = 1.8 19 | targetCompatibility = 1.8 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencyManagement { 25 | imports { 26 | mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1' 27 | } 28 | } 29 | 30 | dependencies { 31 | compile ('org.springframework.cloud:spring-cloud-starter-eureka') 32 | compile ('org.springframework.boot:spring-boot-starter-security') 33 | compile ('org.springframework.cloud:spring-cloud-starter-oauth2') 34 | compile ('org.springframework.boot:spring-boot-starter-data-jpa') 35 | compile ('org.springframework.boot:spring-boot-starter-web') 36 | compile("com.h2database:h2") 37 | testCompile('org.springframework.boot:spring-boot-starter-test') 38 | } 39 | jar { 40 | manifest { 41 | attributes "Main-Class": "com.sample.starter.OrderServiceStarter" 42 | } 43 | 44 | from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }){ 45 | exclude 'META-INF/MANIFEST.MF' 46 | exclude 'META-INF/*.SF' 47 | exclude 'META-INF/*.DSA' 48 | exclude 'META-INF/*.RSA' 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /order-service/settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | rootProject.name = 'order-service' 3 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.order.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import com.order.entity.Orders; 16 | import com.order.service.OrderService; 17 | 18 | @RestController 19 | @RequestMapping(value = "/orders") 20 | public class OrderController { 21 | 22 | @Autowired 23 | private OrderService orderService; 24 | 25 | @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) 26 | public ResponseEntity createOrder(@RequestBody Orders order){ 27 | Orders createdOrder = orderService.create(order); 28 | return ResponseEntity.ok(createdOrder); 29 | } 30 | @GetMapping(value = "/{orderId}", produces = MediaType.APPLICATION_JSON_VALUE) 31 | public ResponseEntity getOrder(@PathVariable("orderId") Integer orderId){ 32 | Orders order = orderService.getOrder(orderId); 33 | return ResponseEntity.ok(order); 34 | } 35 | @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) 36 | public ResponseEntity> getAllOrders(){ 37 | List orders = orderService.getOrders(); 38 | return ResponseEntity.>ok(orders); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/entity/Orders.java: -------------------------------------------------------------------------------- 1 | package com.order.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.GenerationType; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | import javax.persistence.Temporal; 13 | import javax.persistence.TemporalType; 14 | 15 | @Entity 16 | @Table(name = "orders") 17 | public class Orders implements Serializable{ 18 | 19 | private static final long serialVersionUID = 5963825246334931686L; 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.AUTO) 23 | private int id; 24 | 25 | @Column(name= "amount", nullable =false) 26 | private double amount; 27 | 28 | @Temporal(TemporalType.TIMESTAMP) 29 | @Column(name = "date", nullable = false) 30 | private Date date; 31 | 32 | @Column(name = "status", nullable = false) 33 | private String status; 34 | 35 | @Column(name = "quantity", nullable = false) 36 | private Integer quantity; 37 | 38 | public int getId() { 39 | return id; 40 | } 41 | 42 | public void setId(int id) { 43 | this.id = id; 44 | } 45 | 46 | public double getAmount() { 47 | return amount; 48 | } 49 | 50 | public void setAmount(double amount) { 51 | this.amount = amount; 52 | } 53 | 54 | public Date getDate() { 55 | return date; 56 | } 57 | 58 | public void setDate(Date date) { 59 | this.date = date; 60 | } 61 | 62 | public String getStatus() { 63 | return status; 64 | } 65 | 66 | public void setStatus(String status) { 67 | this.status = status; 68 | } 69 | 70 | public Integer getQuantity() { 71 | return quantity; 72 | } 73 | 74 | public void setQuantity(Integer quantity) { 75 | this.quantity = quantity; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.order.repository; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | import com.order.entity.Orders; 6 | 7 | public interface OrderRepository extends JpaRepository{ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.order.service; 2 | 3 | import java.util.List; 4 | 5 | import com.order.entity.Orders; 6 | 7 | public interface OrderService { 8 | Orders create(Orders order); 9 | List getOrders(); 10 | Orders getOrder(Integer id); 11 | } 12 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.order.service.impl; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import com.order.entity.Orders; 9 | import com.order.repository.OrderRepository; 10 | import com.order.service.OrderService; 11 | 12 | @Service 13 | public class OrderServiceImpl implements OrderService{ 14 | 15 | @Autowired 16 | private OrderRepository orderRepository; 17 | 18 | @Override 19 | public Orders create(Orders order) { 20 | return orderRepository.saveAndFlush(order); 21 | } 22 | 23 | @Override 24 | public List getOrders() { 25 | return orderRepository.findAll(); 26 | } 27 | 28 | @Override 29 | public Orders getOrder(Integer id) { 30 | return orderRepository.findOne(id); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /order-service/src/main/java/com/order/starter/OrderServiceStarter.java: -------------------------------------------------------------------------------- 1 | package com.order.starter; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 10 | 11 | @EnableDiscoveryClient 12 | @SpringBootApplication 13 | @EnableResourceServer 14 | @ComponentScan("com.order") 15 | @EnableJpaRepositories(basePackages ={"com.order.repository"}) 16 | @EntityScan(basePackages={"com.order.entity"}) 17 | public class OrderServiceStarter { 18 | public static void main(String[] args) { 19 | SpringApplication.run(OrderServiceStarter.class, args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /order-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=6767 2 | server.context-path=/order-api 3 | spring.application.name=order-service 4 | 5 | ################ DB Connection ################# 6 | spring.datasource.url=jdbc:h2:mem:order_service 7 | spring.datasource.username= 8 | spring.datasource.password= 9 | spring.datasource.dataSourceClassName=org.h2.jdbcx.JdbcDataSource 10 | 11 | # JPA properties 12 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 13 | spring.jpa.database=H2 14 | spring.jpa.openInView=false 15 | spring.jpa.show_sql=true 16 | spring.jpa.generate-ddl=false 17 | spring.jpa.hibernate.ddl-auto=create 18 | 19 | # Discovery Server Access 20 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 21 | eureka.instance.preferIpAddress=true 22 | 23 | security.basic.enabled=false 24 | 25 | #To maintain oauth filter ordering 26 | security.oauth2.resource.filter-order=3 27 | 28 | # User info 29 | security.oauth2.resource.userInfoUri=http://localhost:8787/auth-api/users/authenticate 30 | -------------------------------------------------------------------------------- /order-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | ${FILE_LOG_PATTERN} 12 | 13 | 14 | 15 | ${LOG_FILE}.log 16 | 17 | ${FILE_LOG_PATTERN} 18 | 19 | 20 | 21 | ${LOG_FILE}.%d{yyyy-MM-dd}.gz 22 | 23 | 24 | - 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /order-service/src/test/java/com/order/controller/OrderControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.order.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | import org.springframework.http.MediaType; 14 | import org.springframework.test.context.junit4.SpringRunner; 15 | import org.springframework.test.context.web.WebAppConfiguration; 16 | import org.springframework.test.web.servlet.MockMvc; 17 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 18 | 19 | import com.fasterxml.jackson.databind.ObjectMapper; 20 | import com.order.entity.Orders; 21 | import com.order.service.OrderService; 22 | import com.order.starter.OrderServiceStarter; 23 | 24 | import static org.mockito.Mockito.when; 25 | import static org.mockito.MockitoAnnotations.initMocks; 26 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 27 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 28 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 29 | 30 | 31 | @RunWith(SpringRunner.class) 32 | @SpringBootTest(classes = OrderServiceStarter.class) 33 | @WebAppConfiguration 34 | public class OrderControllerTest { 35 | 36 | private ObjectMapper objectMapper = new ObjectMapper(); 37 | 38 | @InjectMocks 39 | private OrderController orderController; 40 | 41 | @Mock 42 | private OrderService orderService; 43 | 44 | private MockMvc mockMvc; 45 | 46 | @Before 47 | public void setUp(){ 48 | initMocks(this); 49 | this.mockMvc = MockMvcBuilders.standaloneSetup(orderController).build(); 50 | } 51 | @Test 52 | public void createOrder() throws Exception{ 53 | Orders order = getOrder(); 54 | 55 | String jsonValue = objectMapper.writeValueAsString(order); 56 | 57 | mockMvc.perform(post("/orders").contentType(MediaType.APPLICATION_JSON).content(jsonValue)) 58 | .andExpect(status().isOk()); 59 | } 60 | @Test 61 | public void getOrders() throws Exception{ 62 | Orders order1 = getOrder(); 63 | Orders order2 = getOrder(); 64 | 65 | List orders = new ArrayList<>(); 66 | orders.add(order1); 67 | orders.add(order2); 68 | 69 | when(orderService.getOrders()).thenReturn(orders); 70 | 71 | mockMvc.perform(get("/orders")).andExpect(jsonPath("$[0].amount").value(orders.get(0).getAmount())) 72 | .andExpect(status().isOk()); 73 | } 74 | private Orders getOrder(){ 75 | Orders order = new Orders(); 76 | order.setDate(new Date()); 77 | order.setAmount(2000.00); 78 | order.setQuantity(1); 79 | order.setStatus("CONFIRMED"); 80 | return order; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /order-service/src/test/java/com/order/service/OrderServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.order.service; 2 | 3 | 4 | import static org.mockito.Mockito.times; 5 | import static org.mockito.Mockito.verify; 6 | import static org.mockito.Mockito.when; 7 | import static org.mockito.MockitoAnnotations.initMocks; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Date; 11 | import java.util.List; 12 | 13 | import org.junit.Assert; 14 | import org.junit.Before; 15 | import org.junit.Test; 16 | import org.mockito.InjectMocks; 17 | import org.mockito.Mock; 18 | 19 | import com.order.entity.Orders; 20 | import com.order.repository.OrderRepository; 21 | import com.order.service.impl.OrderServiceImpl; 22 | 23 | public class OrderServiceTest { 24 | 25 | @Mock 26 | private OrderRepository orderRepository; 27 | 28 | @InjectMocks 29 | private OrderServiceImpl orderService; 30 | 31 | @Before 32 | public void setup(){ 33 | initMocks(this); 34 | } 35 | @Test 36 | public void createOrder(){ 37 | Orders order = getOrder(1); 38 | orderService.create(order); 39 | verify(orderRepository, times(1)).saveAndFlush(order); 40 | } 41 | @Test 42 | public void findOrder(){ 43 | Orders order = getOrder(1); 44 | when(orderService.getOrder(order.getId())).thenReturn(order); 45 | 46 | Orders foundOrder = orderService.getOrder(order.getId()); 47 | Assert.assertEquals("Order", order, foundOrder); 48 | } 49 | @Test 50 | public void getAllOrders(){ 51 | Orders order1 = getOrder(1); 52 | Orders order2 = getOrder(2); 53 | 54 | List orders = new ArrayList<>(); 55 | orders.add(order1); 56 | orders.add(order2); 57 | 58 | when(orderService.getOrders()).thenReturn(orders); 59 | 60 | List foundOrders = orderService.getOrders(); 61 | Assert.assertEquals(orders.size(), foundOrders.size(), 0); 62 | } 63 | private Orders getOrder(int id){ 64 | Orders order = new Orders(); 65 | order.setId(id); 66 | order.setDate(new Date()); 67 | order.setAmount(2000.00); 68 | order.setQuantity(1); 69 | order.setStatus("CONFIRMED"); 70 | return order; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /order-service/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=6767 2 | server.context-path=/order-api 3 | spring.application.name=order-service 4 | 5 | ################ DB Connection ################# 6 | spring.datasource.url=jdbc:h2:mem:demo_service 7 | spring.datasource.username= 8 | spring.datasource.password= 9 | spring.datasource.dataSourceClassName=org.h2.jdbcx.JdbcDataSource 10 | 11 | # JPA properties 12 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 13 | spring.jpa.database=H2 14 | spring.jpa.openInView=false 15 | spring.jpa.show_sql=true 16 | spring.jpa.generate-ddl=false 17 | spring.jpa.hibernate.ddl-auto=create 18 | 19 | security.basic.enabled=false 20 | 21 | #Disable client registration 22 | eureka.client.register-with-eureka=false 23 | eureka.client.fetch-registry=false -------------------------------------------------------------------------------- /routing-server/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf 2 | *.java text eol=lf 3 | *.properties text eol=lf 4 | *.xml text eol=lf 5 | *.jsp text eol=lf 6 | *.html text eol=lf 7 | *.css text eol=lf 8 | *.js text eol=lf 9 | *.ftl text eol=lf 10 | -------------------------------------------------------------------------------- /routing-server/.gitignore: -------------------------------------------------------------------------------- 1 | # Java class files 2 | *.class 3 | 4 | 5 | 6 | 7 | # Eclipse project files 8 | .classpath 9 | .project 10 | .settings/ 11 | 12 | 13 | #Gradle 14 | .gradletasknamecache 15 | .gradle/ 16 | build/ 17 | bin/ 18 | gradle/ 19 | gradlew 20 | gradlew.bat 21 | 22 | #log 23 | log 24 | /.gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /routing-server/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansaritariq/microservices_architecture/dc72e9b92465228a3ec2d2a264081c0dd104a873/routing-server/README.md -------------------------------------------------------------------------------- /routing-server/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'org.springframework.boot' 3 | apply plugin: 'eclipse' 4 | 5 | sourceCompatibility = 1.8 6 | targetCompatibility = 1.8 7 | 8 | buildscript { 9 | ext { 10 | springBootVersion = '1.5.3.RELEASE' 11 | } 12 | repositories { 13 | mavenCentral() 14 | } 15 | dependencies { 16 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 17 | } 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | dependencyManagement { 24 | imports { 25 | mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1' 26 | } 27 | } 28 | dependencies { 29 | compile ('org.springframework.cloud:spring-cloud-starter-zuul') 30 | compile ('org.springframework.cloud:spring-cloud-starter-eureka') 31 | compile ('org.springframework.boot:spring-boot-starter-security') 32 | compile ('org.springframework.cloud:spring-cloud-starter-security') 33 | testCompile('org.springframework.boot:spring-boot-starter-test') 34 | } 35 | 36 | jar { 37 | manifest { 38 | attributes "Main-Class": "com.gateway.server.GatewayServer" 39 | } 40 | 41 | from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }){ 42 | exclude 'META-INF/MANIFEST.MF' 43 | exclude 'META-INF/*.SF' 44 | exclude 'META-INF/*.DSA' 45 | exclude 'META-INF/*.RSA' 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /routing-server/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was auto generated by the Gradle buildInit task 3 | * by 'tariq.anwar' at '18/11/16 11:20 AM' with Gradle 2.14 4 | * 5 | * The settings file is used to specify which projects to include in your build. 6 | * In a single project build this file can be empty or even removed. 7 | * 8 | * Detailed information about configuring a multi-project build in Gradle can be found 9 | * in the user guide at https://docs.gradle.org/2.14/userguide/multi_project_builds.html 10 | */ 11 | 12 | /* 13 | // To declare projects as part of a multi-project build use the 'include' method 14 | include 'shared' 15 | include 'api' 16 | include 'services:webservice' 17 | */ 18 | 19 | rootProject.name = 'edge-server' 20 | -------------------------------------------------------------------------------- /routing-server/src/main/java/com/gateway/config/GatewaySecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.gateway.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 | 8 | @Configuration 9 | public class GatewaySecurityConfiguration extends WebSecurityConfigurerAdapter { 10 | 11 | @Override 12 | protected void configure(HttpSecurity http) throws Exception { 13 | http.csrf().disable().authorizeRequests().antMatchers("/**").permitAll(); 14 | 15 | } 16 | //Allowing all the request to pass 17 | @Override 18 | public void configure(WebSecurity web) throws Exception { 19 | web.ignoring().antMatchers("/**"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /routing-server/src/main/java/com/gateway/filter/CORSFilter.java: -------------------------------------------------------------------------------- 1 | package com.gateway.filter; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.Filter; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.FilterConfig; 8 | import javax.servlet.ServletException; 9 | import javax.servlet.ServletRequest; 10 | import javax.servlet.ServletResponse; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.springframework.core.Ordered; 17 | import org.springframework.core.annotation.Order; 18 | import org.springframework.stereotype.Component; 19 | 20 | 21 | @Component 22 | @Order(Ordered.HIGHEST_PRECEDENCE) 23 | public class CORSFilter implements Filter { 24 | 25 | final static Logger logger = LoggerFactory.getLogger(CORSFilter.class); 26 | 27 | @Override 28 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 29 | throws IOException, ServletException { 30 | HttpServletRequest request = (HttpServletRequest) req; 31 | 32 | HttpServletResponse response = (HttpServletResponse) res; 33 | response.setHeader("Access-Control-Allow-Origin", "*"); 34 | response.setHeader("Access-Control-Allow-Credentials", "true"); 35 | response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); 36 | response.setHeader("Access-Control-Max-Age", "3600"); 37 | response.setHeader("Access-Control-Allow-Headers", 38 | "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers"); 39 | 40 | if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 41 | response.setStatus(HttpServletResponse.SC_OK); 42 | } else { 43 | chain.doFilter(req, res); 44 | } 45 | } 46 | 47 | @Override 48 | public void init(FilterConfig filterConfig) { 49 | logger.info("Implementation not required"); 50 | } 51 | 52 | @Override 53 | public void destroy() { 54 | logger.info("Implementation not required"); 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /routing-server/src/main/java/com/gateway/filter/GatewayFilter.java: -------------------------------------------------------------------------------- 1 | 2 | package com.gateway.filter; 3 | 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.netflix.zuul.ZuulFilter; 10 | import com.netflix.zuul.context.RequestContext; 11 | /** 12 | * This class can be used to allow sensitive headers 13 | * Omitted by zuul. 14 | * 15 | * @see ZuulFilter 16 | * @author tariq.anwar 17 | */ 18 | @Component 19 | public class GatewayFilter extends ZuulFilter { 20 | 21 | @Override 22 | public String filterType() { 23 | return "pre"; 24 | } 25 | 26 | @Override 27 | public int filterOrder() { 28 | return 1; 29 | } 30 | 31 | @Override 32 | public boolean shouldFilter() { 33 | return true; 34 | } 35 | 36 | @Override 37 | public Object run() { 38 | RequestContext ctx = RequestContext.getCurrentContext(); 39 | HttpServletRequest request = ctx.getRequest(); 40 | /* 41 | * Adding authorization header to zuul request header as 42 | * zuul omits sensitive headers 43 | */ 44 | if(request.getHeader("Authorization") != null){ 45 | ctx.addZuulRequestHeader("Authorization", request.getHeader("Authorization")); 46 | } 47 | return null; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /routing-server/src/main/java/com/gateway/server/GatewayServer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.gateway.server; 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | import org.springframework.context.annotation.ComponentScan; 8 | 9 | @SpringBootApplication 10 | @EnableZuulProxy 11 | @ComponentScan("com.gateway") 12 | public class GatewayServer { 13 | public static void main(String[] args) { 14 | SpringApplication.run(GatewayServer.class, args); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /routing-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Port 2 | server.port=8765 3 | 4 | # Application name 5 | spring.application.name=gateway-server 6 | 7 | # Discovery Server Access 8 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 9 | 10 | #Disable Spring Boot basic authentication 11 | security.basic.enabled=false 12 | security.user.password=none 13 | 14 | #zuul routing 15 | zuul.routes.auth-server.path=/auth-api/** 16 | zuul.routes.auth-server.stripPrefix=false 17 | zuul.routes.order-service.path=/order-api/** 18 | zuul.routes.order-service.stripPrefix=false 19 | 20 | #Hystrix time out 21 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000 22 | 23 | #Ribbon time out 24 | auth-server.ribbon.ReadTimeout=70000 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /routing-server/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | ${FILE_LOG_PATTERN} 13 | 14 | 15 | 16 | ${LOG_FILE}.log 17 | 18 | ${FILE_LOG_PATTERN} 19 | 20 | 21 | 22 | ${LOG_FILE}.%d{yyyy-MM-dd}.gz 23 | 24 | 25 | - 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /service-registrar/.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf 2 | *.java text eol=lf 3 | *.properties text eol=lf 4 | *.xml text eol=lf 5 | *.jsp text eol=lf 6 | *.html text eol=lf 7 | *.css text eol=lf 8 | *.js text eol=lf 9 | *.ftl text eol=lf 10 | -------------------------------------------------------------------------------- /service-registrar/.gitignore: -------------------------------------------------------------------------------- 1 | # Java class files 2 | *.class 3 | 4 | 5 | 6 | 7 | # Eclipse project files 8 | .classpath 9 | .project 10 | .settings/ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | #Gradle 19 | .gradletasknamecache 20 | .gradle/ 21 | build/ 22 | bin/ 23 | gradle/ 24 | gradlew 25 | gradlew.bat 26 | 27 | #log 28 | log 29 | /.gradle/ 30 | /build/ 31 | -------------------------------------------------------------------------------- /service-registrar/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansaritariq/microservices_architecture/dc72e9b92465228a3ec2d2a264081c0dd104a873/service-registrar/README.md -------------------------------------------------------------------------------- /service-registrar/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | apply plugin: 'java' 3 | apply plugin: 'org.springframework.boot' 4 | apply plugin: 'eclipse' 5 | 6 | buildscript { 7 | ext { 8 | springBootVersion = '1.5.3.RELEASE' 9 | } 10 | repositories { 11 | mavenCentral() 12 | } 13 | dependencies { 14 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 15 | } 16 | } 17 | 18 | sourceCompatibility = 1.8 19 | targetCompatibility = 1.8 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencyManagement { 25 | imports { 26 | mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Dalston.SR1' 27 | } 28 | } 29 | 30 | dependencies { 31 | compile 'org.springframework.cloud:spring-cloud-starter-eureka-server' 32 | testCompile('org.springframework.boot:spring-boot-starter-test') 33 | } 34 | jar { 35 | manifest { 36 | attributes "Main-Class": "com.service.registrar.ServiceRegistrationServer" 37 | } 38 | 39 | from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }){ 40 | exclude 'META-INF/MANIFEST.MF' 41 | exclude 'META-INF/*.SF' 42 | exclude 'META-INF/*.DSA' 43 | exclude 'META-INF/*.RSA' 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /service-registrar/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was auto generated by the Gradle buildInit task 3 | * by 'tariq.anwar' at '15/11/16 9:27 PM' with Gradle 2.14 4 | * 5 | * The settings file is used to specify which projects to include in your build. 6 | * In a single project build this file can be empty or even removed. 7 | * 8 | * Detailed information about configuring a multi-project build in Gradle can be found 9 | * in the user guide at https://docs.gradle.org/2.14/userguide/multi_project_builds.html 10 | */ 11 | 12 | /* 13 | // To declare projects as part of a multi-project build use the 'include' method 14 | include 'shared' 15 | include 'api' 16 | include 'services:webservice' 17 | */ 18 | 19 | rootProject.name = 'service-registrar' 20 | -------------------------------------------------------------------------------- /service-registrar/src/main/java/com/service/registrar/ServiceRegistrationServer.java: -------------------------------------------------------------------------------- 1 | package com.service.registrar; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class ServiceRegistrationServer { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServiceRegistrationServer.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /service-registrar/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8761 2 | security.basic.enabled=false 3 | eureka.client.register-with-eureka=false 4 | eureka.client.fetch-registry=false -------------------------------------------------------------------------------- /service-registrar/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | ${FILE_LOG_PATTERN} 12 | 13 | 14 | 15 | ${LOG_FILE}.log 16 | 17 | ${FILE_LOG_PATTERN} 18 | 19 | 20 | 21 | ${LOG_FILE}.%d{yyyy-MM-dd}.gz 22 | 23 | 24 | - 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /service-registrar/src/test/java/com/service/registrar/ServiceRegistrarTest.java: -------------------------------------------------------------------------------- 1 | package com.service.registrar; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest({"server.port:8761", "eureka.client.register-with-eureka:false", 10 | "eureka.client.fetch-registry:false"}) 11 | public class ServiceRegistrarTest { 12 | 13 | @Test 14 | public void contextLoadTest() { 15 | 16 | } 17 | } 18 | --------------------------------------------------------------------------------