diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
new file mode 100644
index 0000000..7cf77fe
--- /dev/null
+++ b/docker/docker-compose.yml
@@ -0,0 +1,20 @@
+version: "3.0"
+
+services:
+ eureka-server:
+ container_name: eureka
+ image: springcloud/eureka
+ ports:
+ - "8761:8761"
+ redis:
+ container_name: redis
+ image: redis
+ ports:
+ - "6379:6379"
+ mongo:
+ container_name: mongo
+ image: mongo
+ ports:
+ - "27017:27017"
+ volumes:
+ - "${MONGO_VOLUME}:/var/lib/mongodb"
\ No newline at end of file
diff --git a/docker/kubernetes/ui-interface.yml b/docker/kubernetes/ui-interface.yml
index 23dbd88..379d349 100644
--- a/docker/kubernetes/ui-interface.yml
+++ b/docker/kubernetes/ui-interface.yml
@@ -4,6 +4,13 @@ metadata:
name: ui-interface
data:
application.yaml: |-
+ ribbon:
+ eureka:
+ enabled: false
+ client:
+ enabled: true
+ ServerListRefreshInterval: 50
+
spring:
cloud:
gateway:
diff --git a/docker/mongo.yml b/docker/mongo.yml
deleted file mode 100644
index 9ea08ff..0000000
--- a/docker/mongo.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mongo
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: mongo
- template:
- metadata:
- labels:
- app: mongo
- spec:
- containers:
- - name: mongo
- image: mongo
- imagePullPolicy: "IfNotPresent"
- ports:
- - containerPort: 27017
-
----
-
-kind: Service
-apiVersion: v1
-metadata:
- name: mongo-svc
-spec:
- selector:
- app: mongo
- ports:
- - port: 27017
\ No newline at end of file
diff --git a/docker/starter.sh b/docker/starter.sh
new file mode 100644
index 0000000..73d5207
--- /dev/null
+++ b/docker/starter.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+docker-compose up 2>docker.log &
+
+cd ..
+
+PROJECT_HOME=`pwd`
+
+HELLO_SERVICE_JAR_DIR=$PROJECT_HOME/hello-service/build/libs
+MESSAGE_SERVICE_JAR_DIR=$PROJECT_HOME/message-service/build/libs
+UI_JAR_DIR=$PROJECT_HOME/ui/target
+
+echo "The content of PROJECT_HOME is: $PROJECT_HOME"
+echo "The content of HELLO_SERVICE_JAR_DIR is: $HELLO_SERVICE_JAR_DIR"
+echo "The content of MESSAGE_SERVICE_JAR_DIR is: $MESSAGE_SERVICE_JAR_DIR"
+echo "The content of UI_JAR_DIR is: $UI_JAR_DIR"
+
+
+echo "start of hello-service"
+cd $HELLO_SERVICE_JAR_DIR
+java -jar -Dspring.profiles.active=netflix hello-service.jar >$PROJECT_HOME/hello-service.log &
+
+
+echo "start of message-service"
+cd $MESSAGE_SERVICE_JAR_DIR
+java -jar -Dspring.profiles.active=netflix message-service.jar >$PROJECT_HOME/message-service.log &
+
+
+#echo "start of ui"
+#cd $UI_JAR_DIR
+#java -jar -Dspring.profiles.active=netflix ui-interface.jar >$PROJECT_HOME/ui-interface.log &
diff --git a/hello-service/build.gradle b/hello-service/build.gradle
index e8cec9e..495921f 100644
--- a/hello-service/build.gradle
+++ b/hello-service/build.gradle
@@ -27,11 +27,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
-
- implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
- implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
- implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-ribbon'
-
+
compile 'org.projectlombok:lombok:1.18.6'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
@@ -52,3 +48,5 @@ docker {
pull true
noCache true
}
+
+apply from: rootProject.file('profile.gradle');
\ No newline at end of file
diff --git a/hello-service/profile.gradle b/hello-service/profile.gradle
new file mode 100644
index 0000000..3854b4c
--- /dev/null
+++ b/hello-service/profile.gradle
@@ -0,0 +1,12 @@
+if (project.hasProperty('kubernetes')) {
+ println("kubernetes")
+ dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
+ }
+} else if (project.hasProperty('netflix')) {
+ println("netflix")
+ dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
+ }
+}
\ No newline at end of file
diff --git a/hello-service/profiles/kubernetes_build.gradle b/hello-service/profiles/kubernetes_build.gradle
new file mode 100644
index 0000000..8986dc6
--- /dev/null
+++ b/hello-service/profiles/kubernetes_build.gradle
@@ -0,0 +1,4 @@
+dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
+}
\ No newline at end of file
diff --git a/hello-service/profiles/netflix_build.gradle b/hello-service/profiles/netflix_build.gradle
new file mode 100644
index 0000000..f6b40be
--- /dev/null
+++ b/hello-service/profiles/netflix_build.gradle
@@ -0,0 +1,3 @@
+dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
+}
\ No newline at end of file
diff --git a/hello-service/src/main/kubernetes/hello-service-k8s.yml b/hello-service/src/main/kubernetes/hello-service-k8s.yml
deleted file mode 100644
index 6ac9b75..0000000
--- a/hello-service/src/main/kubernetes/hello-service-k8s.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: hello-service-config
- labels:
- app: hello-service
-data:
- hello-service-uri: "http://message-service/message/random"
-
----
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: hello-service-deployment
- labels:
- app: hello-service
-spec:
- replicas: 3
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxSurge: 1
- maxUnavailable: 25%
- selector:
- matchLabels:
- app: hello-service
- template:
- metadata:
- labels:
- app: hello-service
- spec:
- containers:
- - name: hello-service
- image: mrflick72/hello-service:latest
- ports:
- - containerPort: 8080
-
- livenessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
-
- readinessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
- envFrom:
- - configMapRef:
- name: hello-service-config
-
----
-
-kind: Service
-apiVersion: v1
-metadata:
- name: hello-service-svc
-spec:
- selector:
- app: hello-service
- ports:
- - protocol: TCP
- port: 8080
----
-
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: hello-service-ingress
- annotations:
- nginx.ingress.kubernetes.io/rewrite-target: /$1
-spec:
- rules:
- - http:
- paths:
- - path: /hello-service/?(.*)
- backend:
- serviceName: hello-service-svc
- servicePort: 8080
\ No newline at end of file
diff --git a/hello-service/src/main/resources/application-netflix.yml b/hello-service/src/main/resources/application-netflix.yml
new file mode 100644
index 0000000..05ddf29
--- /dev/null
+++ b/hello-service/src/main/resources/application-netflix.yml
@@ -0,0 +1,9 @@
+server:
+ use-forward-headers: true
+ port: 7070
+
+hello-service-uri: http://message-service/message/random
+
+management:
+ server:
+ port: 7071
\ No newline at end of file
diff --git a/message-service/build.gradle b/message-service/build.gradle
index ddc1f08..cf2071e 100644
--- a/message-service/build.gradle
+++ b/message-service/build.gradle
@@ -25,9 +25,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
- implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
- implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
-
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-reflect'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
@@ -36,6 +33,7 @@ dependencies {
testImplementation 'io.projectreactor:reactor-test'
}
+
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
@@ -64,3 +62,5 @@ docker {
pull true
noCache true
}
+
+apply from: rootProject.file('profile.gradle');
\ No newline at end of file
diff --git a/message-service/profile.gradle b/message-service/profile.gradle
new file mode 100644
index 0000000..3854b4c
--- /dev/null
+++ b/message-service/profile.gradle
@@ -0,0 +1,12 @@
+if (project.hasProperty('kubernetes')) {
+ println("kubernetes")
+ dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
+ }
+} else if (project.hasProperty('netflix')) {
+ println("netflix")
+ dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
+ }
+}
\ No newline at end of file
diff --git a/message-service/profiles/kubernetes_build.gradle b/message-service/profiles/kubernetes_build.gradle
new file mode 100644
index 0000000..8986dc6
--- /dev/null
+++ b/message-service/profiles/kubernetes_build.gradle
@@ -0,0 +1,4 @@
+dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes'
+ implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
+}
\ No newline at end of file
diff --git a/message-service/profiles/netflix_build.gradle b/message-service/profiles/netflix_build.gradle
new file mode 100644
index 0000000..f6b40be
--- /dev/null
+++ b/message-service/profiles/netflix_build.gradle
@@ -0,0 +1,3 @@
+dependencies {
+ implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
+}
\ No newline at end of file
diff --git a/message-service/src/main/kotlin/it/valeriovaudi/messageservice/MessageServiceApplication.kt b/message-service/src/main/kotlin/it/valeriovaudi/messageservice/MessageServiceApplication.kt
index f332a8d..8bed833 100644
--- a/message-service/src/main/kotlin/it/valeriovaudi/messageservice/MessageServiceApplication.kt
+++ b/message-service/src/main/kotlin/it/valeriovaudi/messageservice/MessageServiceApplication.kt
@@ -68,5 +68,11 @@ class MessageRoute(private val messageRepository: MessageRepository) {
}
.flatMap { noContent().build() }
}
+
+ DELETE("/message/{messageId}") {
+ val messageId = it.pathVariable("messageId")
+ messageRepository.deleteById(messageId)
+ .flatMap { noContent().build() }
+ }
}
}
\ No newline at end of file
diff --git a/message-service/src/main/kubernetes/message-service-k8s.yml b/message-service/src/main/kubernetes/message-service-k8s.yml
deleted file mode 100644
index 548b43e..0000000
--- a/message-service/src/main/kubernetes/message-service-k8s.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: message-service-config
- labels:
- app: message-service
-data:
- SPRING_DATA_MONGODB_HOST: "mongo-svc"
- SERVER_USEFORWARDHEADERS: "true"
-
----
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: message-service-deployment
- labels:
- app: message-service
-spec:
- replicas: 3
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxSurge: 1
- maxUnavailable: 25%
- selector:
- matchLabels:
- app: message-service
- template:
- metadata:
- labels:
- app: message-service
- spec:
- containers:
- - name: message-service
- image: mrflick72/message-service:latest
- ports:
- - containerPort: 8080
-
- livenessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
-
- readinessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
- envFrom:
- - configMapRef:
- name: message-service-config
----
-
-kind: Service
-apiVersion: v1
-metadata:
- name: message-service
-spec:
- selector:
- app: message-service
- ports:
- - protocol: TCP
- port: 8080
- targetPort: 8080
----
-
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: message-service-ingress
- annotations:
- nginx.ingress.kubernetes.io/rewrite-target: /$1
-spec:
- rules:
- - host: message-service.com
- http:
- paths:
- - path: /message-service/?(.*)
- backend:
- serviceName: message-service
- servicePort: 8080
diff --git a/message-service/src/main/resources/application-netflix.yml b/message-service/src/main/resources/application-netflix.yml
new file mode 100644
index 0000000..8660fad
--- /dev/null
+++ b/message-service/src/main/resources/application-netflix.yml
@@ -0,0 +1,7 @@
+server:
+ use-forward-headers: true
+ port: 9090
+
+management:
+ server:
+ port: 9091
\ No newline at end of file
diff --git a/ui/pom.xml b/ui/pom.xml
index d7f513c..8d2a625 100644
--- a/ui/pom.xml
+++ b/ui/pom.xml
@@ -20,19 +20,20 @@
+
- org.springframework.cloud
- spring-cloud-starter-kubernetes
+ org.springframework.session
+ spring-session-core
- org.springframework.cloud
- spring-cloud-starter-kubernetes-config
+ org.springframework.boot
+ spring-boot-starter-data-redis
- org.springframework.cloud
- spring-cloud-starter-kubernetes-ribbon
+ org.springframework.session
+ spring-session-data-redis
@@ -45,6 +46,11 @@
spring-boot-starter-actuator
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
org.springframework.boot
spring-boot-starter-test
@@ -64,6 +70,38 @@
+
+
+ netflix
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-client
+
+
+
+
+
+ kubernetes
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes-config
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes-ribbon
+
+
+
+
+
ui-interface
@@ -73,6 +111,50 @@
spring-boot-maven-plugin
+
+ com.github.eirslett
+ frontend-maven-plugin
+ 1.6
+
+
+ src/main/frontend
+
+
+
+
+ install node and npm
+
+ install-node-and-npm
+
+
+ v9.8.0
+ 5.8.0
+
+
+
+
+ npm install
+
+ npm
+
+
+ install
+
+
+
+
+ npm build
+
+ npm
+
+
+ run-script build
+
+
+
+
+
+
com.spotify
docker-maven-plugin
diff --git a/ui/src/main/frontend/app/component/Jumbotron.js b/ui/src/main/frontend/app/component/Jumbotron.js
new file mode 100644
index 0000000..23e8ad5
--- /dev/null
+++ b/ui/src/main/frontend/app/component/Jumbotron.js
@@ -0,0 +1,15 @@
+import React from "react"
+
+export default ({title, leadSection, bottomSection}) => {
+ return
+
{title}
+
+
+ {leadSection}
+
+
+
+
+ {bottomSection}
+
+}
diff --git a/ui/src/main/frontend/app/component/TextInputForm.js b/ui/src/main/frontend/app/component/TextInputForm.js
new file mode 100644
index 0000000..9edb9bd
--- /dev/null
+++ b/ui/src/main/frontend/app/component/TextInputForm.js
@@ -0,0 +1,11 @@
+import React from "react"
+
+export default ({value, onChangeHandler, componentId, componentLabel, componentPlaceholder, inputRef}) => {
+ return
+
+
+
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/app/messages-site/MessageSiteApp.js b/ui/src/main/frontend/app/messages-site/MessageSiteApp.js
new file mode 100644
index 0000000..e32b076
--- /dev/null
+++ b/ui/src/main/frontend/app/messages-site/MessageSiteApp.js
@@ -0,0 +1,73 @@
+import React from "react"
+import Jumbotron from "../component/Jumbotron";
+import MessageRepository from "../repository/MessageRepository";
+import TextInputForm from "../component/TextInputForm";
+
+export default class MessageSiteApp extends React.Component {
+
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ messages: []
+ };
+
+ this.inputRef = React.createRef();
+ this.messageRepository = new MessageRepository();
+ this.saveMessage = this.saveMessage.bind(this);
+ this.displayMessages = this.displayMessages.bind(this);
+ }
+
+ saveMessage() {
+ this.messageRepository
+ .saveMessage({message: this.inputRef.current.value})
+ .then(response => this.displayMessages())
+ }
+
+ componentDidMount() {
+ this.displayMessages();
+ }
+
+ displayMessages() {
+ this.messageRepository.findMessages()
+ .then(data => {
+ console.log(data)
+ this.setState({messages: data})
+ })
+ }
+
+ deleteMessage(messageId) {
+ this.messageRepository.deleteMessage(messageId)
+ .then(response => {
+ this.displayMessages()
+ })
+ }
+
+ render() {
+ let leadSection =
+
+ let bottomSection =
+
+ {this.state.messages.map(message => {
+ return -
+ {message.message}
+
+ Delete
+
+
+ })}
+
+ return
+ }
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/app/messages-site/index.js b/ui/src/main/frontend/app/messages-site/index.js
new file mode 100644
index 0000000..b7a7b7e
--- /dev/null
+++ b/ui/src/main/frontend/app/messages-site/index.js
@@ -0,0 +1,7 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import MessageSiteApp from "./MessageSiteApp";
+
+if(document.getElementById('app')){
+ ReactDOM.render(, document.getElementById('app'));
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/app/repository/MessageRepository.js b/ui/src/main/frontend/app/repository/MessageRepository.js
new file mode 100644
index 0000000..f7750c4
--- /dev/null
+++ b/ui/src/main/frontend/app/repository/MessageRepository.js
@@ -0,0 +1,40 @@
+const SAY_HELLO_TO = (name) => `/ui/hello-service/hello/${name}`;
+const SAVE_A_NEW_MESSAGE = "/ui/message-service/message";
+const DELETE_A_MESSAGE = (messageId) => `/ui/message-service/message/${messageId}`;
+
+export default class MessageRepository {
+
+ sayHelloTo(name) {
+ return fetch(SAY_HELLO_TO(name))
+ .then(data => data.text());
+ }
+
+ saveMessage(message) {
+ return fetch(SAVE_A_NEW_MESSAGE, {
+ method: "POST",
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(message),
+ credentials: 'same-origin'
+ })
+ }
+
+ findMessages() {
+ return fetch(SAVE_A_NEW_MESSAGE, {
+ method: "GET",
+ headers: {
+ 'Accept': 'application/json'
+ },
+ credentials: 'same-origin'
+ }).then(response => response.json())
+ }
+
+
+ deleteMessage(messageId) {
+ return fetch(DELETE_A_MESSAGE(messageId), {
+ method: "DELETE",
+ credentials: 'same-origin'
+ })
+ }
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/app/site/MainSiteApp.js b/ui/src/main/frontend/app/site/MainSiteApp.js
new file mode 100644
index 0000000..ed56cc7
--- /dev/null
+++ b/ui/src/main/frontend/app/site/MainSiteApp.js
@@ -0,0 +1,42 @@
+import React from "react"
+import Jumbotron from "../component/Jumbotron";
+import MessageRepository from "../repository/MessageRepository";
+import TextInputForm from "../component/TextInputForm";
+
+export default class MainSiteApp extends React.Component {
+
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ message: "No message right now"
+ };
+
+ this.inputRef = React.createRef();
+ this.messageRepository = new MessageRepository();
+ this.sayHello = this.sayHello.bind(this);
+ }
+
+ sayHello() {
+ this.messageRepository
+ .sayHelloTo(this.inputRef.current.value)
+ .then(message => this.setState({message: message}))
+ }
+
+ render() {
+ let leadSection =
+ let bottomSection = {this.state.message}
+
+ return
+ }
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/app/site/index.js b/ui/src/main/frontend/app/site/index.js
new file mode 100644
index 0000000..c0b8505
--- /dev/null
+++ b/ui/src/main/frontend/app/site/index.js
@@ -0,0 +1,7 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import MainSiteApp from "./MainSiteApp";
+
+if(document.getElementById('app')){
+ ReactDOM.render(, document.getElementById('app'));
+}
\ No newline at end of file
diff --git a/ui/src/main/frontend/package.json b/ui/src/main/frontend/package.json
new file mode 100644
index 0000000..b927fcd
--- /dev/null
+++ b/ui/src/main/frontend/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "ui",
+ "version": "1.0.0",
+ "description": "UI of My say hello on kubernetes",
+ "babel": {
+ "presets": [
+ "react",
+ "env"
+ ]
+ },
+ "scripts": {
+ "build": "webpack --config webpack.config.js",
+ "watch": "webpack --watch"
+ },
+ "author": "mrFlick72",
+ "license": "ISC",
+ "devDependencies": {
+ "babel-core": "^6.26.2",
+ "babel-preset-env": "^1.6.1",
+ "babel-preset-react": "^6.24.1",
+ "clean-webpack-plugin": "^0.1.19",
+ "css-loader": "^0.28.11",
+ "html-webpack-plugin": "^3.2.0",
+ "uglifyjs-webpack-plugin": "^2.1.1",
+ "webpack": "^4.29.0",
+ "webpack-cli": "^3.3.1"
+ },
+ "dependencies": {
+ "acorn": "^6.1.1",
+ "babel-loader": "^7.1.4",
+ "build": "^0.1.4",
+ "prop-types": "^15.6.1",
+ "react": "^16.3.2",
+ "react-dom": "^16.3.2",
+ "style-loader": "^0.21.0"
+ }
+}
diff --git a/ui/src/main/frontend/webpack.config.js b/ui/src/main/frontend/webpack.config.js
new file mode 100644
index 0000000..fb82e7b
--- /dev/null
+++ b/ui/src/main/frontend/webpack.config.js
@@ -0,0 +1,50 @@
+var path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+const BUID_DIR = path.resolve(__dirname + "../../../../target/classes/static");
+
+module.exports = {
+ // mode: 'production',
+ entry: {
+ site: path.resolve(__dirname, './app/site/index.js'),
+ messagesSite: path.resolve(__dirname, './app/messages-site/index.js')
+ },
+ resolve: {
+ extensions: [".js", ".jsx"]
+ },
+ plugins: [
+ new HtmlWebpackPlugin({
+ chunks: ['site'],
+ filename: "index.html",
+ template: path.resolve(__dirname, "../resources/static/index.html")
+ }),
+ new HtmlWebpackPlugin({
+ chunks: ['messagesSite'],
+ filename: "messages.html",
+ template: path.resolve(__dirname, "../resources/static/messages.html")
+ })
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: ['style-loader', 'css-loader']
+ },
+ {
+ test: path.join(__dirname, "."),
+ exclude: path.resolve(__dirname, "node_modules"),
+ use: {
+ loader: "babel-loader",
+ options: {
+ presets: ["env", "react"]
+ }
+ }
+
+ }
+ ]
+ },
+ output: {
+ filename: '[name]_[hash]_bundle.js',
+ path: BUID_DIR
+ }
+};
\ No newline at end of file
diff --git a/ui/src/main/java/it/valeriovaudi/ui/UiApplication.java b/ui/src/main/java/it/valeriovaudi/ui/UiApplication.java
index 6a986b0..a634eed 100644
--- a/ui/src/main/java/it/valeriovaudi/ui/UiApplication.java
+++ b/ui/src/main/java/it/valeriovaudi/ui/UiApplication.java
@@ -3,6 +3,18 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.authorization.AuthorizationDecision;
+import org.springframework.security.authorization.ReactiveAuthorizationManager;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.server.SecurityWebFilterChain;
+import reactor.core.publisher.Mono;
+
+import static java.util.Arrays.asList;
@EnableDiscoveryClient
@SpringBootApplication
@@ -12,4 +24,36 @@ public static void main(String[] args) {
SpringApplication.run(UiApplication.class, args);
}
+}
+
+@EnableWebFluxSecurity
+class SecurityConfig {
+
+ @Bean
+ public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
+ return http.csrf().disable().authorizeExchange()
+ .pathMatchers("/index.html").hasRole("USER")
+ .pathMatchers("/messages.html").hasRole("ADMIN")
+ .anyExchange().permitAll()
+ .and().formLogin()
+ .and().logout()
+ .and().build();
+ }
+
+ @Bean
+ public MapReactiveUserDetailsService userDetailsService() {
+ UserDetails user = User.withDefaultPasswordEncoder()
+ .username("user")
+ .password("secret")
+ .roles("USER")
+ .build();
+
+ UserDetails admin = User.withDefaultPasswordEncoder()
+ .username("admin")
+ .password("secret")
+ .roles("ADMIN")
+ .build();
+
+ return new MapReactiveUserDetailsService(asList(admin, user));
+ }
}
\ No newline at end of file
diff --git a/ui/src/main/kubernetes/ui-interface-k8s.yml b/ui/src/main/kubernetes/ui-interface-k8s.yml
deleted file mode 100644
index 9f4899d..0000000
--- a/ui/src/main/kubernetes/ui-interface-k8s.yml
+++ /dev/null
@@ -1,95 +0,0 @@
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: ui-interface
-data:
- application.yaml: |-
- ribbon:
- eureka:
- enabled: false
- client:
- enabled: true
- ServerListRefreshInterval: 50
-
- spring:
- cloud:
- gateway:
- routes:
- - id: hello-service
- uri: lb://hello-service-svc/
- predicates:
- - Path=/hello-service/**
- filters:
- - StripPrefix=1
-
----
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: ui-interface-deployment
- labels:
- app: ui-interface
-spec:
- replicas: 3
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxSurge: 1
- maxUnavailable: 25%
- selector:
- matchLabels:
- app: ui-interface
- template:
- metadata:
- labels:
- app: ui-interface
- spec:
- containers:
- - name: ui-interface
- image: mrflick72/ui-interface:latest
- ports:
- - containerPort: 8080
- livenessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
-
- readinessProbe:
- httpGet:
- path: /actuator/health
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 5
- successThreshold: 1
----
-
-kind: Service
-apiVersion: v1
-metadata:
- name: ui-interface
-spec:
- selector:
- app: ui-interface
- ports:
- - protocol: TCP
- port: 808
----
-
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: ui-interface-ingress
- annotations:
- nginx.ingress.kubernetes.io/rewrite-target: /$1
-spec:
- rules:
- - http:
- paths:
- - path: /ui/?(.*)
- backend:
- serviceName: ui-interface
- servicePort: 8080
diff --git a/ui/src/main/resources/application-netflix.yml b/ui/src/main/resources/application-netflix.yml
new file mode 100644
index 0000000..f1ce346
--- /dev/null
+++ b/ui/src/main/resources/application-netflix.yml
@@ -0,0 +1,16 @@
+spring:
+ cloud:
+ gateway:
+ routes:
+ - id: hello-service
+ uri: lb://hello-service/
+ predicates:
+ - Path=/ui/hello-service/**
+ filters:
+ - StripPrefix=2
+ - id: message-service
+ uri: lb://message-service/
+ predicates:
+ - Path=/ui/message-service/**
+ filters:
+ - StripPrefix=2
\ No newline at end of file
diff --git a/ui/src/main/resources/static/index.html b/ui/src/main/resources/static/index.html
index 43d9b89..e96b4b2 100644
--- a/ui/src/main/resources/static/index.html
+++ b/ui/src/main/resources/static/index.html
@@ -10,20 +10,7 @@
-
-
-
Hello, world!
-
-
-
-
-
+
-