diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..0c07dd9 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,105 @@ +version: 2 +jobs: + build: + docker: + - image: circleci/openjdk:8u171-jdk + working_directory: ~/repo + environment: + MAVEN_OPTS: -Xmx3200m + steps: + - checkout + - restore_cache: + keys: + - v1-dependencies-{{ checksum "pom.xml" }} + - v1-dependencies- + - run: mvn dependency:go-offline + - save_cache: + paths: + - ~/.m2 + key: v1-dependencies-{{ checksum "pom.xml" }} + - run: mvn package + - run: + name: Codecov + command: | + bash <(curl -s https://codecov.io/bash) + - persist_to_workspace: + root: target + paths: + - config.jar + deploy_registry: + docker: + - image: docker:18.06.1-ce-git + working_directory: ~/repo + steps: + - checkout + - setup_remote_docker + - attach_workspace: + at: target + - run: + name: Docker build and push + command: | + docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} + docker build \ + --build-arg COMMIT_REF=${CIRCLE_SHA1} \ + --build-arg BUILD_DATE=`date -u +”%Y-%m-%dT%H:%M:%SZ”` \ + -t ${SERVICE_NAME} . + docker tag ${SERVICE_NAME} ${DOCKER_USER}/${IMAGE_NAME}:${CIRCLE_SHA1} + docker tag ${SERVICE_NAME} ${DOCKER_USER}/${IMAGE_NAME}:latest + docker push ${DOCKER_USER}/${IMAGE_NAME}:${CIRCLE_SHA1} + docker push ${DOCKER_USER}/${IMAGE_NAME}:latest + deploy_gcp: + docker: + - image: google/cloud-sdk + working_directory: ~/repo + steps: + - checkout + - attach_workspace: + at: target + - run: + name: Setup Google Cloud SDK + command: | + echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json + gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json + gcloud --quiet config set project ${GOOGLE_PROJECT_ID} + gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} + gcloud --quiet container clusters get-credentials ${GOOGLE_CLUSTER_NAME} + - setup_remote_docker + - run: + name: Docker build and push + command: | + docker build \ + --build-arg COMMIT_REF=${CIRCLE_SHA1} \ + --build-arg BUILD_DATE=`date -u +”%Y-%m-%dT%H:%M:%SZ”` \ + -t ${SERVICE_NAME} . + docker tag ${SERVICE_NAME} us.gcr.io/${GOOGLE_PROJECT_ID}/${IMAGE_NAME}:${CIRCLE_SHA1} + gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://us.gcr.io + docker push us.gcr.io/${GOOGLE_PROJECT_ID}/${IMAGE_NAME}:${CIRCLE_SHA1} + - run: + name: Deploy to Kubernetes + command: | + kubectl patch deployment "$SERVICE_NAME" -p '{"spec":{"template":{"spec":{"containers":[{"name":"'"$SERVICE_NAME"'","image":"us.gcr.io/'"$GOOGLE_PROJECT_ID"'/'"$IMAGE_NAME"':'"$CIRCLE_SHA1"'"}]}}}}' +workflows: + version: 2 + test_build_and_deploy: + jobs: + - build + - deploy_registry: + requires: + - build + filters: + branches: + only: master + - request-testing: + type: approval + requires: + - build + filters: + branches: + only: master + - deploy_gcp: + requires: + - build + - request-testing + filters: + branches: + only: master \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..790fc0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Intellij +.idea/ +*.iml +*.iws + +# Mac +.DS_Store + +# Maven +log/ +target/ + +# Eclipse +**/*.project +**/*.classpath +**/*.settings \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..916d25a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM java:8-jre-alpine + +ENV APP_COMMIT_REF=${COMMIT_REF} \ + APP_BUILD_DATE=${BUILD_DATE} + +ADD ./target/config.jar /app/ +CMD ["java", "-Xmx200m", "-jar", "/app/config.jar"] + +HEALTHCHECK --interval=30s --timeout=30s CMD curl -f http://localhost:8888/actuator/health || exit 1 + +EXPOSE 8888 \ No newline at end of file diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..f290e94 --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Alexander Lukyanchikov, http://sqshq.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dfb50e6 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Piggy Metrics (Kubernetes) - Config service + +[![CircleCI](https://circleci.com/gh/afermon/PiggyMetrics-config-service.svg?style=svg)](https://circleci.com/gh/afermon/PiggyMetrics-config-service) [![codecov](https://codecov.io/gh/afermon/PiggyMetrics-config-service/branch/master/graph/badge.svg)](https://codecov.io/gh/afermon/PiggyMetrics-config-service) [![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/afermon/PiggyMetrics-config-service/blob/master/LICENCE) + +[Spring Cloud Config](http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html) is horizontally scalable centralized configuration service for distributed systems. It uses a pluggable repository layer that currently supports local storage, Git, and Subversion. + +In this project, I use `native profile`, which simply loads config files from the local classpath. You can see `shared` directory in [Config service resources](https://github.com/sqshq/PiggyMetrics/tree/master/config/src/main/resources). Now, when Notification-service requests it's configuration, Config service responses with `shared/notification-service.yml` and `shared/application.yml` (which is shared between all client applications). + +For more information please refer to the main repository [afermon/PiggyMetrics-Kubernetes](https://github.com/afermon/PiggyMetrics-Kubernetes) + +## Refereces +* Forked from [sqshq/PiggyMetrics](https://github.com/sqshq/PiggyMetrics) \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2ae6239 --- /dev/null +++ b/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + config + 1.0.0-SNAPSHOT + jar + + config + Configuration Server + + + com.piggymetrics + piggymetrics + 1.0-SNAPSHOT + + + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.boot + spring-boot-starter-security + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + config + + + + + + diff --git a/src/main/java/com/piggymetrics/config/ConfigApplication.java b/src/main/java/com/piggymetrics/config/ConfigApplication.java new file mode 100644 index 0000000..26f58f2 --- /dev/null +++ b/src/main/java/com/piggymetrics/config/ConfigApplication.java @@ -0,0 +1,14 @@ +package com.piggymetrics.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigApplication.class, args); + } +} diff --git a/src/main/java/com/piggymetrics/config/SecurityConfig.java b/src/main/java/com/piggymetrics/config/SecurityConfig.java new file mode 100644 index 0000000..c6fd3c7 --- /dev/null +++ b/src/main/java/com/piggymetrics/config/SecurityConfig.java @@ -0,0 +1,24 @@ +package com.piggymetrics.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +/** + * @author cdov + */ +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable(); + http + .authorizeRequests() + .antMatchers("/actuator/**").permitAll() + .anyRequest().authenticated() + .and() + .httpBasic() + ; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..772c904 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,15 @@ +spring: + cloud: + config: + server: + native: + search-locations: classpath:/shared + profiles: + active: native + security: + user: + password: ${CONFIG_SERVICE_PASSWORD} + +server: + port: 8888 + diff --git a/src/main/resources/shared/account-service.yml b/src/main/resources/shared/account-service.yml new file mode 100644 index 0000000..209425d --- /dev/null +++ b/src/main/resources/shared/account-service.yml @@ -0,0 +1,26 @@ +security: + oauth2: + client: + clientId: account-service + clientSecret: ${ACCOUNT_SERVICE_PASSWORD} + accessTokenUri: http://auth-service:5000/uaa/oauth/token + grant-type: client_credentials + scope: server + +spring: + data: + mongodb: + host: account-mongodb + username: user + password: ${MONGODB_PASSWORD} + database: piggymetrics + port: 27017 + +server: + servlet: + context-path: /accounts + port: 6000 + +feign: + hystrix: + enabled: true \ No newline at end of file diff --git a/src/main/resources/shared/application.yml b/src/main/resources/shared/application.yml new file mode 100644 index 0000000..6b2c05e --- /dev/null +++ b/src/main/resources/shared/application.yml @@ -0,0 +1,27 @@ +logging: + level: + org.springframework.security: INFO + +hystrix: + command: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 10000 + +eureka: + instance: + prefer-ip-address: true + client: + serviceUrl: + defaultZone: http://registry:8761/eureka/ + +security: + oauth2: + resource: + user-info-uri: http://auth-service:5000/uaa/users/current + +spring: + rabbitmq: + host: rabbitmq \ No newline at end of file diff --git a/src/main/resources/shared/auth-service.yml b/src/main/resources/shared/auth-service.yml new file mode 100644 index 0000000..137c067 --- /dev/null +++ b/src/main/resources/shared/auth-service.yml @@ -0,0 +1,13 @@ +spring: + data: + mongodb: + host: auth-mongodb + username: user + password: ${MONGODB_PASSWORD} + database: piggymetrics + port: 27017 + +server: + servlet: + context-path: /uaa + port: 5000 diff --git a/src/main/resources/shared/gateway.yml b/src/main/resources/shared/gateway.yml new file mode 100644 index 0000000..bceb918 --- /dev/null +++ b/src/main/resources/shared/gateway.yml @@ -0,0 +1,45 @@ +hystrix: + command: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 20000 + +ribbon: + ReadTimeout: 20000 + ConnectTimeout: 20000 + +zuul: + ignoredServices: '*' + host: + connect-timeout-millis: 20000 + socket-timeout-millis: 20000 + + routes: + auth-service: + path: /uaa/** + url: http://auth-service:5000 + stripPrefix: false + sensitiveHeaders: + + account-service: + path: /accounts/** + serviceId: account-service + stripPrefix: false + sensitiveHeaders: + + statistics-service: + path: /statistics/** + serviceId: statistics-service + stripPrefix: false + sensitiveHeaders: + + notification-service: + path: /notifications/** + serviceId: notification-service + stripPrefix: false + sensitiveHeaders: + +server: + port: 4000 diff --git a/src/main/resources/shared/monitoring.yml b/src/main/resources/shared/monitoring.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/shared/notification-service.yml b/src/main/resources/shared/notification-service.yml new file mode 100644 index 0000000..65065e3 --- /dev/null +++ b/src/main/resources/shared/notification-service.yml @@ -0,0 +1,50 @@ +security: + oauth2: + client: + clientId: notification-service + clientSecret: ${NOTIFICATION_SERVICE_PASSWORD} + accessTokenUri: http://auth-service:5000/uaa/oauth/token + grant-type: client_credentials + scope: server + +server: + servlet: + context-path: /notifications + port: 8000 + +remind: + cron: 0 0 0 * * * + email: + text: "Hey, {0}! We''ve missed you here on PiggyMetrics. It''s time to check your budget statistics.\r\n\r\nCheers,\r\nPiggyMetrics team" + subject: PiggyMetrics reminder + +backup: + cron: 0 0 12 * * * + email: + text: "Howdy, {0}. Your account backup is ready.\r\n\r\nCheers,\r\nPiggyMetrics team" + subject: PiggyMetrics account backup + attachment: backup.json + +spring: + data: + mongodb: + host: notification-mongodb + username: user + password: ${MONGODB_PASSWORD} + database: piggymetrics + port: 27017 + mail: + host: ${NOTIFICATION_EMAIL_HOST} + port: ${NOTIFICATION_EMAIL_PORT} + username: ${NOTIFICATION_EMAIL_USER} + password: ${NOTIFICATION_EMAIL_PASS} + properties: + mail: + smtp: + auth: true + socketFactory: + port: ${NOTIFICATION_EMAIL_PORT} + class: javax.net.ssl.SSLSocketFactory + fallback: false + ssl: + enable: true diff --git a/src/main/resources/shared/registry.yml b/src/main/resources/shared/registry.yml new file mode 100644 index 0000000..b83497d --- /dev/null +++ b/src/main/resources/shared/registry.yml @@ -0,0 +1,2 @@ +server: + port: 8761 \ No newline at end of file diff --git a/src/main/resources/shared/statistics-service.yml b/src/main/resources/shared/statistics-service.yml new file mode 100644 index 0000000..a460f90 --- /dev/null +++ b/src/main/resources/shared/statistics-service.yml @@ -0,0 +1,25 @@ +security: + oauth2: + client: + clientId: statistics-service + clientSecret: ${STATISTICS_SERVICE_PASSWORD} + accessTokenUri: http://auth-service:5000/uaa/oauth/token + grant-type: client_credentials + scope: server + +spring: + data: + mongodb: + host: statistics-mongodb + username: user + password: ${MONGODB_PASSWORD} + database: piggymetrics + port: 27017 + +server: + servlet: + context-path: /statistics + port: 7000 + +rates: + url: https://api.exchangeratesapi.io \ No newline at end of file diff --git a/src/main/resources/shared/turbine-stream-service.yml b/src/main/resources/shared/turbine-stream-service.yml new file mode 100644 index 0000000..e69de29