├── gradle.properties ├── zwitscher-edge ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-test.properties │ │ │ └── bootstrap.properties │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── edge │ │ │ └── ZwitscherEdgeApplicationTests.java │ └── main │ │ ├── docker │ │ ├── zwitscher-edge.conf │ │ └── zwitscher-edge.sh │ │ ├── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── edge │ │ └── ZwitscherEdgeApplication.java ├── Dockerfile ├── build.gradle ├── marathon-zwitscher-edge.json └── k8s-zwitscher-edge.yml ├── zwitscher-monitor ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-test.properties │ │ │ └── bootstrap.properties │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── monitor │ │ │ └── ZwitscherMonitorApplicationTests.java │ └── main │ │ ├── docker │ │ ├── zwitscher-monitor.conf │ │ └── zwitscher-monitor.sh │ │ ├── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── monitor │ │ └── ZwitscherMonitorApplication.java ├── Dockerfile ├── build.gradle ├── marathon-zwitscher-monitor.json └── k8s-zwitscher-monitor.yml ├── zwitscher-board ├── src │ ├── test │ │ ├── resources │ │ │ ├── bootstrap.properties │ │ │ └── application-test.properties │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── board │ │ │ └── ZwitscherBoardApplicationTests.java │ └── main │ │ ├── docker │ │ ├── zwitscher-board.conf │ │ └── zwitscher-board.sh │ │ ├── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ └── templates │ │ │ └── index.html │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── board │ │ ├── domain │ │ ├── Zwitscher.java │ │ ├── Quote.java │ │ ├── QuoteRepository.java │ │ └── ZwitscherRepository.java │ │ ├── ZwitscherBoardApplication.java │ │ └── web │ │ └── ZwitscherBoardController.java ├── Dockerfile ├── build.gradle ├── marathon-zwitscher-board.json └── k8s-zwitscher-board.yml ├── zwitscher-service ├── src │ ├── test │ │ ├── resources │ │ │ ├── bootstrap.properties │ │ │ └── application-test.properties │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── service │ │ │ ├── quote │ │ │ └── RandomQuoteTest.java │ │ │ └── ZwitscherServiceApplicationTests.java │ └── main │ │ ├── docker │ │ ├── zwitscher-service.conf │ │ └── zwitscher-service.sh │ │ ├── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── service │ │ ├── tweet │ │ ├── ZwitscherMessage.java │ │ ├── ZwitscherRepository.java │ │ ├── SocialZwitscherConfiguration.java │ │ ├── SocialZwitscherRepository.java │ │ └── ZwitscherController.java │ │ ├── quote │ │ ├── RandomQuote.java │ │ ├── RandomQuoteFallback.java │ │ ├── QuotesOnDesignClient.java │ │ ├── RandomQuoteController.java │ │ └── QuotesOnDesignConfiguration.java │ │ └── ZwitscherServiceApplication.java ├── Dockerfile ├── build.gradle ├── marathon-zwitscher-service.json └── k8s-zwitscher-service.yml ├── zwitscher.png ├── zwitscher-eureka ├── src │ ├── main │ │ ├── resources │ │ │ ├── bootstrap.yml │ │ │ └── application.yml │ │ ├── docker │ │ │ ├── zwitscher-eureka.sh │ │ │ └── zwitscher-eureka.conf │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── eureka │ │ │ └── ZwitscherEurekaApplication.java │ └── test │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── eureka │ │ └── ZwitscherEurekaApplicationTests.java ├── build.gradle ├── Dockerfile ├── marathon-zwitscher-eureka.json └── k8s-zwitscher-eureka.yml ├── zwitscher-config ├── src │ ├── main │ │ ├── docker │ │ │ ├── zwitscher-config.conf │ │ │ ├── zwitscher-config.sh │ │ │ └── jce_policy-8.tar.gz │ │ ├── resources │ │ │ ├── server.jks │ │ │ ├── bootstrap.yml │ │ │ ├── config │ │ │ │ ├── zwitscher-board.yml │ │ │ │ ├── zwitscher-board-docker.yml │ │ │ │ ├── zwitscher-monitor.yml │ │ │ │ ├── zwitscher-edge.yml │ │ │ │ └── zwitscher-service.yml │ │ │ └── application.yml │ │ └── java │ │ │ └── de │ │ │ └── qaware │ │ │ └── cloud │ │ │ └── nativ │ │ │ └── zwitscher │ │ │ └── config │ │ │ └── ZwitscherConfigApplication.java │ └── test │ │ └── java │ │ └── de │ │ └── qaware │ │ └── cloud │ │ └── nativ │ │ └── zwitscher │ │ └── config │ │ └── ZwitscherConfigApplicationTests.java ├── build.gradle ├── Dockerfile ├── marathon-zwitscher-config.json └── k8s-zwitscher-config.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore ├── k8s-setup-vagrant.sh ├── .travis.yml ├── k8s-setup-gce.sh ├── k8s-setup-aws.sh ├── marathon-deploy-all.sh ├── LICENSE ├── contributing.json ├── gradlew.bat ├── docker-compose.yml ├── gradlew ├── k8s-zwitscher.yml └── README.md /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=true 2 | -------------------------------------------------------------------------------- /zwitscher-edge/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /zwitscher-monitor/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /zwitscher-edge/src/test/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.failFast=false -------------------------------------------------------------------------------- /zwitscher-board/src/test/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.failFast=false -------------------------------------------------------------------------------- /zwitscher-monitor/src/test/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.failFast=false -------------------------------------------------------------------------------- /zwitscher-service/src/test/resources/bootstrap.properties: -------------------------------------------------------------------------------- 1 | spring.cloud.config.failFast=false -------------------------------------------------------------------------------- /zwitscher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qaware/cloud-native-zwitscher/HEAD/zwitscher.png -------------------------------------------------------------------------------- /zwitscher-eureka/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-eureka -------------------------------------------------------------------------------- /zwitscher-eureka/src/main/docker/zwitscher-eureka.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /opt/zwitscher-eureka/zwitscher-eureka.jar -------------------------------------------------------------------------------- /zwitscher-edge/src/main/docker/zwitscher-edge.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-edge -------------------------------------------------------------------------------- /zwitscher-board/src/main/docker/zwitscher-board.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-board -------------------------------------------------------------------------------- /zwitscher-config/src/main/docker/zwitscher-config.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-config -------------------------------------------------------------------------------- /zwitscher-eureka/src/main/docker/zwitscher-eureka.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-eureka -------------------------------------------------------------------------------- /zwitscher-monitor/src/main/docker/zwitscher-monitor.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-monitor -------------------------------------------------------------------------------- /zwitscher-service/src/main/docker/zwitscher-service.conf: -------------------------------------------------------------------------------- 1 | MODE=run 2 | JAVA_OPTS=-Xmx128m 3 | LOG_FOLDER=/opt/zwitscher-service -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qaware/cloud-native-zwitscher/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /zwitscher-monitor/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Monitoring Server 3 | 4 | server: 5 | port: 8989 6 | -------------------------------------------------------------------------------- /zwitscher-service/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | spring.social.twitter.appId=test 2 | spring.social.twitter.appSecret=test 3 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/docker/zwitscher-board.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$DOCKER_COMPOSE" ]; then sleep 85; fi 3 | /opt/zwitscher-board/zwitscher-board.jar -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/server.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qaware/cloud-native-zwitscher/HEAD/zwitscher-config/src/main/resources/server.jks -------------------------------------------------------------------------------- /zwitscher-edge/src/main/docker/zwitscher-edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$DOCKER_COMPOSE" ]; then sleep 100; fi 3 | /opt/zwitscher-edge/zwitscher-edge.jar -------------------------------------------------------------------------------- /zwitscher-config/src/main/docker/zwitscher-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$DOCKER_COMPOSE" ]; then sleep 10; fi 3 | /opt/zwitscher-config/zwitscher-config.jar -------------------------------------------------------------------------------- /zwitscher-monitor/src/main/docker/zwitscher-monitor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$DOCKER_COMPOSE" ]; then sleep 120; fi 3 | /opt/zwitscher-monitor/zwitscher-monitor.jar -------------------------------------------------------------------------------- /zwitscher-service/src/main/docker/zwitscher-service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$DOCKER_COMPOSE" ]; then sleep 60; fi 3 | /opt/zwitscher-service/zwitscher-service.jar -------------------------------------------------------------------------------- /zwitscher-config/src/main/docker/jce_policy-8.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qaware/cloud-native-zwitscher/HEAD/zwitscher-config/src/main/docker/jce_policy-8.tar.gz -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':zwitscher-eureka' 2 | include ':zwitscher-config' 3 | include ':zwitscher-service' 4 | include ':zwitscher-board' 5 | include ':zwitscher-monitor' 6 | include ':zwitscher-edge' 7 | -------------------------------------------------------------------------------- /zwitscher-board/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | board.title=Zwitscher Board UI Test 2 | board.headline=Random Quote on Design Test 3 | board.zwitscherUrl=http://zwitscher-service/tweets?q={q} -------------------------------------------------------------------------------- /zwitscher-board/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Board UI 3 | 4 | server: 5 | port: 8081 6 | 7 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 30000 -------------------------------------------------------------------------------- /zwitscher-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Service 3 | 4 | server: 5 | port: 8080 6 | 7 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 30000 -------------------------------------------------------------------------------- /zwitscher-eureka/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-eureka' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-starter-eureka-server' 8 | } 9 | -------------------------------------------------------------------------------- /zwitscher-edge/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Zuul Edge Server 3 | 4 | server: 5 | port: 8765 6 | 7 | hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 30000 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ 2 | .idea/ 3 | *.iml 4 | *.iws 5 | *.ipr 6 | 7 | # Maven 8 | target/ 9 | *.versionsBackup 10 | 11 | # Gradle 12 | .gradle/ 13 | build/ 14 | 15 | # OSX 16 | *.DS_Store 17 | 18 | kubernetes.tar.gz 19 | kubernetes/ 20 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Mar 09 01:22:32 CET 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip 7 | -------------------------------------------------------------------------------- /zwitscher-config/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-config' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-config-server' 8 | compile 'org.springframework.cloud:spring-cloud-starter-eureka' 9 | } 10 | -------------------------------------------------------------------------------- /k8s-setup-vagrant.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export KUBERNETES_PROVIDER=vagrant 3 | export NUM_NODES=1 4 | 5 | # export KUBERNETES_MEMORY=2048 6 | # export KUBERNETES_MASTER_MEMORY=1536 7 | # export KUBERNETES_NODE_MEMORY=2048 8 | 9 | export KUBE_ENABLE_CLUSTER_MONITORING=none 10 | 11 | curl -sS https://get.k8s.io | bash 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | env: 7 | - TERM=dumb 8 | 9 | before_cache: 10 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 11 | cache: 12 | directories: 13 | - $HOME/.gradle/caches/ 14 | - $HOME/.gradle/wrapper/ 15 | 16 | before_install: 17 | - chmod +x gradlew 18 | 19 | script: ./gradlew build 20 | -------------------------------------------------------------------------------- /zwitscher-eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Eureka Server 3 | 4 | server: 5 | port: 8761 6 | 7 | management: 8 | context-path: /admin 9 | 10 | endpoints: 11 | info: 12 | enabled: true 13 | shutdown: 14 | enabled: true 15 | health: 16 | enabled: true 17 | sensitive: false 18 | 19 | eureka: 20 | client: 21 | registerWithEureka: false 22 | fetchRegistry: false -------------------------------------------------------------------------------- /k8s-setup-gce.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export KUBE_GCE_ZONE=europe-west1-d 4 | export NUM_NODES=4 5 | export KUBE_GCE_INSTANCE_PREFIX=k8s 6 | 7 | # Disable logging to save resources 8 | export KUBE_ENABLE_CLUSTER_MONITORING=none 9 | export KUBE_ENABLE_NODE_LOGGING=false 10 | export KUBE_ENABLE_CLUSTER_LOGGING=false 11 | 12 | #export KUBE_ENABLE_NODE_AUTOSCALER=true 13 | #export KUBE_AUTOSCALER_MIN_NODES=2 14 | #export KUBE_AUTOSCALER_MAX_NODES=4 15 | 16 | curl -sS https://get.k8s.io | bash 17 | -------------------------------------------------------------------------------- /zwitscher-edge/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-edge 5 | 6 | COPY build/libs/zwitscher-edge-1.1.0.jar /opt/zwitscher-edge/zwitscher-edge.jar 7 | COPY src/main/docker/zwitscher-edge.* /opt/zwitscher-edge/ 8 | 9 | RUN chmod 755 /opt/zwitscher-edge/zwitscher-edge.jar; chmod 755 /opt/zwitscher-edge/zwitscher-edge.sh 10 | 11 | EXPOSE 8765 12 | CMD /opt/zwitscher-edge/zwitscher-edge.sh 13 | -------------------------------------------------------------------------------- /zwitscher-board/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-board 5 | 6 | COPY build/libs/zwitscher-board-1.1.0.jar /opt/zwitscher-board/zwitscher-board.jar 7 | COPY src/main/docker/zwitscher-board.* /opt/zwitscher-board/ 8 | 9 | RUN chmod 755 /opt/zwitscher-board/zwitscher-board.jar; chmod 755 /opt/zwitscher-board/zwitscher-board.sh 10 | 11 | EXPOSE 8081 12 | CMD /opt/zwitscher-board/zwitscher-board.sh 13 | -------------------------------------------------------------------------------- /zwitscher-eureka/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-eureka 5 | 6 | COPY build/libs/zwitscher-eureka-1.1.0.jar /opt/zwitscher-eureka/zwitscher-eureka.jar 7 | COPY src/main/docker/zwitscher-eureka.* /opt/zwitscher-eureka/ 8 | 9 | RUN chmod 755 /opt/zwitscher-eureka/zwitscher-eureka.jar; chmod 755 /opt/zwitscher-eureka/zwitscher-eureka.sh 10 | 11 | EXPOSE 8761 12 | CMD /opt/zwitscher-eureka/zwitscher-eureka.sh -------------------------------------------------------------------------------- /zwitscher-edge/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-edge' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-starter-config' 8 | compile 'org.springframework.cloud:spring-cloud-starter-eureka' 9 | 10 | compile 'org.springframework.boot:spring-boot-starter-aop' 11 | compile 'org.springframework.retry:spring-retry' 12 | 13 | compile 'org.springframework.cloud:spring-cloud-starter-zuul' 14 | compile 'org.springframework.cloud:spring-cloud-starter-hystrix' 15 | } 16 | -------------------------------------------------------------------------------- /zwitscher-monitor/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-monitor 5 | 6 | COPY build/libs/zwitscher-monitor-1.1.0.jar /opt/zwitscher-monitor/zwitscher-monitor.jar 7 | COPY src/main/docker/zwitscher-monitor.* /opt/zwitscher-monitor/ 8 | 9 | RUN chmod 755 /opt/zwitscher-monitor/zwitscher-monitor.jar; chmod 755 /opt/zwitscher-monitor/zwitscher-monitor.sh 10 | 11 | EXPOSE 8989 12 | CMD /opt/zwitscher-monitor/zwitscher-monitor.sh 13 | -------------------------------------------------------------------------------- /zwitscher-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-ibmjava8:8.0-3.10 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-service 5 | 6 | COPY build/libs/zwitscher-service-1.1.0.jar /opt/zwitscher-service/zwitscher-service.jar 7 | COPY src/main/docker/zwitscher-service.* /opt/zwitscher-service/ 8 | 9 | RUN chmod 755 /opt/zwitscher-service/zwitscher-service.jar; chmod 755 /opt/zwitscher-service/zwitscher-service.sh 10 | 11 | EXPOSE 8080 12 | CMD /opt/zwitscher-service/zwitscher-service.sh 13 | -------------------------------------------------------------------------------- /zwitscher-monitor/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-monitor' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-starter-config' 8 | compile 'org.springframework.cloud:spring-cloud-starter-eureka' 9 | 10 | compile 'org.springframework.boot:spring-boot-starter-aop' 11 | compile 'org.springframework.retry:spring-retry' 12 | 13 | compile 'org.springframework.cloud:spring-cloud-starter-hystrix-dashboard' 14 | compile 'org.springframework.cloud:spring-cloud-starter-turbine' 15 | } 16 | -------------------------------------------------------------------------------- /k8s-setup-aws.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export KUBERNETES_PROVIDER=aws 3 | 4 | # Frankfurt 5 | export KUBE_AWS_ZONE=eu-central-1a 6 | export NUM_NODES=4 7 | export MASTER_SIZE=m3.medium 8 | export NODE_SIZE=t2.small 9 | export KUBE_AWS_INSTANCE_PREFIX=k8s 10 | 11 | # Disable logging to save resources 12 | export KUBE_ENABLE_CLUSTER_MONITORING=none 13 | export KUBE_ENABLE_NODE_LOGGING=false 14 | export KUBE_ENABLE_CLUSTER_LOGGING=false 15 | 16 | #export KUBE_ENABLE_NODE_AUTOSCALER=true 17 | #export KUBE_AUTOSCALER_MIN_NODES=2 18 | #export KUBE_AUTOSCALER_MAX_NODES=4 19 | 20 | curl -sS https://get.k8s.io | bash 21 | -------------------------------------------------------------------------------- /zwitscher-edge/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-edge 4 | cloud: 5 | config: 6 | enabled: true 7 | failFast: true 8 | retry: 9 | initialInterval: 1500 10 | maxInterval: 5000 11 | maxAttempts: 5 12 | multiplier: 1.5 13 | discovery: 14 | enabled: true 15 | serviceId: ZWITSCHER-CONFIG 16 | 17 | eureka: 18 | instance: 19 | nonSecurePort: ${server.port:8765} 20 | appGroupName: ZWITSCHER 21 | client: 22 | serviceUrl: 23 | defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ -------------------------------------------------------------------------------- /zwitscher-monitor/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-monitor 4 | cloud: 5 | config: 6 | enabled: true 7 | failFast: true 8 | retry: 9 | initialInterval: 1500 10 | maxInterval: 5000 11 | maxAttempts: 5 12 | multiplier: 1.5 13 | discovery: 14 | enabled: true 15 | serviceId: ZWITSCHER-CONFIG 16 | 17 | eureka: 18 | instance: 19 | nonSecurePort: ${server.port:8989} 20 | appGroupName: ZWITSCHER 21 | client: 22 | serviceUrl: 23 | defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ -------------------------------------------------------------------------------- /zwitscher-service/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-service' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-starter-config' 8 | compile 'org.springframework.cloud:spring-cloud-starter-eureka' 9 | 10 | compile 'org.springframework.boot:spring-boot-starter-aop' 11 | compile 'org.springframework.retry:spring-retry' 12 | 13 | compile 'org.springframework.social:spring-social-twitter' 14 | 15 | compile 'org.springframework.cloud:spring-cloud-starter-feign' 16 | compile 'org.springframework.cloud:spring-cloud-starter-hystrix' 17 | } 18 | -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-config 4 | profiles: 5 | active: native 6 | 7 | encrypt: 8 | failOnError: false 9 | keyStore: 10 | location: classpath:/server.jks 11 | password: ${KEYSTORE_PASSWORD:letmein} # don't use a default in production 12 | alias: configkey 13 | secret: ${KEY_PASSWORD:changeme} # don't use a default in production 14 | 15 | eureka: 16 | instance: 17 | nonSecurePort: ${server.port:8888} 18 | appGroupName: ZWITSCHER 19 | client: 20 | serviceUrl: 21 | defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ -------------------------------------------------------------------------------- /zwitscher-board/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-board 4 | cloud: 5 | config: 6 | enabled: true 7 | failFast: true 8 | retry: 9 | initialInterval: 1500 10 | maxInterval: 5000 11 | maxAttempts: 5 12 | multiplier: 1.5 13 | discovery: 14 | enabled: true 15 | serviceId: ZWITSCHER-CONFIG 16 | 17 | eureka: 18 | instance: 19 | nonSecurePort: ${server.port:8081} 20 | appGroupName: ZWITSCHER 21 | client: 22 | healthcheck: 23 | enabled: true 24 | serviceUrl: 25 | defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ 26 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zwitscher-service 4 | cloud: 5 | config: 6 | enabled: true 7 | failFast: true 8 | retry: 9 | initialInterval: 1500 10 | maxInterval: 5000 11 | maxAttempts: 5 12 | multiplier: 1.5 13 | discovery: 14 | enabled: true 15 | serviceId: ZWITSCHER-CONFIG 16 | 17 | eureka: 18 | instance: 19 | nonSecurePort: ${server.port:8080} 20 | appGroupName: ZWITSCHER 21 | client: 22 | healthcheck: 23 | enabled: true 24 | serviceUrl: 25 | defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ 26 | -------------------------------------------------------------------------------- /zwitscher-board/build.gradle: -------------------------------------------------------------------------------- 1 | jar { 2 | baseName = 'zwitscher-board' 3 | version = "$version" 4 | } 5 | 6 | dependencies { 7 | compile 'org.springframework.cloud:spring-cloud-starter-config' 8 | compile 'org.springframework.cloud:spring-cloud-starter-eureka' 9 | 10 | compile 'org.springframework.boot:spring-boot-starter-aop' 11 | compile 'org.springframework.retry:spring-retry' 12 | 13 | compile 'org.springframework.cloud:spring-cloud-starter-feign' 14 | compile 'org.springframework.cloud:spring-cloud-starter-hystrix' 15 | compile 'org.springframework.cloud:spring-cloud-starter-ribbon' 16 | 17 | compile 'org.springframework.boot:spring-boot-starter-thymeleaf' 18 | compile 'org.springframework.boot:spring-boot-starter-web' 19 | } 20 | -------------------------------------------------------------------------------- /zwitscher-config/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qaware-oss-docker-registry.bintray.io/base/alpine-k8s-openjdk8:8u92 2 | MAINTAINER QAware GmbH 3 | 4 | RUN mkdir -p /opt/zwitscher-config 5 | 6 | COPY build/libs/zwitscher-config-1.1.0.jar /opt/zwitscher-config/zwitscher-config.jar 7 | COPY src/main/docker/zwitscher-config.* /opt/zwitscher-config/ 8 | 9 | RUN chmod 755 /opt/zwitscher-config/zwitscher-config.jar; chmod 755 /opt/zwitscher-config/zwitscher-config.sh 10 | 11 | RUN rm -f /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/local_policy.jar /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/US_export_policy.jar 12 | ADD src/main/docker/jce_policy-8.tar.gz /usr/lib/jvm/java-1.8-openjdk/jre/lib/security 13 | 14 | EXPOSE 8888 15 | CMD /opt/zwitscher-config/zwitscher-config.sh 16 | -------------------------------------------------------------------------------- /zwitscher-eureka/marathon-zwitscher-eureka.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-eureka", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | 8 | "container": { 9 | "type": "DOCKER", 10 | "docker": { 11 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-eureka:1.1.0", 12 | "network": "BRIDGE", 13 | "portMappings": [ 14 | { "hostPort": 8761, "containerPort": 8761, "protocol": "tcp", "servicePort":8761} 15 | ] 16 | } 17 | }, 18 | 19 | "healthChecks": [ 20 | { 21 | "protocol": "HTTP", 22 | "path": "/admin/health", 23 | "intervalSeconds": 10, 24 | "portIndex": 0, 25 | "timeoutSeconds": 10, 26 | "maxConsecutiveFailures": 3 27 | } 28 | ] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/config/zwitscher-board.yml: -------------------------------------------------------------------------------- 1 | board: 2 | title: Zwitscher Board UI 3 | headline: Random Quote on Design 4 | zwitscherUrl: http://zwitscher-service/tweets?q={q} 5 | 6 | endpoints: 7 | info: 8 | enabled: true 9 | shutdown: 10 | enabled: true 11 | health: 12 | enabled: true 13 | sensitive: false 14 | 15 | logging: 16 | level: 17 | com.netflix.discovery: INFO 18 | org.springframework.cloud: INFO 19 | org.springframework.web: DEBUG 20 | de.qaware.cloud.nativ.zwitscher: DEBUG 21 | 22 | management: 23 | context-path: /admin 24 | 25 | eureka: 26 | instance: 27 | # register with IP addresses (required for deployment in Kubernetes?) 28 | preferIpAddress: true 29 | leaseRenewalIntervalInSeconds: 10 30 | statusPageUrlPath: ${management.context-path}/info 31 | healthCheckUrlPath: ${management.context-path}/health -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/config/zwitscher-board-docker.yml: -------------------------------------------------------------------------------- 1 | board: 2 | title: Zwitscher Board UI (Docker) 3 | headline: Random Quote on Design (Docker) 4 | zwitscherUrl: http://zwitscher-service/tweets?q={q} 5 | 6 | endpoints: 7 | info: 8 | enabled: true 9 | shutdown: 10 | enabled: true 11 | health: 12 | enabled: true 13 | sensitive: false 14 | 15 | logging: 16 | level: 17 | com.netflix.discovery: INFO 18 | org.springframework.cloud: INFO 19 | org.springframework.web: DEBUG 20 | de.qaware.cloud.nativ.zwitscher: DEBUG 21 | 22 | management: 23 | context-path: /admin 24 | 25 | eureka: 26 | instance: 27 | # register with IP addresses (required for deployment in Kubernetes?) 28 | preferIpAddress: true 29 | leaseRenewalIntervalInSeconds: 10 30 | statusPageUrlPath: ${management.context-path}/info 31 | healthCheckUrlPath: ${management.context-path}/health -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/config/zwitscher-monitor.yml: -------------------------------------------------------------------------------- 1 | turbine: 2 | appConfig: zwitscher-service,zwitscher-board 3 | instanceUrlSuffix: /admin/hystrix.stream 4 | clusterNameExpression: appGroupName 5 | aggregator: 6 | clusterConfig: ZWITSCHER 7 | 8 | endpoints: 9 | info: 10 | enabled: true 11 | shutdown: 12 | enabled: true 13 | health: 14 | enabled: true 15 | sensitive: false 16 | 17 | logging: 18 | level: 19 | com.netflix.discovery: INFO 20 | com.netflix.turbine: INFO 21 | org.springframework.cloud: INFO 22 | org.springframework.web: INFO 23 | 24 | management: 25 | context-path: /admin 26 | 27 | eureka: 28 | instance: 29 | # register with IP addresses (required for deployment in Kubernetes?) 30 | preferIpAddress: true 31 | leaseRenewalIntervalInSeconds: 10 32 | statusPageUrlPath: ${management.context-path}/info 33 | healthCheckUrlPath: ${management.context-path}/health -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/config/zwitscher-edge.yml: -------------------------------------------------------------------------------- 1 | zuul: 2 | ignoredPatterns: /**/admin/** 3 | routes: 4 | api: 5 | path: /api/** 6 | serviceId: zwitscher-service 7 | stripPrefix: true 8 | web: 9 | path: /** 10 | serviceId: zwitscher-board 11 | 12 | endpoints: 13 | info: 14 | enabled: true 15 | shutdown: 16 | enabled: true 17 | health: 18 | enabled: true 19 | sensitive: false 20 | 21 | logging: 22 | level: 23 | com.netflix.discovery: INFO 24 | org.springframework.cloud: INFO 25 | org.springframework.web: DEBUG 26 | de.qaware.cloud.nativ.zwitscher: DEBUG 27 | 28 | management: 29 | context-path: /admin 30 | 31 | eureka: 32 | instance: 33 | # register with IP addresses (required for deployment in Kubernetes?) 34 | preferIpAddress: true 35 | leaseRenewalIntervalInSeconds: 10 36 | statusPageUrlPath: ${management.context-path}/info 37 | healthCheckUrlPath: ${management.context-path}/health -------------------------------------------------------------------------------- /zwitscher-config/marathon-zwitscher-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-config", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | 8 | "cmd": "/opt/java/latest/bin/java -Xmx256m -Dserver.port=$PORT0 -Deureka.instance.ipAddress=$HOST -jar /opt/zwitscher-config/zwitscher-config.jar", 9 | 10 | "container": { 11 | "type": "DOCKER", 12 | "docker": { 13 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-config:1.1.0", 14 | "network": "BRIDGE", 15 | "portMappings": [ 16 | { "containerPort": 0, "hostPort": 0, "protocol": "tcp" } 17 | ] 18 | } 19 | }, 20 | 21 | "healthChecks": [ 22 | { 23 | "protocol": "HTTP", 24 | "path": "/admin/health", 25 | "intervalSeconds": 10, 26 | "portIndex": 0, 27 | "timeoutSeconds": 10, 28 | "maxConsecutiveFailures": 3 29 | } 30 | ], 31 | 32 | "dependencies" : [ "zwitscher-eureka" ], 33 | 34 | "env": { 35 | "eureka.host": "zwitscher-eureka.marathon.mesos" 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /zwitscher-service/marathon-zwitscher-service.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-service", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | "cmd": "/opt/java/latest/bin/java -Xmx256m -Dserver.port=$PORT0 -Deureka.instance.ipAddress=$HOST -jar /opt/zwitscher-service/zwitscher-service.jar", 8 | 9 | "container": { 10 | "type": "DOCKER", 11 | "docker": { 12 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service:1.1.0", 13 | "network": "BRIDGE", 14 | "portMappings": [ 15 | { "containerPort": 0, "hostPort": 0, "protocol": "tcp" } 16 | ] 17 | } 18 | }, 19 | 20 | "healthChecks": [ 21 | { 22 | "protocol": "HTTP", 23 | "path": "/admin/health", 24 | "intervalSeconds": 10, 25 | "portIndex": 0, 26 | "timeoutSeconds": 10, 27 | "maxConsecutiveFailures": 3 28 | } 29 | ], 30 | 31 | "dependencies" : [ "zwitscher-config", "zwitscher-eureka" ], 32 | 33 | "env": { 34 | "eureka.host": "zwitscher-eureka.marathon.mesos" 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /zwitscher-edge/marathon-zwitscher-edge.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-edge", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | 8 | "cmd": "/opt/java/latest/bin/java -Xmx256m -Dserver.port=$PORT0 -Deureka.instance.ipAddress=$HOST -jar /opt/zwitscher-edge/zwitscher-edge.jar", 9 | 10 | "container": { 11 | "type": "DOCKER", 12 | "docker": { 13 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-edge:1.1.0", 14 | "network": "BRIDGE", 15 | "portMappings": [ 16 | { "hostPort": 0, "containerPort": 8765, "protocol": "tcp"} 17 | ] 18 | } 19 | }, 20 | 21 | "healthChecks": [ 22 | { 23 | "protocol": "HTTP", 24 | "path": "/admin/health", 25 | "intervalSeconds": 10, 26 | "portIndex": 0, 27 | "timeoutSeconds": 10, 28 | "maxConsecutiveFailures": 3 29 | } 30 | ], 31 | 32 | "dependencies" : [ "zwitscher-config", "zwitscher-eureka" ], 33 | 34 | "env": { 35 | "eureka.host": "zwitscher-eureka.marathon.mesos" 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /zwitscher-monitor/marathon-zwitscher-monitor.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-monitor", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | 8 | "cmd": "/opt/java/latest/bin/java -Xmx256m -Dserver.port=$PORT0 -Deureka.instance.ipAddress=$HOST -jar /opt/zwitscher-monitor/zwitscher-monitor.jar", 9 | 10 | "container": { 11 | "type": "DOCKER", 12 | "docker": { 13 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-monitor:1.1.0", 14 | "network": "BRIDGE", 15 | "portMappings": [ 16 | { "hostPort": 0, "containerPort": 8989, "protocol": "tcp"} 17 | ] 18 | } 19 | }, 20 | 21 | "healthChecks": [ 22 | { 23 | "protocol": "HTTP", 24 | "path": "/admin/health", 25 | "intervalSeconds": 10, 26 | "portIndex": 0, 27 | "timeoutSeconds": 10, 28 | "maxConsecutiveFailures": 3 29 | } 30 | ], 31 | 32 | "dependencies" : [ "zwitscher-config", "zwitscher-eureka" ], 33 | 34 | "env": { 35 | "eureka.host": "zwitscher-eureka.marathon.mesos" 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /zwitscher-board/marathon-zwitscher-board.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "zwitscher-board", 3 | 4 | "instances": 1, 5 | "cpus": 0.2, 6 | "mem": 512, 7 | 8 | "cmd": "/opt/java/latest/bin/java -Xmx256m -Dserver.port=$PORT0 -Deureka.instance.ipAddress=$HOST -jar /opt/zwitscher-board/zwitscher-board.jar", 9 | 10 | "container": { 11 | "type": "DOCKER", 12 | "docker": { 13 | "image": "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-board:1.1.0", 14 | "network": "BRIDGE", 15 | "portMappings": [ 16 | { "hostPort": 0, "containerPort": 8081, "protocol": "tcp" } 17 | ] 18 | } 19 | }, 20 | 21 | "healthChecks": [ 22 | { 23 | "protocol": "HTTP", 24 | "path": "/admin/health", 25 | "intervalSeconds": 10, 26 | "portIndex": 0, 27 | "timeoutSeconds": 10, 28 | "maxConsecutiveFailures": 3 29 | } 30 | ], 31 | 32 | "dependencies" : [ "zwitscher-config", "zwitscher-eureka" ], 33 | 34 | "env": { 35 | "eureka.host": "zwitscher-eureka.marathon.mesos" 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /marathon-deploy-all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Deploys all Zwitscher services on DC/OS in one go. 3 | 4 | # Location of the marathon API. 5 | # http://m1.dcos:8080/v2 for Vagrant DC/OS cluster. 6 | MARATHON_API="http://m1.dcos:8080/v2" 7 | # Delay between deployments to account for image download and startup times 8 | DELAY=45 9 | # Service start order 10 | START_ORDER="eureka config service board edge monitor" 11 | 12 | # Determine the base path 13 | BASE_PATH="$(dirname "$0")" 14 | 15 | # Workaround for OSX not having readlink -f to resolve symlinks 16 | if uname | grep "Darwin" > /dev/null 17 | then 18 | while [ -L "$BASE_PATH" ] 19 | do 20 | BASE_PATH="$(readlink "$BASE_PATH")" 21 | done 22 | else 23 | BASE_PATH="$(readlink -f "$BASE_PATH")" 24 | fi 25 | 26 | # Hard-coded service start order 27 | for SERVICE in $START_ORDER 28 | do 29 | f="$BASE_PATH/zwitscher-$SERVICE/marathon-zwitscher-$SERVICE.json" 30 | echo "Deploying $f" 31 | # Deploy using the Marathon REST API 32 | curl -X POST "$MARATHON_API/apps" -H "Content-type: application/json" -d "@$f" 33 | echo 34 | sleep $DELAY 35 | done 36 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | 15 | 16 | 17 | 18 |

Zwitscher Messages on Topic

19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 QAware GmbH, Munich, Germany 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | info: 2 | component: Zwitscher Config Server 3 | 4 | endpoints: 5 | info: 6 | enabled: true 7 | shutdown: 8 | enabled: true 9 | health: 10 | enabled: true 11 | sensitive: false 12 | 13 | server: 14 | port: 8888 15 | 16 | management: 17 | context-path: /admin 18 | 19 | logging: 20 | level: 21 | com.netflix.discovery: INFO 22 | org.springframework.cloud: INFO 23 | 24 | eureka: 25 | instance: 26 | # register with IP addresses (required for deployment in Kubernetes?) 27 | preferIpAddress: true 28 | leaseRenewalIntervalInSeconds: 10 29 | statusPageUrlPath: ${management.context-path}/info 30 | healthCheckUrlPath: ${management.context-path}/health 31 | 32 | --- 33 | spring: 34 | profiles: native 35 | cloud: 36 | config: 37 | server: 38 | native: 39 | searchLocations: classpath:/config 40 | 41 | --- 42 | spring: 43 | profiles: docker 44 | cloud: 45 | config: 46 | server: 47 | git: 48 | uri: https://github.com/qaware/cloud-native-zwitscher/tree/master/zwitscher-config/src/main/resources/config 49 | cloneOnStart: true -------------------------------------------------------------------------------- /zwitscher-eureka/k8s-zwitscher-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-eureka 5 | labels: 6 | zwitscher: eureka 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8761 12 | selector: 13 | zwitscher: eureka 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-eureka 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: eureka 26 | spec: 27 | containers: 28 | - name: zwitscher-eureka 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-eureka:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "125m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "250m" 38 | ports: 39 | - containerPort: 8761 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8761 44 | initialDelaySeconds: 60 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8761 50 | timeoutSeconds: 30 51 | env: 52 | - name: JAVA_OPTS 53 | value: -Xmx128m 54 | -------------------------------------------------------------------------------- /zwitscher-board/k8s-zwitscher-board.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-board 5 | labels: 6 | zwitscher: board 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8081 12 | selector: 13 | zwitscher: board 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-board 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: board 26 | spec: 27 | containers: 28 | - name: zwitscher-board 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-board:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "250m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "500m" 38 | ports: 39 | - containerPort: 8081 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8081 44 | initialDelaySeconds: 90 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8081 50 | timeoutSeconds: 30 51 | env: 52 | - name: EUREKA_HOST 53 | value: zwitscher-eureka 54 | - name: JAVA_OPTS 55 | value: -Xmx128m 56 | -------------------------------------------------------------------------------- /zwitscher-config/k8s-zwitscher-config.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-config 5 | labels: 6 | zwitscher: config 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8888 12 | selector: 13 | zwitscher: config 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-config 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: config 26 | spec: 27 | containers: 28 | - name: zwitscher-config 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-config:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "125m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "250m" 38 | ports: 39 | - containerPort: 8888 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8888 44 | initialDelaySeconds: 90 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8888 50 | timeoutSeconds: 30 51 | env: 52 | - name: EUREKA_HOST 53 | value: zwitscher-eureka 54 | - name: JAVA_OPTS 55 | value: -Xmx128m 56 | -------------------------------------------------------------------------------- /zwitscher-monitor/k8s-zwitscher-monitor.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-monitor 5 | labels: 6 | zwitscher: monitor 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8989 12 | selector: 13 | zwitscher: monitor 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-monitor 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: monitor 26 | spec: 27 | containers: 28 | - name: zwitscher-monitor 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-monitor:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "125m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "250m" 38 | ports: 39 | - containerPort: 8989 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8989 44 | initialDelaySeconds: 120 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8989 50 | timeoutSeconds: 30 51 | env: 52 | - name: EUREKA_HOST 53 | value: zwitscher-eureka 54 | - name: JAVA_OPTS 55 | value: -Xmx128m 56 | -------------------------------------------------------------------------------- /zwitscher-service/k8s-zwitscher-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-service 5 | labels: 6 | zwitscher: service 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8080 12 | selector: 13 | zwitscher: service 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-service 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: service 26 | spec: 27 | containers: 28 | - name: zwitscher-service 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "250m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "500m" 38 | ports: 39 | - containerPort: 8080 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8080 44 | initialDelaySeconds: 90 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8080 50 | timeoutSeconds: 30 51 | env: 52 | - name: EUREKA_HOST 53 | value: zwitscher-eureka 54 | - name: JAVA_OPTS 55 | value: -Xmx128m 56 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/tweet/ZwitscherMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.tweet; 25 | 26 | import lombok.Data; 27 | 28 | /** 29 | * Our simple ZwitscherMessage data class. 30 | */ 31 | @Data 32 | public class ZwitscherMessage { 33 | private final String message; 34 | } 35 | -------------------------------------------------------------------------------- /zwitscher-edge/k8s-zwitscher-edge.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-edge 5 | labels: 6 | zwitscher: edge 7 | spec: 8 | # if your cluster supports it, uncomment the following to automatically create 9 | # an external load-balanced IP for the frontend service. Does not work locally. 10 | type: LoadBalancer 11 | ports: 12 | - port: 8765 13 | selector: 14 | zwitscher: edge 15 | --- 16 | apiVersion: extensions/v1beta1 17 | kind: Deployment 18 | metadata: 19 | name: zwitscher-edge 20 | spec: 21 | replicas: 1 22 | minReadySeconds: 30 23 | template: 24 | metadata: 25 | labels: 26 | zwitscher: edge 27 | spec: 28 | containers: 29 | - name: zwitscher-edge 30 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-edge:1.1.0" 31 | imagePullPolicy: Always 32 | resources: 33 | requests: 34 | memory: "128Mi" 35 | cpu: "125m" 36 | limits: 37 | memory: "256Mi" 38 | cpu: "250m" 39 | ports: 40 | - containerPort: 8765 41 | livenessProbe: 42 | httpGet: 43 | path: /admin/health 44 | port: 8765 45 | initialDelaySeconds: 90 46 | timeoutSeconds: 30 47 | readinessProbe: 48 | httpGet: 49 | path: /admin/info 50 | port: 8765 51 | timeoutSeconds: 30 52 | env: 53 | - name: EUREKA_HOST 54 | value: zwitscher-eureka 55 | - name: JAVA_OPTS 56 | value: -Xmx128m 57 | -------------------------------------------------------------------------------- /zwitscher-config/src/main/resources/config/zwitscher-service.yml: -------------------------------------------------------------------------------- 1 | endpoints: 2 | info: 3 | enabled: true 4 | shutdown: 5 | enabled: true 6 | health: 7 | enabled: true 8 | sensitive: false 9 | 10 | logging: 11 | level: 12 | com.netflix.discovery: INFO 13 | org.springframework.cloud: INFO 14 | org.springframework.web: DEBUG 15 | de.qaware.cloud.nativ.zwitscher: DEBUG 16 | 17 | management: 18 | context-path: /admin 19 | 20 | eureka: 21 | instance: 22 | # register with IP addresses (required for deployment in Kubernetes?) 23 | preferIpAddress: true 24 | leaseRenewalIntervalInSeconds: 10 25 | statusPageUrlPath: ${management.context-path}/info 26 | healthCheckUrlPath: ${management.context-path}/health 27 | 28 | spring: 29 | social: 30 | twitter: 31 | appId: '{cipher}AQBSfX5qoZ9g1Qo0cCtj1WWSJBJyjz72ojQTCsMF8e30AwKCdb5qx2K33gWAWgCCMIwGXcWwA68EzI4zgLeZoAV3HirorC4fNqjU4M1MaXmuHSO7DGgheDBU+n1NzgWrmOVFxFdZjtdGFuARANxjQ53+al/ZhD9/+HPqMewH+lemOpEBlPpp0IAVBfactDRlCxwfFIn6qjON176nB6tz9BKLCAWFIR6OtBtP/oFZ6iao9SQCGWujNAkg3ALZpWf6TqwFUSdPfDhAwUaUAL2+XA3fGDy8xTljW+eEe+MHJzGc5mD+HqYBqiBnjFd+yiplKYY35OjyUEppKGvoZbKNwUpGFHx40MKQLCPLW9cT2ZEFUvZkF6d+5yobrkBcO2Pp9eWY1pst5CQj8qBs8jURo172' 32 | appSecret: '{cipher}AQBWP86hCkery1FxrhY4cBtzFmKHJqXQlc7/pXDnocDQ5otfi0eKai2CFk/OFRDoDW6C+5wZyVbY0K6YcZCU92vDxCf9qGKj9lTvnPS43bcmAbY7Jp/UlIh5LGq2EZBjtGlxpqthSUJ07p9qBumsneRh6xwOIA6oDYUQibyUwaA9t3jvK/r4nf66hYKvzBzWijMGo3eSKMDjq1SNnRUDA06xhYZ8lNvwkqIRRbA8TdOhSeBKRNacxUfetskp21M4D92Btq+KLp2x/6+WzI9uOVTxsh6RMRpFaK33w9WzZlfNvGqlRsj4F9c3JyJBPv1/cEgAAvcPp8dr/a7ooUdNl1s998aLRW+ijw4maR0KNmrGSjkefSe7uP+sXGm/kQ6BSyBr/qL/vAA87c7KqSW/EGpKYxQMTA6IhriS/jIaJRJs0fXtrbdNIEzpM4/xC0dxe58=' 33 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/domain/Zwitscher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board.domain; 25 | 26 | import lombok.AllArgsConstructor; 27 | import lombok.Data; 28 | import lombok.NoArgsConstructor; 29 | 30 | /** 31 | * A simple Zwitscher data class. Also defines the fallback implementation. 32 | */ 33 | @Data 34 | @NoArgsConstructor 35 | @AllArgsConstructor 36 | public class Zwitscher { 37 | private String message; 38 | } 39 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/quote/RandomQuote.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import lombok.AllArgsConstructor; 27 | import lombok.Data; 28 | import lombok.NoArgsConstructor; 29 | 30 | /** 31 | * The data class for our RandomQuote. Only contains the quote and author field 32 | * of the original response obtained from Quotes on Design. 33 | */ 34 | @Data 35 | @NoArgsConstructor 36 | @AllArgsConstructor 37 | public class RandomQuote { 38 | private String quote; 39 | private String author; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /zwitscher-service/src/test/java/de/qaware/cloud/nativ/zwitscher/service/quote/RandomQuoteTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import org.junit.Test; 27 | 28 | import static org.hamcrest.Matchers.is; 29 | import static org.junit.Assert.assertThat; 30 | 31 | public class RandomQuoteTest { 32 | 33 | @Test 34 | public void testAllArgsConstructor() throws Exception { 35 | RandomQuote quote = new RandomQuote("quote", "author"); 36 | assertThat(quote.getQuote(), is("quote")); 37 | assertThat(quote.getAuthor(), is("author")); 38 | } 39 | } -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/quote/RandomQuoteFallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import lombok.extern.slf4j.Slf4j; 27 | import org.springframework.stereotype.Component; 28 | 29 | /** 30 | * A fallback implementation for the QuotesOnDesignClient. 31 | */ 32 | @Component 33 | @Slf4j 34 | public class RandomQuoteFallback implements QuotesOnDesignClient { 35 | @Override 36 | public RandomQuote getRandomQuote() { 37 | log.warn("Using fallback for RandomQuote."); 38 | return new RandomQuote("Everything fails all the time.", "Unknown"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/tweet/ZwitscherRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.tweet; 25 | 26 | import java.util.Collection; 27 | 28 | /** 29 | * The ZwitscherRepository provides methods to work with ZwitscherMessages. 30 | */ 31 | public interface ZwitscherRepository { 32 | /** 33 | * Find and return all ZwitscherMessages matching the given query. 34 | * 35 | * @param q the query string up to 500 characters 36 | * @param pageSize the number of messages to return 37 | * @return a collection of ZwitscherMessages 38 | */ 39 | Collection search(String q, int pageSize); 40 | } 41 | -------------------------------------------------------------------------------- /zwitscher-config/src/test/java/de/qaware/cloud/nativ/zwitscher/config/ZwitscherConfigApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.config; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.springframework.boot.test.SpringApplicationConfiguration; 29 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 30 | import org.springframework.test.context.web.WebAppConfiguration; 31 | 32 | @RunWith(SpringJUnit4ClassRunner.class) 33 | @SpringApplicationConfiguration(classes = ZwitscherConfigApplication.class) 34 | @WebAppConfiguration 35 | public class ZwitscherConfigApplicationTests { 36 | 37 | @Test 38 | public void contextLoads() { 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /zwitscher-eureka/src/test/java/de/qaware/cloud/nativ/zwitscher/eureka/ZwitscherEurekaApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.eureka; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.springframework.boot.test.SpringApplicationConfiguration; 29 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 30 | import org.springframework.test.context.web.WebAppConfiguration; 31 | 32 | @RunWith(SpringJUnit4ClassRunner.class) 33 | @SpringApplicationConfiguration(classes = ZwitscherEurekaApplication.class) 34 | @WebAppConfiguration 35 | public class ZwitscherEurekaApplicationTests { 36 | 37 | @Test 38 | public void contextLoads() { 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /contributing.json: -------------------------------------------------------------------------------- 1 | // https://gitmagic.io/rules 2 | { 3 | "commit": { 4 | "subject_cannot_be_empty": true, 5 | "subject_must_be_longer_than": 3, 6 | "subject_must_be_shorter_than": 101, 7 | "subject_lines_must_be_shorter_than": 101, 8 | "subject_must_be_single_line": true, 9 | "subject_must_be_in_tense": "past", 10 | "subject_must_start_with_case": "upper", 11 | "subject_must_end_with_dot": true, 12 | "subject_must_close_github_issue": false, 13 | "subject_must_include_github_issue": true, 14 | // Body is the rest of the commit message after the first paragraph, 15 | // separated by a blank line. 16 | "body_cannot_be_empty": false, 17 | "body_lines_must_be_shorter_than": 73, 18 | "body_must_close_github_issue": false, 19 | "body_must_include_github_issue": false 20 | }, 21 | 22 | "pull_request": { 23 | "subject_cannot_be_empty": true, 24 | "subject_must_be_longer_than": 3, 25 | "subject_must_be_shorter_than": 101, 26 | "subject_must_be_in_tense": "past", 27 | "subject_must_start_with_case": "upper", 28 | "subject_must_not_end_with_dot": true, 29 | "subject_must_include_github_issue": false, 30 | 31 | "body_cannot_be_empty": true, 32 | "body_must_include_verification_steps": false, 33 | "body_must_close_github_issue": false, 34 | "body_must_include_github_issue": false 35 | }, 36 | 37 | "issue": { 38 | "subject_cannot_be_empty": true, 39 | "subject_must_be_longer_than": 3, 40 | "subject_must_be_shorter_than": 101, 41 | "subject_must_be_in_tense": "imperative", 42 | "subject_must_start_with_case": "upper", 43 | "subject_must_not_end_with_dot": true, 44 | "body_cannot_be_empty": true, 45 | "body_must_include_reproduction_steps": ["bug"], 46 | "label_must_be_set": true 47 | }, 48 | "branch": { 49 | "name_must_be_longer_than": 3, 50 | "name_must_be_shorter_than": 127, 51 | "name_must_include_github_issue": false 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /zwitscher-config/src/main/java/de/qaware/cloud/nativ/zwitscher/config/ZwitscherConfigApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.config; 25 | 26 | import org.springframework.boot.SpringApplication; 27 | import org.springframework.boot.autoconfigure.SpringBootApplication; 28 | import org.springframework.cloud.config.server.EnableConfigServer; 29 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 30 | 31 | /** 32 | * The config server main application class for the Cloud Native Zwitscher showcase. 33 | */ 34 | @SpringBootApplication 35 | @EnableConfigServer 36 | @EnableEurekaClient 37 | public class ZwitscherConfigApplication { 38 | public static void main(String[] args) { 39 | SpringApplication.run(ZwitscherConfigApplication.class, args); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /zwitscher-eureka/src/main/java/de/qaware/cloud/nativ/zwitscher/eureka/ZwitscherEurekaApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.eureka; 25 | 26 | import org.springframework.boot.SpringApplication; 27 | import org.springframework.boot.autoconfigure.SpringBootApplication; 28 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 29 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 30 | 31 | /** 32 | * The Eureka server main application class for the Cloud Native Zwitscher showcase. 33 | */ 34 | @SpringBootApplication 35 | @EnableEurekaServer 36 | @EnableDiscoveryClient 37 | public class ZwitscherEurekaApplication { 38 | public static void main(String[] args) { 39 | SpringApplication.run(ZwitscherEurekaApplication.class, args); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /zwitscher-edge/src/test/java/de/qaware/cloud/nativ/zwitscher/edge/ZwitscherEdgeApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.edge; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.springframework.boot.test.SpringApplicationConfiguration; 29 | import org.springframework.test.context.TestPropertySource; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | import org.springframework.test.context.web.WebAppConfiguration; 32 | 33 | @RunWith(SpringJUnit4ClassRunner.class) 34 | @SpringApplicationConfiguration(classes = ZwitscherEdgeApplication.class) 35 | @WebAppConfiguration 36 | @TestPropertySource("classpath:/application-test.properties") 37 | public class ZwitscherEdgeApplicationTests { 38 | 39 | @Test 40 | public void contextLoads() { 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /zwitscher-board/src/test/java/de/qaware/cloud/nativ/zwitscher/board/ZwitscherBoardApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.springframework.boot.test.SpringApplicationConfiguration; 29 | import org.springframework.test.context.TestPropertySource; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | import org.springframework.test.context.web.WebAppConfiguration; 32 | 33 | @RunWith(SpringJUnit4ClassRunner.class) 34 | @SpringApplicationConfiguration(classes = ZwitscherBoardApplication.class) 35 | @WebAppConfiguration 36 | @TestPropertySource("classpath:/application-test.properties") 37 | public class ZwitscherBoardApplicationTests { 38 | 39 | @Test 40 | public void contextLoads() { 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /zwitscher-monitor/src/test/java/de/qaware/cloud/nativ/zwitscher/monitor/ZwitscherMonitorApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.monitor; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.springframework.boot.test.SpringApplicationConfiguration; 29 | import org.springframework.test.context.TestPropertySource; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | import org.springframework.test.context.web.WebAppConfiguration; 32 | 33 | @RunWith(SpringJUnit4ClassRunner.class) 34 | @SpringApplicationConfiguration(classes = ZwitscherMonitorApplication.class) 35 | @WebAppConfiguration 36 | @TestPropertySource("classpath:/application-test.properties") 37 | public class ZwitscherMonitorApplicationTests { 38 | 39 | @Test 40 | public void contextLoads() { 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/domain/Quote.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board.domain; 25 | 26 | import lombok.AllArgsConstructor; 27 | import lombok.Data; 28 | import lombok.NoArgsConstructor; 29 | import lombok.extern.slf4j.Slf4j; 30 | import org.springframework.stereotype.Component; 31 | 32 | /** 33 | * A simple quote data class. Also defines the fallback implementation. 34 | */ 35 | @Data 36 | @NoArgsConstructor 37 | @AllArgsConstructor 38 | public class Quote { 39 | 40 | private String quote; 41 | private String author; 42 | 43 | @Component 44 | @Slf4j 45 | static class Fallback implements QuoteRepository { 46 | @Override 47 | public Quote getNextQuote() { 48 | log.warn("Using fallback quote."); 49 | return new Quote("Everything fails all the time.", "Unknown"); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/tweet/SocialZwitscherConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.tweet; 25 | 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.social.twitter.api.Twitter; 30 | import org.springframework.social.twitter.api.impl.TwitterTemplate; 31 | 32 | /** 33 | * A custom configuration to initialize the Twitter template. 34 | */ 35 | @Configuration 36 | public class SocialZwitscherConfiguration { 37 | @Bean 38 | public Twitter twitter(final @Value("${spring.social.twitter.appId}") String appId, 39 | final @Value("${spring.social.twitter.appSecret}") String appSecret) { 40 | return new TwitterTemplate(appId, appSecret); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/domain/QuoteRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board.domain; 25 | 26 | import org.springframework.cloud.netflix.feign.FeignClient; 27 | import org.springframework.web.bind.annotation.RequestMapping; 28 | import org.springframework.web.bind.annotation.RequestMethod; 29 | 30 | /** 31 | * The feign client to access the /quote service from our zwitscher-service. Feign 32 | * will locate the endpoint via Eureka using the serviceId and use Ribbon to balance 33 | * between the registered instances. 34 | */ 35 | @FeignClient(name = "zwitscher-service", fallback = Quote.Fallback.class) 36 | public interface QuoteRepository { 37 | /** 38 | * Get the next quote from the the /quote service. 39 | * 40 | * @return the quote 41 | */ 42 | @RequestMapping(method = RequestMethod.GET, value = "/quote") 43 | Quote getNextQuote(); 44 | } 45 | -------------------------------------------------------------------------------- /zwitscher-edge/src/main/java/de/qaware/cloud/nativ/zwitscher/edge/ZwitscherEdgeApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.edge; 25 | 26 | import org.springframework.boot.SpringApplication; 27 | import org.springframework.boot.autoconfigure.SpringBootApplication; 28 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 29 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 30 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 31 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 32 | 33 | /** 34 | * The Zuul edge server main application class of the Cloud Native Zwitscher showcase. 35 | */ 36 | @SpringBootApplication 37 | @EnableDiscoveryClient 38 | @EnableZuulProxy 39 | @EnableCircuitBreaker 40 | public class ZwitscherEdgeApplication { 41 | public static void main(String[] args) { 42 | SpringApplication.run(ZwitscherEdgeApplication.class, args); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/quote/QuotesOnDesignClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import org.springframework.cloud.netflix.feign.FeignClient; 27 | import org.springframework.web.bind.annotation.RequestMapping; 28 | import org.springframework.web.bind.annotation.RequestMethod; 29 | 30 | /** 31 | * A declarative Feign REST client to access the external Quotes on Design service. 32 | */ 33 | @FeignClient(name = "quotesOnDesign", url = "http://quotesondesign.com", 34 | configuration = QuotesOnDesignConfiguration.class, 35 | fallback = RandomQuoteFallback.class) 36 | public interface QuotesOnDesignClient { 37 | /** 38 | * Obtain a random quote by GET /api/3.0/api-3.0.json 39 | * 40 | * @return a random quote 41 | */ 42 | @RequestMapping(method = RequestMethod.GET, value = "/api/3.0/api-3.0.json") 43 | RandomQuote getRandomQuote(); 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/ZwitscherServiceApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service; 25 | 26 | import org.springframework.boot.SpringApplication; 27 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 28 | import org.springframework.boot.autoconfigure.SpringBootApplication; 29 | import org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration; 30 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 31 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 32 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 33 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 34 | 35 | /** 36 | * The Zwitscher service main application of the Cloud Native Zwitscher Showcase. 37 | */ 38 | @SpringBootApplication 39 | @EnableDiscoveryClient 40 | @EnableHystrix 41 | @EnableCircuitBreaker 42 | @EnableFeignClients 43 | @EnableAutoConfiguration(exclude = {TwitterAutoConfiguration.class}) 44 | public class ZwitscherServiceApplication { 45 | public static void main(String[] args) { 46 | SpringApplication.run(ZwitscherServiceApplication.class, args); 47 | } 48 | } -------------------------------------------------------------------------------- /zwitscher-monitor/src/main/java/de/qaware/cloud/nativ/zwitscher/monitor/ZwitscherMonitorApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.monitor; 25 | 26 | import org.springframework.boot.autoconfigure.SpringBootApplication; 27 | import org.springframework.boot.builder.SpringApplicationBuilder; 28 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 29 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 30 | import org.springframework.cloud.netflix.turbine.EnableTurbine; 31 | import org.springframework.stereotype.Controller; 32 | import org.springframework.web.bind.annotation.RequestMapping; 33 | import org.springframework.web.bind.annotation.RequestMethod; 34 | 35 | /** 36 | * The Hystrix and Turbine monitoring dashboard main application of the Cloud 37 | * Native Zwitscher showcase. 38 | */ 39 | @SpringBootApplication 40 | @EnableDiscoveryClient 41 | @EnableTurbine 42 | @EnableHystrixDashboard 43 | @Controller 44 | public class ZwitscherMonitorApplication { 45 | 46 | @RequestMapping(path = "/", method = RequestMethod.GET) 47 | public String index() { 48 | return "forward:/hystrix"; 49 | } 50 | 51 | public static void main(String[] args) { 52 | new SpringApplicationBuilder(ZwitscherMonitorApplication.class) 53 | .web(true).run(args); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/quote/RandomQuoteController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Qualifier; 28 | import org.springframework.http.HttpEntity; 29 | import org.springframework.http.HttpStatus; 30 | import org.springframework.http.MediaType; 31 | import org.springframework.http.ResponseEntity; 32 | import org.springframework.web.bind.annotation.RequestMapping; 33 | import org.springframework.web.bind.annotation.RequestMethod; 34 | import org.springframework.web.bind.annotation.RestController; 35 | 36 | /** 37 | * A REST controller to produce random quotes. The client used here is a feign client 38 | * that goes against a public quote API service. 39 | */ 40 | @RestController 41 | @RequestMapping("/quote") 42 | public class RandomQuoteController { 43 | 44 | @Autowired 45 | @Qualifier("de.qaware.cloud.nativ.zwitscher.service.quote.QuotesOnDesignClient") 46 | private QuotesOnDesignClient quoteClient; 47 | 48 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 49 | public HttpEntity quote() { 50 | RandomQuote quote = quoteClient.getRandomQuote(); 51 | return new ResponseEntity<>(quote, HttpStatus.OK); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/ZwitscherBoardApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board; 25 | 26 | import org.springframework.boot.SpringApplication; 27 | import org.springframework.boot.autoconfigure.SpringBootApplication; 28 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 29 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 30 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 31 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 32 | import org.springframework.cloud.netflix.ribbon.RibbonClient; 33 | import org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory; 34 | import org.springframework.cloud.netflix.ribbon.SpringClientFactory; 35 | import org.springframework.context.annotation.Bean; 36 | import org.springframework.web.client.RestTemplate; 37 | 38 | /** 39 | * The Zwitscher board UI main application of the Cloud Native Zwitscher Showcase. 40 | */ 41 | @SpringBootApplication 42 | @EnableDiscoveryClient 43 | @EnableCircuitBreaker 44 | @EnableFeignClients 45 | @RibbonClient(name = "zwitscher-service") 46 | public class ZwitscherBoardApplication { 47 | public static void main(String[] args) { 48 | SpringApplication.run(ZwitscherBoardApplication.class, args); 49 | } 50 | 51 | @Bean 52 | @LoadBalanced 53 | public RestTemplate zwitscherServiceRestTemplate(SpringClientFactory clientFactory) { 54 | RibbonClientHttpRequestFactory requestFactory = new RibbonClientHttpRequestFactory(clientFactory); 55 | return new RestTemplate(requestFactory); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | zwitschereureka: 2 | image: "zwitscher-eureka:1.1.0" 3 | hostname: zwitschereureka 4 | environment: 5 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9761 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 6 | ports: 7 | - "8761:8761" 8 | - "9761:9761" 9 | 10 | zwitscherconfig: 11 | image: "zwitscher-config:1.1.0" 12 | hostname: zwitscherconfig 13 | links: 14 | - zwitschereureka 15 | environment: 16 | DOCKER_COMPOSE: 'true' 17 | EUREKA_HOST: zwitschereureka 18 | EUREKA_PORT: 8761 19 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9888 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 20 | ports: 21 | - "8888:8888" 22 | - "9888:9888" 23 | 24 | zwitscherservice: 25 | image: "zwitscher-service:1.1.0" 26 | hostname: zwitscherservice 27 | links: 28 | - zwitschereureka 29 | - zwitscherconfig 30 | environment: 31 | DOCKER_COMPOSE: 'true' 32 | EUREKA_HOST: zwitschereureka 33 | EUREKA_PORT: 8761 34 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9080 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 35 | ports: 36 | - "8080:8080" 37 | - "9080:9080" 38 | 39 | zwitscherboard: 40 | image: "zwitscher-board:1.1.0" 41 | hostname: zwitscherboard 42 | links: 43 | - zwitschereureka 44 | - zwitscherconfig 45 | - zwitscherservice 46 | environment: 47 | DOCKER_COMPOSE: 'true' 48 | EUREKA_HOST: zwitschereureka 49 | EUREKA_PORT: 8761 50 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9081 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 51 | ports: 52 | - "8081:8081" 53 | - "9081:9081" 54 | 55 | zwitscheredge: 56 | image: "zwitscher-edge:1.1.0" 57 | hostname: zwitscheredge 58 | links: 59 | - zwitschereureka 60 | - zwitscherconfig 61 | - zwitscherservice 62 | - zwitscherboard 63 | environment: 64 | DOCKER_COMPOSE: 'true' 65 | EUREKA_HOST: zwitschereureka 66 | EUREKA_PORT: 8761 67 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9765 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 68 | ports: 69 | - "8765:8765" 70 | - "9765:9765" 71 | 72 | zwitschermonitor: 73 | image: "zwitscher-monitor:1.1.0" 74 | hostname: zwitschermonitor 75 | links: 76 | - zwitschereureka 77 | - zwitscherconfig 78 | - zwitscherservice 79 | - zwitscherboard 80 | - zwitscheredge 81 | environment: 82 | DOCKER_COMPOSE: 'true' 83 | EUREKA_HOST: zwitschereureka 84 | EUREKA_PORT: 8761 85 | JAVA_OPTS: -Xmx128m -Dcom.sun.management.jmxremote.port=9989 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 86 | ports: 87 | - "8989:8989" 88 | - "9989:9989" 89 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/quote/QuotesOnDesignConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.quote; 25 | 26 | import feign.codec.Decoder; 27 | import org.springframework.beans.factory.ObjectFactory; 28 | import org.springframework.boot.autoconfigure.web.HttpMessageConverters; 29 | import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; 30 | import org.springframework.cloud.netflix.feign.support.SpringDecoder; 31 | import org.springframework.context.annotation.Bean; 32 | import org.springframework.context.annotation.Configuration; 33 | import org.springframework.http.MediaType; 34 | import org.springframework.http.converter.HttpMessageConverter; 35 | import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; 36 | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; 37 | 38 | /** 39 | * Custom configuration component required for the QuotesOnDesign feign client. 40 | */ 41 | @Configuration 42 | public class QuotesOnDesignConfiguration { 43 | @Bean 44 | public Decoder feignDecoder() { 45 | HttpMessageConverter jacksonConverter = new QuoteOnDesignMessageConverter(); 46 | ObjectFactory objectFactory = () -> new HttpMessageConverters(jacksonConverter); 47 | return new ResponseEntityDecoder(new SpringDecoder(objectFactory)); 48 | } 49 | 50 | /** 51 | * Private message converter implementation required due to strange content type [text/x-json]. 52 | */ 53 | private static class QuoteOnDesignMessageConverter extends AbstractJackson2HttpMessageConverter { 54 | public QuoteOnDesignMessageConverter() { 55 | super(Jackson2ObjectMapperBuilder.json().build(), 56 | MediaType.APPLICATION_JSON_UTF8, 57 | new MediaType("text", "x-json", DEFAULT_CHARSET)); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/tweet/SocialZwitscherRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.tweet; 25 | 26 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 27 | import lombok.RequiredArgsConstructor; 28 | import lombok.extern.slf4j.Slf4j; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.boot.actuate.health.Health; 31 | import org.springframework.boot.actuate.health.HealthIndicator; 32 | import org.springframework.social.twitter.api.SearchResults; 33 | import org.springframework.social.twitter.api.Twitter; 34 | import org.springframework.stereotype.Repository; 35 | 36 | import java.util.Collection; 37 | import java.util.Collections; 38 | 39 | import static java.util.stream.Collectors.toList; 40 | 41 | /** 42 | * This implementation uses Spring Social Twitter API to access tweets 43 | * from twitter in order to map them to ZwitscherMessages. 44 | */ 45 | @Repository 46 | @Slf4j 47 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 48 | public class SocialZwitscherRepository implements ZwitscherRepository, HealthIndicator { 49 | 50 | private final Twitter twitter; 51 | 52 | @Override 53 | @HystrixCommand(fallbackMethod = "noResults") 54 | public Collection search(String q, int pageSize) { 55 | SearchResults results = twitter.searchOperations().search(q, pageSize); 56 | return results.getTweets().stream() 57 | .map(t -> new ZwitscherMessage(t.getUnmodifiedText())) 58 | .collect(toList()); 59 | } 60 | 61 | protected Collection noResults(String q, int pageSize) { 62 | log.warn("Using fallback ZwitscherMessage results."); 63 | return Collections.emptyList(); 64 | } 65 | 66 | @Override 67 | public Health health() { 68 | // maybe check the connection status here 69 | return Health.up().build(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/domain/ZwitscherRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board.domain; 25 | 26 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.hibernate.validator.constraints.Length; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.beans.factory.annotation.Value; 31 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 32 | import org.springframework.stereotype.Repository; 33 | import org.springframework.web.client.RestTemplate; 34 | 35 | import java.util.Arrays; 36 | import java.util.Collection; 37 | import java.util.Collections; 38 | 39 | /** 40 | * The ZwitscherRepository uses a load balanced RestTemplate to access the /tweets, the 41 | * actual invocation is wrapped into a Hystrix command. 42 | */ 43 | @Repository 44 | @Slf4j 45 | public class ZwitscherRepository { 46 | 47 | @Autowired 48 | @LoadBalanced 49 | private RestTemplate restTemplate; 50 | 51 | @Value("${board.zwitscherUrl}") 52 | private String tweetsRibbonUrl; 53 | 54 | /** 55 | * Find the matching Zwitscher messages for the given query. 56 | * 57 | * @param q the query, max 500 chars long 58 | * @return the tweets, never NULL 59 | */ 60 | @HystrixCommand(fallbackMethod = "none") 61 | public Collection findByQ(final @Length(max = 500) String q) { 62 | log.info("Get Zwitscher message from /tweets using q={}.", q); 63 | 64 | Zwitscher[] tweets = restTemplate.getForObject(tweetsRibbonUrl, Zwitscher[].class, q); 65 | return Arrays.asList(tweets); 66 | } 67 | 68 | /** 69 | * Fallback method called by Hystrix in case of error. 70 | * 71 | * @param q the query, not used actually 72 | * @return empty collection 73 | */ 74 | protected Collection none(final String q) { 75 | log.warn("Using fallback for Zwitscher messages."); 76 | return Collections.emptyList(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /zwitscher-service/src/main/java/de/qaware/cloud/nativ/zwitscher/service/tweet/ZwitscherController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service.tweet; 25 | 26 | import lombok.RequiredArgsConstructor; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.boot.actuate.metrics.CounterService; 29 | import org.springframework.http.HttpEntity; 30 | import org.springframework.http.HttpStatus; 31 | import org.springframework.http.MediaType; 32 | import org.springframework.http.ResponseEntity; 33 | import org.springframework.web.bind.annotation.RequestMapping; 34 | import org.springframework.web.bind.annotation.RequestMethod; 35 | import org.springframework.web.bind.annotation.RequestParam; 36 | import org.springframework.web.bind.annotation.RestController; 37 | 38 | import java.util.Collection; 39 | 40 | /** 41 | * A simple REST controller to work with ZwitscherMessages. 42 | */ 43 | @RestController 44 | @RequestMapping("/tweets") 45 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 46 | public class ZwitscherController { 47 | 48 | private final CounterService counterService; 49 | private final ZwitscherRepository repository; 50 | 51 | /** 52 | * Return ZwitscherMessages matching the given query. 53 | * 54 | * @param q the query string 55 | * @param pageSize the number of messages to be returned 56 | * @return list of found Zwitscher messages 57 | */ 58 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 59 | public HttpEntity> tweets(@RequestParam("q") String q, 60 | @RequestParam(value = "pageSize", required = false, defaultValue = "50") 61 | int pageSize) { 62 | // record some metrics 63 | counterService.increment("services.system.tweets.invoked"); 64 | 65 | // perform the actual call 66 | Collection zwitscherMessages = repository.search(q, pageSize); 67 | return new ResponseEntity<>(zwitscherMessages, HttpStatus.OK); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /zwitscher-service/src/test/java/de/qaware/cloud/nativ/zwitscher/service/ZwitscherServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.service; 25 | 26 | import de.qaware.cloud.nativ.zwitscher.service.quote.QuotesOnDesignClient; 27 | import de.qaware.cloud.nativ.zwitscher.service.quote.RandomQuote; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.mockito.Mockito; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.beans.factory.annotation.Qualifier; 33 | import org.springframework.boot.test.SpringApplicationConfiguration; 34 | import org.springframework.context.annotation.Bean; 35 | import org.springframework.context.annotation.Configuration; 36 | import org.springframework.context.annotation.Import; 37 | import org.springframework.social.twitter.api.Twitter; 38 | import org.springframework.test.context.TestPropertySource; 39 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 40 | import org.springframework.test.context.web.WebAppConfiguration; 41 | 42 | import static org.hamcrest.Matchers.is; 43 | import static org.hamcrest.Matchers.notNullValue; 44 | import static org.junit.Assert.assertThat; 45 | 46 | @RunWith(SpringJUnit4ClassRunner.class) 47 | @SpringApplicationConfiguration(classes = ZwitscherServiceApplicationTests.MockTwitterConfiguration.class) 48 | @WebAppConfiguration 49 | @TestPropertySource("classpath:/application-test.properties") 50 | public class ZwitscherServiceApplicationTests { 51 | 52 | @Configuration 53 | @Import(ZwitscherServiceApplication.class) 54 | public static class MockTwitterConfiguration { 55 | @Bean 56 | public Twitter twitter() { 57 | return Mockito.mock(Twitter.class); 58 | } 59 | 60 | } 61 | 62 | @Autowired 63 | @Qualifier("de.qaware.cloud.nativ.zwitscher.service.quote.QuotesOnDesignClient") 64 | private QuotesOnDesignClient quoteClient; 65 | 66 | @Test 67 | public void contextLoads() { 68 | } 69 | 70 | @Test 71 | public void testQuotesOnDesignFeignClient() throws Exception { 72 | RandomQuote quote = quoteClient.getRandomQuote(); 73 | assertThat(quote, is(notNullValue())); 74 | 75 | assertThat(quote.getQuote(), is(notNullValue())); 76 | assertThat(quote.getAuthor(), is(notNullValue())); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /zwitscher-board/src/main/java/de/qaware/cloud/nativ/zwitscher/board/web/ZwitscherBoardController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2016 QAware GmbH, Munich, Germany 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package de.qaware.cloud.nativ.zwitscher.board.web; 25 | 26 | import de.qaware.cloud.nativ.zwitscher.board.domain.Quote; 27 | import de.qaware.cloud.nativ.zwitscher.board.domain.QuoteRepository; 28 | import de.qaware.cloud.nativ.zwitscher.board.domain.Zwitscher; 29 | import de.qaware.cloud.nativ.zwitscher.board.domain.ZwitscherRepository; 30 | import org.hibernate.validator.constraints.Length; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.beans.factory.annotation.Qualifier; 33 | import org.springframework.beans.factory.annotation.Value; 34 | import org.springframework.stereotype.Controller; 35 | import org.springframework.ui.Model; 36 | import org.springframework.web.bind.annotation.RequestMapping; 37 | import org.springframework.web.bind.annotation.RequestMethod; 38 | import org.springframework.web.bind.annotation.RequestParam; 39 | 40 | import java.util.Collection; 41 | 42 | /** 43 | * The main UI controller for the Zwitscher board interface. 44 | */ 45 | @Controller 46 | public class ZwitscherBoardController { 47 | 48 | @Autowired 49 | @Qualifier("de.qaware.cloud.nativ.zwitscher.board.domain.QuoteRepository") 50 | private QuoteRepository quoteRepository; 51 | 52 | @Autowired 53 | private ZwitscherRepository zwitscherRepository; 54 | 55 | @Value("${board.title}") 56 | private String title; 57 | 58 | @Value("${board.headline}") 59 | private String headline; 60 | 61 | /** 62 | * Renders the one and only Zwitscher board UI. 63 | * 64 | * @param viewModel the view model used to render the template 65 | * @return the template to use 66 | */ 67 | @RequestMapping(value = "/", method = RequestMethod.GET) 68 | public String index(Model viewModel) { 69 | populateDefault(viewModel); 70 | return "index"; 71 | } 72 | 73 | /** 74 | * Called when posting the search form on the Zwitscher board. 75 | * 76 | * @param q the query string 77 | * @param viewModel the view model used to render the template 78 | * @return the template to use 79 | */ 80 | @RequestMapping(value = "/search", method = RequestMethod.GET) 81 | public String search(@RequestParam("q") @Length(max = 500) String q, 82 | Model viewModel) { 83 | populateDefault(viewModel); 84 | populateTweets(q, viewModel); 85 | return "index"; 86 | } 87 | 88 | private void populateDefault(Model viewModel) { 89 | viewModel.addAttribute("title", title); 90 | viewModel.addAttribute("headline", headline); 91 | 92 | Quote quote = quoteRepository.getNextQuote(); 93 | viewModel.addAttribute("quote", quote); 94 | } 95 | 96 | private void populateTweets(String q, Model viewModel) { 97 | Collection tweets = zwitscherRepository.findByQ(q); 98 | viewModel.addAttribute("tweets", tweets); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >&- 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >&- 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /k8s-zwitscher.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: zwitscher-eureka 5 | labels: 6 | zwitscher: eureka 7 | spec: 8 | # use NodePort here to be able to access the port on each node 9 | type: NodePort 10 | ports: 11 | - port: 8761 12 | selector: 13 | zwitscher: eureka 14 | --- 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: zwitscher-eureka 19 | spec: 20 | replicas: 1 21 | minReadySeconds: 30 22 | template: 23 | metadata: 24 | labels: 25 | zwitscher: eureka 26 | spec: 27 | containers: 28 | - name: zwitscher-eureka 29 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-eureka:1.1.0" 30 | imagePullPolicy: Always 31 | resources: 32 | requests: 33 | memory: "128Mi" 34 | cpu: "125m" 35 | limits: 36 | memory: "256Mi" 37 | cpu: "250m" 38 | ports: 39 | - containerPort: 8761 40 | livenessProbe: 41 | httpGet: 42 | path: /admin/health 43 | port: 8761 44 | initialDelaySeconds: 60 45 | timeoutSeconds: 30 46 | readinessProbe: 47 | httpGet: 48 | path: /admin/info 49 | port: 8761 50 | timeoutSeconds: 30 51 | env: 52 | - name: JAVA_OPTS 53 | value: -Xmx128m 54 | --- 55 | apiVersion: v1 56 | kind: Service 57 | metadata: 58 | name: zwitscher-config 59 | labels: 60 | zwitscher: config 61 | spec: 62 | # use NodePort here to be able to access the port on each node 63 | type: NodePort 64 | ports: 65 | - port: 8888 66 | selector: 67 | zwitscher: config 68 | --- 69 | apiVersion: extensions/v1beta1 70 | kind: Deployment 71 | metadata: 72 | name: zwitscher-config 73 | spec: 74 | replicas: 1 75 | minReadySeconds: 30 76 | template: 77 | metadata: 78 | labels: 79 | zwitscher: config 80 | spec: 81 | containers: 82 | - name: zwitscher-config 83 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-config:1.1.0" 84 | imagePullPolicy: Always 85 | resources: 86 | requests: 87 | memory: "128Mi" 88 | cpu: "125m" 89 | limits: 90 | memory: "256Mi" 91 | cpu: "250m" 92 | ports: 93 | - containerPort: 8888 94 | livenessProbe: 95 | httpGet: 96 | path: /admin/health 97 | port: 8888 98 | initialDelaySeconds: 90 99 | timeoutSeconds: 30 100 | readinessProbe: 101 | httpGet: 102 | path: /admin/info 103 | port: 8888 104 | timeoutSeconds: 30 105 | env: 106 | - name: EUREKA_HOST 107 | value: zwitscher-eureka 108 | - name: JAVA_OPTS 109 | value: -Xmx128m 110 | --- 111 | apiVersion: v1 112 | kind: Service 113 | metadata: 114 | name: zwitscher-service 115 | labels: 116 | zwitscher: service 117 | spec: 118 | # use NodePort here to be able to access the port on each node 119 | type: NodePort 120 | ports: 121 | - port: 8080 122 | selector: 123 | zwitscher: service 124 | --- 125 | apiVersion: extensions/v1beta1 126 | kind: Deployment 127 | metadata: 128 | name: zwitscher-service 129 | spec: 130 | replicas: 1 131 | minReadySeconds: 30 132 | template: 133 | metadata: 134 | labels: 135 | zwitscher: service 136 | spec: 137 | containers: 138 | - name: zwitscher-service 139 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service:1.1.0" 140 | imagePullPolicy: Always 141 | resources: 142 | requests: 143 | memory: "128Mi" 144 | cpu: "250m" 145 | limits: 146 | memory: "256Mi" 147 | cpu: "500m" 148 | ports: 149 | - containerPort: 8080 150 | livenessProbe: 151 | httpGet: 152 | path: /admin/health 153 | port: 8080 154 | initialDelaySeconds: 90 155 | timeoutSeconds: 30 156 | readinessProbe: 157 | httpGet: 158 | path: /admin/info 159 | port: 8080 160 | timeoutSeconds: 30 161 | env: 162 | - name: EUREKA_HOST 163 | value: zwitscher-eureka 164 | - name: JAVA_OPTS 165 | value: -Xmx128m 166 | --- 167 | apiVersion: v1 168 | kind: Service 169 | metadata: 170 | name: zwitscher-board 171 | labels: 172 | zwitscher: board 173 | spec: 174 | # use NodePort here to be able to access the port on each node 175 | type: NodePort 176 | ports: 177 | - port: 8081 178 | selector: 179 | zwitscher: board 180 | --- 181 | apiVersion: extensions/v1beta1 182 | kind: Deployment 183 | metadata: 184 | name: zwitscher-board 185 | spec: 186 | replicas: 1 187 | minReadySeconds: 30 188 | template: 189 | metadata: 190 | labels: 191 | zwitscher: board 192 | spec: 193 | containers: 194 | - name: zwitscher-board 195 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-board:1.1.0" 196 | imagePullPolicy: Always 197 | resources: 198 | requests: 199 | memory: "128Mi" 200 | cpu: "250m" 201 | limits: 202 | memory: "256Mi" 203 | cpu: "500m" 204 | ports: 205 | - containerPort: 8081 206 | livenessProbe: 207 | httpGet: 208 | path: /admin/health 209 | port: 8081 210 | initialDelaySeconds: 90 211 | timeoutSeconds: 30 212 | readinessProbe: 213 | httpGet: 214 | path: /admin/info 215 | port: 8081 216 | timeoutSeconds: 30 217 | env: 218 | - name: EUREKA_HOST 219 | value: zwitscher-eureka 220 | - name: JAVA_OPTS 221 | value: -Xmx128m 222 | --- 223 | apiVersion: v1 224 | kind: Service 225 | metadata: 226 | name: zwitscher-edge 227 | labels: 228 | zwitscher: edge 229 | spec: 230 | # if your cluster supports it, uncomment the following to automatically create 231 | # an external load-balanced IP for the frontend service. Does not work locally. 232 | type: LoadBalancer 233 | ports: 234 | - port: 8765 235 | selector: 236 | zwitscher: edge 237 | --- 238 | apiVersion: extensions/v1beta1 239 | kind: Deployment 240 | metadata: 241 | name: zwitscher-edge 242 | spec: 243 | replicas: 1 244 | minReadySeconds: 30 245 | template: 246 | metadata: 247 | labels: 248 | zwitscher: edge 249 | spec: 250 | containers: 251 | - name: zwitscher-edge 252 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-edge:1.1.0" 253 | imagePullPolicy: Always 254 | resources: 255 | requests: 256 | memory: "128Mi" 257 | cpu: "125m" 258 | limits: 259 | memory: "256Mi" 260 | cpu: "250m" 261 | ports: 262 | - containerPort: 8765 263 | livenessProbe: 264 | httpGet: 265 | path: /admin/health 266 | port: 8765 267 | initialDelaySeconds: 90 268 | timeoutSeconds: 30 269 | readinessProbe: 270 | httpGet: 271 | path: /admin/info 272 | port: 8765 273 | timeoutSeconds: 30 274 | env: 275 | - name: EUREKA_HOST 276 | value: zwitscher-eureka 277 | - name: JAVA_OPTS 278 | value: -Xmx128m 279 | --- 280 | apiVersion: v1 281 | kind: Service 282 | metadata: 283 | name: zwitscher-monitor 284 | labels: 285 | zwitscher: monitor 286 | spec: 287 | # use NodePort here to be able to access the port on each node 288 | type: NodePort 289 | ports: 290 | - port: 8989 291 | selector: 292 | zwitscher: monitor 293 | --- 294 | apiVersion: extensions/v1beta1 295 | kind: Deployment 296 | metadata: 297 | name: zwitscher-monitor 298 | spec: 299 | replicas: 1 300 | minReadySeconds: 30 301 | template: 302 | metadata: 303 | labels: 304 | zwitscher: monitor 305 | spec: 306 | containers: 307 | - name: zwitscher-monitor 308 | image: "qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-monitor:1.1.0" 309 | imagePullPolicy: Always 310 | resources: 311 | requests: 312 | memory: "128Mi" 313 | cpu: "125m" 314 | limits: 315 | memory: "256Mi" 316 | cpu: "250m" 317 | ports: 318 | - containerPort: 8989 319 | livenessProbe: 320 | httpGet: 321 | path: /admin/health 322 | port: 8989 323 | initialDelaySeconds: 120 324 | timeoutSeconds: 30 325 | readinessProbe: 326 | httpGet: 327 | path: /admin/info 328 | port: 8989 329 | timeoutSeconds: 30 330 | env: 331 | - name: EUREKA_HOST 332 | value: zwitscher-eureka 333 | - name: JAVA_OPTS 334 | value: -Xmx128m 335 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/qaware/cloud-native-zwitscher.svg?branch=master)](https://travis-ci.org/qaware/cloud-native-zwitscher) 2 | [![Stories in Ready](https://badge.waffle.io/qaware/cloud-native-zwitscher.png?label=ready&title=Ready)](https://waffle.io/qaware/cloud-native-zwitscher) 3 | [![Stories in Progress](https://badge.waffle.io/qaware/cloud-native-zwitscher.png?label=in%20progress&title=In%20Progress)](https://waffle.io/qaware/cloud-native-zwitscher) 4 | [![MIT License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://github.com/qaware/cloud-native-zwitscher/blob/master/LICENSE) 5 | 6 | # Cloud Native Zwitscher Showcase 7 | 8 | This showcase demonstrates how to build a cloud native application using 9 | Spring Boot, Spring Cloud and Netflix OSS components. The individual parts 10 | will later be deployed and run on Mesos with Kubernetes. 11 | 12 | ![Zwitscher Showcase Overview](zwitscher.png) 13 | 14 | ## Build instructions 15 | 16 | In order to compile and run the examples you do not need much. A recent JDK8 needs to 17 | be available in your SEU. 18 | ```shell 19 | $ ./gradlew clean build 20 | ``` 21 | 22 | ## Usage instructions 23 | 24 | For the showcase to be fully operational you need to configure your own Twitter API key and secret. First, follow 25 | the instructions on https://spring.io/guides/gs/register-twitter-app/. Once you have a API key and secret, insert 26 | these into the configuration `zwitscher-config/src/main/resources/config/zwitscher-service.yml` 27 | 28 | ```yml 29 | spring: 30 | social: 31 | twitter: 32 | appId: <> 33 | appSecret: <> 34 | ``` 35 | 36 | ## Running the Cloud Native Zwitscher showcase 37 | 38 | The showcase can be run on your local machine as well as on Mesos with Kubernetes. 39 | 40 | ### Local maschine 41 | 42 | To run the showcase locally build the showcase and run the individual parts in a 43 | separate console window. 44 | 45 | Start the Zwitscher Eureka server 46 | ```shell 47 | $ cd cloud-native-zwitscher 48 | $ ./gradlew :zwitscher-eureka:bootRun 49 | ``` 50 | 51 | Start the Zwitscher config server 52 | ```shell 53 | $ cd cloud-native-zwitscher 54 | $ ./gradlew :zwitscher-config:bootRun 55 | ``` 56 | 57 | Start the Zwitscher service server 58 | ```shell 59 | $ cd cloud-native-zwitscher 60 | $ ./gradlew :zwitscher-service:bootRun 61 | ``` 62 | 63 | Start the Zwitscher board UI server 64 | ```shell 65 | $ cd cloud-native-zwitscher 66 | $ ./gradlew :zwitscher-board:bootRun 67 | ``` 68 | 69 | Start the Zwitscher edge server 70 | ```shell 71 | $ cd cloud-native-zwitscher 72 | $ ./gradlew :zwitscher-edge:bootRun 73 | ``` 74 | 75 | Start the Zwitscher monitoring server 76 | ```shell 77 | $ cd cloud-native-zwitscher 78 | $ ./gradlew :zwitscher-monitor:bootRun 79 | ``` 80 | 81 | If everything has started OK, you can access the the services under the following URLs: 82 | 83 | * **Eureka server**: http://localhost:8761 84 | * **Config server**: http://localhost:8888 85 | * **Service server**: http://localhost:8080 86 | * **Board server**: http://localhost:8081 87 | * **Edge server**: http://localhost:8765 88 | * **Monitoring server**: http://localhost:8989 89 | 90 | 91 | ### Docker Compose 92 | 93 | To run the complete showcase using docker locally, please ensure that Docker is running and can be accessed 94 | by Gradle correctly: 95 | ```shell 96 | $ cd cloud-native-zwitscher 97 | $ ./gradlew dockerVersion dockerInfo 98 | ``` 99 | 100 | If the connection to the Docker daemon can be established, you will see some version and detail information printed 101 | in the console. Assuming you have already build the project, you need to build the Docker images: 102 | In order to compile and run the examples you do not need much. A recent JDK8 needs to 103 | be available in your SEU. 104 | ```shell 105 | $ ./gradlew buildDockerImage 106 | ``` 107 | 108 | Once this is done, open a Docker terminal and issue the following command in the project directory: 109 | 110 | ```shell 111 | $ cd cloud-native-zwitscher 112 | $ docker-compose up -d 113 | $ docker-compose logs 114 | ``` 115 | 116 | This will start all the Docker images in the correct order. The instances can then be accessed via their known ports 117 | and the IP address of your Docker installation, usually something like `192.168.99.100`. 118 | 119 | To shutdown and remove everything again, kill and remove the Docker containers first, and finally you can remove the 120 | Docker images again if you wish. 121 | 122 | ```shell 123 | $ docker-compose kill 124 | $ docker-compose rm 125 | $ ./gradlew removeDockerImage 126 | ``` 127 | 128 | ### Kubernetes 129 | 130 | #### Installation 131 | 132 | Before you can run anything, you need to setup the actual Kubernetes installation you want 133 | to deploy the showcase to. For local development use Vagrant, otherwise choose a cloud provider such as AWS or GCE. There are 3 shell scripts provided (`k8s-setup-vagrant.sh`, `k8s-setup-aws.sh`, `k8s-setup-gce.sh`). For AWS and GCE you need to configure your environment 134 | properly and you need to have a paid account. For more details on the prerequisites read 135 | the official [Getting Started Guides](http://kubernetes.io/docs/getting-started-guides/). 136 | 137 | To verify that your Kubernetes cluster is alive and healthy, issue the following command: 138 | ```shell 139 | kubectl.sh cluster-info 140 | ``` 141 | 142 | #### Preparation 143 | 144 | In order to run the showcase using Kubernetes on either AWS, GCE or Vagrant you 145 | need to Dockerize the showcase. If you plan to use AWS or GCE, stop reading here: 146 | the images are already available at the QAware OSS Bintray Docker registry. 147 | 148 | If you plan to deploy and run the showcase locally or you want to use your own 149 | Docker registry then continue. Basically, following the instructions above on how 150 | to build the Docker images using Gradle. 151 | 152 | Then tag the latest images by running the following command. You will have to substitute 153 | the `qaware-oss-docker-registry.bintray.io` registry URL with your custom URL. 154 | ```shell 155 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-eureka: 156 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-config: 157 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service: 158 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-board: 159 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-edge: 160 | docker tag qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-monitor: 161 | ``` 162 | `` - The image ID from the latest versioned image previously created. 163 | `` - Should be the actual Zwitscher showcase version, like 1.1.0. When not specified 164 | "latest" will be used as the Bintray version name. 165 | 166 | Use the Docker client push command to upload and publish your images (please use 167 | Docker v1.6 and above): 168 | ```shell 169 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-eureka 170 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-config 171 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-service 172 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-board 173 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-edge 174 | docker push qaware-oss-docker-registry.bintray.io/zwitscher/zwitscher-monitor 175 | ``` 176 | 177 | Alternatively you can also use Gradle to upload the Docker images to your Bintray 178 | Docker registry. 179 | ```shell 180 | $ ./gradlew pushDockerImage -PbintrayUsername=<> -PbintrayApiKey=<> 181 | ``` 182 | 183 | #### Deployments 184 | 185 | Now you can create the Kubernetes deployments one by one and see how the Zwitscher 186 | showcase becomes alive. In the project root directory issue the following commands: 187 | ```shell 188 | kubectl.sh create -f zwitscher-eureka/k8s-zwitscher-eureka.yml 189 | kubectl.sh create -f zwitscher-config/k8s-zwitscher-config.yml 190 | kubectl.sh create -f zwitscher-service/k8s-zwitscher-service.yml 191 | kubectl.sh create -f zwitscher-board/k8s-zwitscher-board.yml 192 | kubectl.sh create -f zwitscher-edge/k8s-zwitscher-edge.yml 193 | kubectl.sh create -f zwitscher-monitor/k8s-zwitscher-monitor.yml 194 | kubectl.sh get pods,deployments,services 195 | kubectl.sh scale deployment zwitscher-service --replicas=2 196 | kubectl.sh get pods,deployments 197 | ``` 198 | 199 | To setup or tear down the whole Zwitscher Showcase at once you can also use the provided 200 | full Kubernetes deployment descriptor: 201 | ```shell 202 | kubectl.sh create -f k8s-zwitscher.yml 203 | kubectl.sh get pods,deployments,services 204 | kubectl.sh delete -f k8s-zwitscher.yml 205 | ``` 206 | 207 | ### DC/OS 208 | 209 | You need a DC/OS cluster with at least 3GB free RAM. 210 | That amounts to one instance of each service. 211 | You can use the DC/OS Vagrant to run a DC/OS cluster on your local machine, 212 | provided your computer has at least 16GB of RAM 213 | (https://github.com/dcos/dcos-vagrant). 214 | 215 | With DC/OS Vagrant installed, use the following command to spin up a properly 216 | sized cluster. 217 | ```shell 218 | vagrant up m1 a1 a2 a3 boot 219 | ``` 220 | 221 | Each service comes with it's own Marathon config file. You can deploy the 222 | services one at a time or all at once. 223 | 224 | Example deployment of the config service: 225 | ```shell 226 | curl -X POST http://m1.dcos:8080/v2/apps -H "Content-type: application/json" -d @zwitscher-config/marathon-zwitscher-config.json 227 | ``` 228 | 229 | Deploying all services at once: 230 | ```shell 231 | ./marathon-deploy-all.sh 232 | ``` 233 | 234 | #### Troubleshooting 235 | 236 | * *The download of the docker images takes longer than the health check grace 237 | period in Marathon.* 238 | This may lead to Marathon perpetually trying and failing to deploy a service. 239 | In case of this error, try downloading the images manually with Docker on the 240 | cluster workers. 241 | * *Not enough free memory on the VirtualBox Host.* 242 | This usually leads to a dead slow cluster and may cause spurious errors. ensure 243 | that you run the showcase on a host with at least 16 GB RAM, of which 13 GB must 244 | remain free. 245 | * *Other spurious errors.* 246 | The setup has a lot of moving parts that might break down. In case you run into 247 | errors that are not easily identifyable, try tearing down and re-creating the 248 | cluster: 249 | ```shell 250 | vagrant destroy -f m1 a1 a2 a3 boot 251 | vagrant up m1 a1 a2 a3 boot 252 | ``` 253 | 254 | ## References 255 | 256 | * [Spring Initializr](https://start.spring.io) 257 | * [Spring Cloud](http://projects.spring.io/spring-cloud/) 258 | 259 | ## License 260 | 261 | This software is provided under the MIT open source license, read the `LICENSE.txt` file for details. 262 | --------------------------------------------------------------------------------