├── licensing-service ├── src │ └── main │ │ ├── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ └── schema.sql │ │ ├── java │ │ └── com │ │ │ └── thoughtmechanix │ │ │ └── licenses │ │ │ ├── services │ │ │ ├── OrganizationService.java │ │ │ └── LicenseService.java │ │ │ ├── config │ │ │ └── ServiceConfig.java │ │ │ ├── Application.java │ │ │ ├── repository │ │ │ └── LicenseRepository.java │ │ │ ├── model │ │ │ ├── Organization.java │ │ │ └── License.java │ │ │ └── controllers │ │ │ └── LicenseServiceController.java │ │ └── docker │ │ ├── Dockerfile │ │ └── run.sh └── pom.xml ├── confsvr ├── src │ └── main │ │ ├── resources │ │ ├── bootstrap.yml │ │ ├── config │ │ │ ├── organizationservice │ │ │ │ └── organizationservice.yml │ │ │ └── licensingservice │ │ │ │ ├── licensingservice-dev.yml │ │ │ │ ├── licensingservice.yml │ │ │ │ └── licensingservice-prod.yml │ │ └── application.yml │ │ ├── docker │ │ ├── run.sh │ │ └── Dockerfile │ │ └── java │ │ └── com │ │ └── thoughtmechanix │ │ └── confsvr │ │ └── ConfigServerApplication.java ├── .gitignore └── pom.xml ├── .gitignore ├── docker ├── dev │ └── docker-compose.yml ├── prod │ └── docker-compose.yml └── common │ └── docker-compose.yml ├── pom.xml ├── .travis.yml └── README.md /licensing-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /confsvr/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: configserver 4 | 5 | -------------------------------------------------------------------------------- /confsvr/src/main/resources/config/organizationservice/organizationservice.yml: -------------------------------------------------------------------------------- 1 | example.organization.property: "I AM THE DEFAULT ORGANIZATION SERVICE" 2 | -------------------------------------------------------------------------------- /confsvr/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | #* 3 | *# 4 | .#* 5 | .classpath 6 | .project 7 | .settings 8 | .springBeans 9 | .gradle 10 | build 11 | bin 12 | /target/ 13 | git.properties 14 | .idea 15 | *.iml 16 | .factorypath 17 | -------------------------------------------------------------------------------- /licensing-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: licensingservice 4 | profiles: 5 | active: 6 | default 7 | cloud: 8 | config: 9 | uri: http://localhost:8888 -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/services/OrganizationService.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.services; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class OrganizationService { 7 | } 8 | -------------------------------------------------------------------------------- /confsvr/src/main/docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "********************************************************" 3 | echo "Starting Configuration Server" 4 | echo "********************************************************" 5 | java -jar /usr/local/configserver/@project.build.finalName@.jar 6 | -------------------------------------------------------------------------------- /licensing-service/src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | RUN apk update && apk upgrade && apk add netcat-openbsd 3 | RUN mkdir -p /usr/local/licensingservice 4 | ADD @project.build.finalName@.jar /usr/local/licensingservice/ 5 | ADD run.sh run.sh 6 | RUN chmod +x run.sh 7 | CMD ./run.sh 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Java class files 2 | *.class 3 | 4 | # Eclipse project files 5 | .classpath 6 | .project 7 | .settings/ 8 | 9 | # Intellij project files 10 | *.iml 11 | *.ipr 12 | *.iws 13 | .idea/ 14 | 15 | .DS_Store/ 16 | /target 17 | 18 | /target 19 | /target/ 20 | **/target/ 21 | 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/config/ServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | public class ServiceConfig{ 8 | 9 | @Value("${example.property}") 10 | private String exampleProperty; 11 | 12 | public String getExampleProperty(){ 13 | return exampleProperty; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /confsvr/src/main/java/com/thoughtmechanix/confsvr/ConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.confsvr; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.config.server.EnableConfigServer; 6 | 7 | @SpringBootApplication 8 | @EnableConfigServer 9 | public class ConfigServerApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(ConfigServerApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/Application.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses; 2 | 3 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.context.config.annotation.RefreshScope; 7 | 8 | @SpringBootApplication 9 | @RefreshScope 10 | public class Application { 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/repository/LicenseRepository.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.repository; 2 | 3 | import com.thoughtmechanix.licenses.model.License; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | @Repository 10 | public interface LicenseRepository extends CrudRepository { 11 | public List findByOrganizationId(String organizationId); 12 | public License findByOrganizationIdAndLicenseId(String organizationId,String licenseId); 13 | } 14 | -------------------------------------------------------------------------------- /confsvr/src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | RUN apk update && apk upgrade && apk add netcat-openbsd && apk add curl 3 | RUN mkdir -p /usr/local/configserver 4 | RUN echo $JAVA_HOME 5 | RUN cd /tmp/ && \ 6 | curl -k -LO "http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip" -H 'Cookie: oraclelicense=accept-securebackup-cookie' && \ 7 | unzip jce_policy-8.zip && \ 8 | rm jce_policy-8.zip && \ 9 | yes |cp -v /tmp/UnlimitedJCEPolicyJDK8/*.jar /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/ 10 | ADD @project.build.finalName@.jar /usr/local/configserver/ 11 | ADD run.sh run.sh 12 | RUN chmod +x run.sh 13 | CMD ./run.sh 14 | -------------------------------------------------------------------------------- /docker/dev/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | database: 4 | extends: 5 | file: ../common/docker-compose.yml 6 | service: database 7 | environment: 8 | POSTGRES_USER: "postgres_dev" 9 | POSTGRES_PASSWORD: "p0stgr@s_dev" 10 | POSTGRES_DB: "eagle_eye_dev" 11 | configserver: 12 | extends: 13 | file: ../common/docker-compose.yml 14 | service: configserver 15 | licensingservice: 16 | image: ch3-thoughtmechanix/licensing-service 17 | ports: 18 | - "8080:8080" 19 | environment: 20 | PROFILE: "dev" 21 | CONFIGSERVER_URI: "http://configserver:8888" 22 | CONFIGSERVER_PORT: "8888" 23 | DATABASESERVER_PORT: "5432" 24 | -------------------------------------------------------------------------------- /confsvr/src/main/resources/config/licensingservice/licensingservice-dev.yml: -------------------------------------------------------------------------------- 1 | spring.jpa.database: "POSTGRESQL" 2 | spring.datasource.platform: "postgres" 3 | spring.jpa.show-sql: "false" 4 | spring.database.driverClassName: "org.postgresql.Driver" 5 | spring.datasource.url: "jdbc:postgresql://database:5432/eagle_eye_dev" 6 | spring.datasource.username: "postgres_dev" 7 | spring.datasource.password: "{cipher}d495ce8603af958b2526967648aa9620b7e834c4eaff66014aa805450736e119" 8 | spring.datasource.testWhileIdle: "true" 9 | spring.datasource.validationQuery: "SELECT 1" 10 | spring.jpa.properties.hibernate.dialect: "org.hibernate.dialect.PostgreSQLDialect" 11 | redis.server: "redis" 12 | redis.port: "6379" 13 | signing.key: "345345fsdfsf5345" 14 | -------------------------------------------------------------------------------- /docker/prod/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | database: 4 | extends: 5 | file: ../common/docker-compose.yml 6 | service: database 7 | environment: 8 | POSTGRES_USER: "postgres_prod" 9 | POSTGRES_PASSWORD: "p0stgr@s_prod" 10 | POSTGRES_DB: "eagle_eye_prod" 11 | configserver: 12 | extends: 13 | file: ../common/docker-compose.yml 14 | service: configserver 15 | licensingservice: 16 | image: ch3-thoughtmechanix/licensing-service 17 | ports: 18 | - "8080:8080" 19 | environment: 20 | PROFILE: "prod" 21 | CONFIGSERVER_URI: "http://configserver:8888" 22 | CONFIGSERVER_PORT: "8888" 23 | DATABASESERVER_PORT: "5432" 24 | -------------------------------------------------------------------------------- /confsvr/src/main/resources/config/licensingservice/licensingservice.yml: -------------------------------------------------------------------------------- 1 | example.property: "I AM IN THE DEFAULT" 2 | spring.jpa.database: "POSTGRESQL" 3 | spring.datasource.platform: "postgres" 4 | spring.jpa.show-sql: "true" 5 | spring.database.driverClassName: "org.postgresql.Driver" 6 | spring.datasource.url: "jdbc:postgresql://database:5432/eagle_eye_local" 7 | spring.datasource.username: "postgres" 8 | spring.datasource.password: "{cipher}4788dfe1ccbe6485934aec2ffeddb06163ea3d616df5fd75be96aadd4df1da91" 9 | spring.datasource.testWhileIdle: "true" 10 | spring.datasource.validationQuery: "SELECT 1" 11 | spring.jpa.properties.hibernate.dialect: "org.hibernate.dialect.PostgreSQLDialect" 12 | redis.server: "redis" 13 | redis.port: "6379" 14 | signing.key: "345345fsdfsf5345" -------------------------------------------------------------------------------- /confsvr/src/main/resources/config/licensingservice/licensingservice-prod.yml: -------------------------------------------------------------------------------- 1 | example.property: "I AM A PROD PROPERTY OVERRIDE" 2 | spring.jpa.database: "POSTGRESQL" 3 | spring.datasource.platform: "postgres" 4 | spring.jpa.show-sql: "true" 5 | spring.database.driverClassName: "org.postgresql.Driver" 6 | spring.datasource.url: "jdbc:postgresql://database:5432/eagle_eye_prod" 7 | spring.datasource.username: "postgres_prod" 8 | spring.datasource.password: "{cipher}217b23d6209b10bd82c49a9df6490670052a9cd9d4403dcc1288db21c35c48ac" 9 | spring.datasource.testWhileIdle: "true" 10 | spring.datasource.validationQuery: "SELECT 1" 11 | spring.jpa.properties.hibernate.dialect: "org.hibernate.dialect.PostgreSQLDialect" 12 | redis.server: "redis" 13 | redis.port: "6379" 14 | signing.key: "345345fsdfsf5345" -------------------------------------------------------------------------------- /docker/common/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | configserver: 4 | image: johncarnell/tmx-confsvr:chapter3 5 | ports: 6 | - "8888:8888" 7 | environment: 8 | ENCRYPT_KEY: "IMSYMMETRIC" 9 | database: 10 | image: postgres:9.5 11 | ports: 12 | - "5432:5432" 13 | environment: 14 | POSTGRES_USER: "postgres" 15 | POSTGRES_PASSWORD: "p0stgr@s" 16 | POSTGRES_DB: "eagle_eye_local" 17 | licensingservice: 18 | image: johncarnell/tmx-licensing-service:chapter3 19 | ports: 20 | - "8080:8080" 21 | environment: 22 | PROFILE: "default" 23 | CONFIGSERVER_URI: "http://configserver:8888" 24 | CONFIGSERVER_PORT: "8888" 25 | DATABASESERVER_PORT: "5432" 26 | ENCRYPT_KEY: "IMSYMMETRIC" 27 | -------------------------------------------------------------------------------- /licensing-service/src/main/docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "********************************************************" 4 | echo "Waiting for the configuration server to start on port $CONFIGSERVER_PORT" 5 | echo "********************************************************" 6 | while ! `nc -z configserver $CONFIGSERVER_PORT `; do sleep 3; done 7 | echo ">>>>>>>>>>>> Configuration Server has started" 8 | 9 | echo "********************************************************" 10 | echo "Waiting for the database server to start on port $DATABASESERVER_PORT" 11 | echo "********************************************************" 12 | while ! `nc -z database $DATABASESERVER_PORT`; do sleep 3; done 13 | echo ">>>>>>>>>>>> Database Server has started" 14 | 15 | echo "********************************************************" 16 | echo "Starting License Server with Configuration Service : $CONFIGSERVER_URI"; 17 | echo "********************************************************" 18 | java -Dspring.cloud.config.uri=$CONFIGSERVER_URI -Dspring.profiles.active=$PROFILE -jar /usr/local/licensingservice/@project.build.finalName@.jar 19 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/model/Organization.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.model; 2 | 3 | public class Organization { 4 | String id; 5 | String name; 6 | String contactName; 7 | String contactEmail; 8 | String contactPhone; 9 | 10 | 11 | public String getId() { 12 | return id; 13 | } 14 | 15 | public void setId(String id) { 16 | this.id = id; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getContactName() { 28 | return contactName; 29 | } 30 | 31 | public void setContactName(String contactName) { 32 | this.contactName = contactName; 33 | } 34 | 35 | public String getContactEmail() { 36 | return contactEmail; 37 | } 38 | 39 | public void setContactEmail(String contactEmail) { 40 | this.contactEmail = contactEmail; 41 | } 42 | 43 | public String getContactPhone() { 44 | return contactPhone; 45 | } 46 | 47 | public void setContactPhone(String contactPhone) { 48 | this.contactPhone = contactPhone; 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.thoughtmechanix 6 | 0.0.1-SNAPSHOT 7 | tmx-parent-pom 8 | pom 9 | 10 | 11 | thoughtmechanix-parent-pom 12 | Parent Pom for the thoughtmechanix project 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.4.4.RELEASE 18 | 19 | 20 | confsvr 21 | licensing-service 22 | 23 | 24 | 25 | 26 | com.spotify 27 | docker-maven-plugin 28 | 0.4.10 29 | 30 | java 31 | example 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /licensing-service/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS licenses; 2 | 3 | CREATE TABLE licenses ( 4 | license_id VARCHAR(100) PRIMARY KEY NOT NULL, 5 | organization_id TEXT NOT NULL, 6 | license_type TEXT NOT NULL, 7 | product_name TEXT NOT NULL, 8 | license_max INT NOT NULL, 9 | license_allocated INT, 10 | comment VARCHAR(100)); 11 | 12 | 13 | INSERT INTO licenses (license_id, organization_id, license_type, product_name, license_max, license_allocated) 14 | VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a', 'e254f8c-c442-4ebe-a82a-e2fc1d1ff78a', 'user','customer-crm-co', 100,5); 15 | INSERT INTO licenses (license_id, organization_id, license_type, product_name, license_max, license_allocated) 16 | VALUES ('t9876f8c-c338-4abc-zf6a-ttt1', 'e254f8c-c442-4ebe-a82a-e2fc1d1ff78a', 'user','suitability-plus', 200,189); 17 | INSERT INTO licenses (license_id, organization_id, license_type, product_name, license_max, license_allocated) 18 | VALUES ('38777179-7094-4200-9d61-edb101c6ea84', '442adb6e-fa58-47f3-9ca2-ed1fecdfe86c', 'user','HR-PowerSuite', 100,4); 19 | INSERT INTO licenses (license_id, organization_id, license_type, product_name, license_max, license_allocated) 20 | VALUES ('08dbe05-606e-4dad-9d33-90ef10e334f9', '442adb6e-fa58-47f3-9ca2-ed1fecdfe86c', 'core-prod','WildCat Application Gateway', 16,16); -------------------------------------------------------------------------------- /confsvr/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This is the core configuration for a configuration service. I have two examples here: 3 | # 4 | # - A configuration service which completelty loads the configuration for the services 5 | # from the local file server of the config service. This should only be used for 6 | # demonstration purposes or for a small application with a limited number of services. 7 | # 8 | # - A configuraton service that uses a git-based repository to read the files from 9 | # 10 | 11 | 12 | #################################### 13 | server: 14 | port: 8888 15 | spring: 16 | cloud: 17 | config: 18 | server: 19 | encrypt.enabled: false 20 | git: 21 | uri: https://github.com/carnellj/config-repo/ 22 | searchPaths: licensingservice,organizationservice 23 | username: native-cloud-apps 24 | password: 0ffended 25 | 26 | 27 | #### 28 | #Classpath and file-based solution 29 | #### 30 | 31 | #server: 32 | # port: 8888 33 | #spring: 34 | # profiles: 35 | # active: native 36 | # cloud: 37 | # config: 38 | # server: 39 | # native: 40 | # searchLocations: file:///confsvr/src/main/resources/config/licensingservice, 41 | # file://confsvr/src/main/resources/config/organizationservice 42 | ### #searchLocations: classpath:config/,classpath:config/licensingservice 43 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/services/LicenseService.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.services; 2 | 3 | import com.thoughtmechanix.licenses.config.ServiceConfig; 4 | import com.thoughtmechanix.licenses.model.License; 5 | import com.thoughtmechanix.licenses.repository.LicenseRepository; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | @Service 13 | public class LicenseService { 14 | 15 | @Autowired 16 | private LicenseRepository licenseRepository; 17 | 18 | @Autowired 19 | ServiceConfig config; 20 | 21 | public License getLicense(String organizationId,String licenseId) { 22 | License license = licenseRepository.findByOrganizationIdAndLicenseId(organizationId, licenseId); 23 | return license.withComment(config.getExampleProperty()); 24 | } 25 | 26 | public List getLicensesByOrg(String organizationId){ 27 | return licenseRepository.findByOrganizationId( organizationId ); 28 | } 29 | 30 | public void saveLicense(License license){ 31 | license.withId( UUID.randomUUID().toString()); 32 | 33 | licenseRepository.save(license); 34 | 35 | } 36 | 37 | public void updateLicense(License license){ 38 | licenseRepository.save(license); 39 | } 40 | 41 | public void deleteLicense(License license){ 42 | licenseRepository.delete( license.getLicenseId()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | cache: 3 | directories: 4 | - $HOME/.m2 5 | jdk: 6 | - oraclejdk8 7 | sudo: required 8 | services: 9 | - docker 10 | notifications: 11 | slack: teamcarnell:zhTADgjsb7yJ5RPEd7LPNFwI 12 | email: 13 | - carnell28@gmail.com 14 | on_success: always 15 | on_failure: always 16 | env: 17 | global: 18 | - secure: trCh0N1EO2q8LpFeM3FKenduQrctYVPBbd41MvgcaAvFImykJshwvmF/GhOzlzh5s3tDRRxS+UROC40HEkwQKVyEIceYMQPxDqiU+juUjtXg7aVCpCMJDlWHBgC+vW3sJzDmhBvmPmChNfoHQJjiBD6PredQ/w1/ORNb99b49q6ZKWU9myA3jnu45mjOiJDrQ/Is1eZ2jCYucVQZWdjpmioUWoIEGRQ/q25pcQxH3QYUU7QsuzM52wTu1uCgWrSEobRP3qHC2+Y7XA3+MHIfxFivcIvJVFgJ+dCPjq/OWnvxqfazdZOtWlj57Fu3vOCuSmAhmqNpaCm7IwynXiVJdlUzm4W0/827WLwqKs1xWQOf1Hg+za4HTBxnFIySMMPOK3f1nK9RvAskP62tUGihOs/gkzNsY2h1oXXKcphe5zmmhIhv9fhGPXIqv2Ic8nOWnpEVj1TqOMSRcW4dSpnsFOpuP1cfaUjWrLGoHq4TSkjUBKDaYZI+0+MHB9j2gPypFKN407tzDLFm5JNm1BZZfLNmrPdqlMmyogOUKPIqY6ImiieQ1xjv4oZmn21+KrLjd3ujqnON0LYSqIPsHLjQfqcdURrzXQobo8lG5AYqsIfKTxPmNZgKtfO6Qp6+xWZjTsnr0Mh7O/H20U3vE0JV6xxG6ct2P64k9fjcaDiGt1A= 19 | - secure: E6qQL7geK3xHc0d6c7AvfXLtXnjp7DgfspmyUIJPVJycx678xctgbr+JeWtvv40h/7mkUtS8FG4K/9n421b//6sOImYvjAp1Lgsu1IjBMoLZLgX3hFy7tA2yNQIOKZurB7mWDNH33Cpz2F+A5o+Cgjje2F+SxPW0udInba6Emkj6bNoVUoF87hActwCtncSNrQumhr8WvOJ4VPeUuaB/FVQ8NUdAFar9MT1EQZPLdSpiMm/fo0TYHP0CFCNr9/MeGUDEvAGlPqIxr+8WN7xahWTSfcPYZ2eUQiR8Gd76TrRlobCw4p6TJE2IKHGYYNhULOvU4j5ugfEIZT0smNhscRpJjjjmis6s/Y8D0Wxx25c/kY0rOx5lUN6SODmBAm8W7F0Z/G2jjaJUE05jloQ8fhVX4taoCt1+XPaFPxx/T+NjsOkCzmFJ9aUjlMWLwA41eZuyr+rWPbVGpdOeUhkqIs56qAMDEfXqCNaZ1UV0mlQUdDtcuTBlutdl1jxu0ggJaVcDfNpuyVyMmwLH3nMGeJJLXGnrRUGk0sHigiWEAPTGA8gY+3wOs+ov7Zhbl6mUYXJgI1IwingiN43v/tAhlAJnuIkbU5npbppKySO8YlUEu458cJX8lrTvjmduCmW/m94j7EtPwaJ205X6oEzIm5ahMiphde+PNYFiWR19fAU= 20 | script: 21 | - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD 22 | - mvn clean package docker:build 23 | - docker push johncarnell/tmx-licensing-service:chapter3 24 | - docker push johncarnell/tmx-confsvr:chapter3 25 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/controllers/LicenseServiceController.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.controllers; 2 | 3 | import com.thoughtmechanix.licenses.model.License; 4 | import com.thoughtmechanix.licenses.services.LicenseService; 5 | import com.thoughtmechanix.licenses.config.ServiceConfig; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.ResponseStatus; 14 | 15 | import java.util.List; 16 | 17 | @RestController 18 | @RequestMapping(value="v1/organizations/{organizationId}/licenses") 19 | public class LicenseServiceController { 20 | @Autowired 21 | private LicenseService licenseService; 22 | 23 | @Autowired 24 | private ServiceConfig serviceConfig; 25 | 26 | @RequestMapping(value="/",method = RequestMethod.GET) 27 | public List getLicenses( @PathVariable("organizationId") String organizationId) { 28 | 29 | return licenseService.getLicensesByOrg(organizationId); 30 | } 31 | 32 | @RequestMapping(value="/{licenseId}",method = RequestMethod.GET) 33 | public License getLicenses( @PathVariable("organizationId") String organizationId, 34 | @PathVariable("licenseId") String licenseId) { 35 | 36 | return licenseService.getLicense(organizationId,licenseId); 37 | } 38 | 39 | @RequestMapping(value="{licenseId}",method = RequestMethod.PUT) 40 | public String updateLicenses( @PathVariable("licenseId") String licenseId) { 41 | return String.format("This is the put"); 42 | } 43 | 44 | @RequestMapping(value="/",method = RequestMethod.POST) 45 | public void saveLicenses(@RequestBody License license) { 46 | licenseService.saveLicense(license); 47 | } 48 | 49 | @RequestMapping(value="{licenseId}",method = RequestMethod.DELETE) 50 | @ResponseStatus(HttpStatus.NO_CONTENT) 51 | public String deleteLicenses( @PathVariable("licenseId") String licenseId) { 52 | return String.format("This is the Delete"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | Welcome to Spring Microservices in Action, Chapter 3. Chapter 3 introduces the Spring Cloud Config service and how you can use it managed the configuration of your microservices. By the time you are done reading this chapter you will have built and/or deployed: 3 | 4 | 1. A Spring Cloud Config server that is deployed as Docker container and can manage a services configuration information using a file system or GitHub-based repository. 5 | 2. A organization service that will manage organization data used within EagleEye. 6 | 3. A licensing service that will manage licensing data used within EagleEye. 7 | 4. A Postgres SQL database used to hold the data for these two services. 8 | 9 | # Software needed 10 | 1. Apache Maven (http://maven.apache.org). I used version 3.3.9 of the Maven. I chose Maven because, while other build tools like Gradle are extremely popular, Maven is still the pre-dominate build tool in use in the Java ecosystem. All of the code examples in this book have been compiled with Java version 1.8. 11 | 2. Docker (http://docker.com). I built the code examples in this book using Docker V1.12 and above. I am taking advantage of the embedded DNS server in Docker that came out in release V1.11. New Docker releases are constantly coming out so it's release version you are using may change on a regular basis. 12 | 3. Git Client (http://git-scm.com). All of the source code for this book is stored in a GitHub repository. For the book, I used version 2.8.4 of the git client. 13 | 14 | # Building the Docker Images for Chapter 3 15 | To build the code examples for Chapter 3 as a docker image, open a command-line window change to the directory where you have downloaded the chapter 3 source code. 16 | 17 | Run the following maven command. This command will execute the [Spotify docker plugin](https://github.com/spotify/docker-maven-plugin) defined in the pom.xml file. 18 | 19 | **mvn clean package docker:build** 20 | 21 | This is the first chapter we will have multiple Spring projects that need to be be built and compiled. Running the above command at the root of the project directory will build all of the projects. If everything builds successfully you should see a message indicating that the build was successful. 22 | 23 | # Running the services in Chapter 3 24 | 25 | Now we are going to use docker-compose to start the actual image. To start the docker image, 26 | change to the directory containing your chapter 3 source code. Issue the following docker-compose command: 27 | 28 | **docker-compose -f docker/common/docker-compose.yml up** 29 | 30 | If everything starts correctly you should see a bunch of Spring Boot information fly by on standard out. At this point all of the services needed for the chapter code examples will be running. 31 | -------------------------------------------------------------------------------- /licensing-service/src/main/java/com/thoughtmechanix/licenses/model/License.java: -------------------------------------------------------------------------------- 1 | package com.thoughtmechanix.licenses.model; 2 | 3 | 4 | import javax.persistence.Column; 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | 9 | @Entity 10 | @Table(name = "licenses") 11 | public class License{ 12 | @Id 13 | @Column(name = "license_id", nullable = false) 14 | private String licenseId; 15 | 16 | @Column(name = "organization_id", nullable = false) 17 | private String organizationId; 18 | 19 | @Column(name = "product_name", nullable = false) 20 | private String productName; 21 | 22 | @Column(name = "license_type", nullable = false) 23 | private String licenseType; 24 | 25 | @Column(name = "license_max", nullable = false) 26 | private Integer licenseMax; 27 | 28 | @Column(name = "license_allocated", nullable = false) 29 | private Integer licenseAllocated; 30 | 31 | @Column(name="comment") 32 | private String comment; 33 | 34 | 35 | public Integer getLicenseMax() { 36 | return licenseMax; 37 | } 38 | 39 | public void setLicenseMax(Integer licenseMax) { 40 | this.licenseMax = licenseMax; 41 | } 42 | 43 | public Integer getLicenseAllocated() { 44 | return licenseAllocated; 45 | } 46 | 47 | public void setLicenseAllocated(Integer licenseAllocated) { 48 | this.licenseAllocated = licenseAllocated; 49 | } 50 | 51 | 52 | public String getLicenseId() { 53 | return licenseId; 54 | } 55 | 56 | public void setLicenseId(String licenseId) { 57 | this.licenseId = licenseId; 58 | } 59 | 60 | public String getOrganizationId() { 61 | return organizationId; 62 | } 63 | 64 | public void setOrganizationId(String organizationId) { 65 | this.organizationId = organizationId; 66 | } 67 | 68 | public String getProductName() { 69 | return productName; 70 | } 71 | 72 | public void setProductName(String productName) { 73 | this.productName = productName; 74 | } 75 | 76 | public String getLicenseType() { 77 | return licenseType; 78 | } 79 | 80 | public void setLicenseType(String licenseType) { 81 | this.licenseType = licenseType; 82 | } 83 | 84 | public String getComment() { 85 | return comment; 86 | } 87 | 88 | public void setComment(String comment) { 89 | this.comment = comment; 90 | } 91 | 92 | public License withId(String id){ 93 | this.setLicenseId(id); 94 | return this; 95 | } 96 | 97 | public License withOrganizationId(String organizationId){ 98 | this.setOrganizationId(organizationId); 99 | return this; 100 | } 101 | 102 | public License withProductName(String productName){ 103 | this.setProductName(productName); 104 | return this; 105 | } 106 | 107 | public License withLicenseType(String licenseType){ 108 | this.setLicenseType(licenseType); 109 | return this; 110 | } 111 | 112 | public License withLicenseMax(Integer licenseMax){ 113 | this.setLicenseMax(licenseMax); 114 | return this; 115 | } 116 | 117 | public License withLicenseAllocated(Integer licenseAllocated){ 118 | this.setLicenseAllocated(licenseAllocated); 119 | return this; 120 | } 121 | 122 | public License withComment(String comment){ 123 | this.setComment(comment); 124 | return this; 125 | } 126 | 127 | 128 | 129 | } 130 | -------------------------------------------------------------------------------- /confsvr/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.thoughtmechanix 6 | configurationserver 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | Config Server 11 | Config Server demo project 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 1.4.4.RELEASE 17 | 18 | 19 | 20 | 21 | org.springframework.cloud 22 | spring-cloud-dependencies 23 | Camden.SR5 24 | pom 25 | import 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-config-server 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-config 39 | 40 | 41 | 42 | 43 | 44 | UTF-8 45 | com.thoughtmechanix.confsvr.ConfigServerApplication 46 | 1.8 47 | johncarnell/tmx-confsvr 48 | chapter3 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | maven-resources-plugin 57 | 58 | 59 | copy-resources 60 | 61 | validate 62 | 63 | copy-resources 64 | 65 | 66 | ${basedir}/target/dockerfile 67 | 68 | 69 | src/main/docker 70 | true 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | com.spotify 79 | docker-maven-plugin 80 | 0.4.10 81 | 82 | ${docker.image.name}:${docker.image.tag} 83 | ${basedir}/target/dockerfile 84 | 85 | 86 | / 87 | ${project.build.directory} 88 | ${project.build.finalName}.jar 89 | 90 | 91 | 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-maven-plugin 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /licensing-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.thoughtmechanix 6 | licensing-service 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | Eagle Eye Licensing Service 11 | Licensing Service 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 1.4.4.RELEASE 17 | 18 | 19 | 20 | 21 | org.springframework.cloud 22 | spring-cloud-dependencies 23 | Camden.SR5 24 | pom 25 | import 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-web 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-actuator 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-config 46 | 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-config-client 51 | 52 | 53 | com.h2database 54 | h2 55 | 56 | 57 | 58 | postgresql 59 | postgresql 60 | 9.1-901.jdbc4 61 | 62 | 63 | org.springframework.security 64 | spring-security-rsa 65 | 66 | 67 | 68 | 69 | UTF-8 70 | 1.8 71 | UTF-8 72 | com.thoughtmechanix.licenses.Application 73 | johncarnell/tmx-licensing-service 74 | chapter3 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | maven-resources-plugin 83 | 84 | 85 | copy-resources 86 | 87 | validate 88 | 89 | copy-resources 90 | 91 | 92 | ${basedir}/target/dockerfile 93 | 94 | 95 | src/main/docker 96 | true 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | com.spotify 105 | docker-maven-plugin 106 | 0.4.10 107 | 108 | ${docker.image.name}:${docker.image.tag} 109 | ${basedir}/target/dockerfile 110 | 111 | 112 | / 113 | ${project.build.directory} 114 | ${project.build.finalName}.jar 115 | 116 | 117 | 118 | 119 | 120 | org.springframework.boot 121 | spring-boot-maven-plugin 122 | 123 | 124 | 125 | 126 | --------------------------------------------------------------------------------