Skip to content

Commit

Permalink
Adding Istio
Browse files Browse the repository at this point in the history
  • Loading branch information
piomin committed Jul 21, 2020
1 parent 6eef6c9 commit c1e182d
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 9 deletions.
45 changes: 44 additions & 1 deletion simple-microservices/department-service/k8s/deployment.yaml
@@ -1,21 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: department-deployment
name: department-deployment-v1
spec:
selector:
matchLabels:
app: department
version: v1
template:
metadata:
labels:
app: department
version: v1
spec:
containers:
- name: department
image: piomin/department-service
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /etc/podinfo
name: podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: department-deployment-v2
spec:
selector:
matchLabels:
app: department
version: v2
template:
metadata:
labels:
app: department
version: v2
spec:
containers:
- name: department
image: piomin/department-service
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /etc/podinfo
name: podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
---
apiVersion: v1
kind: Service
Expand Down
42 changes: 42 additions & 0 deletions simple-microservices/department-service/k8s/istio.yaml
@@ -0,0 +1,42 @@
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: department-service-destination
spec:
host: department-service.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: department-service-route
spec:
hosts:
- department-service.default.svc.cluster.local
http:
- match:
- headers:
X-Version:
exact: v1
route:
- destination:
host: department-service.default.svc.cluster.local
subset: v1
- match:
- headers:
X-Version:
exact: v2
route:
- destination:
host: department-service.default.svc.cluster.local
subset: v2
- route:
- destination:
host: department-service.default.svc.cluster.local
subset: v1
@@ -1,18 +1,24 @@
package pl.piomin.samples.kubernetes.department

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import org.springframework.web.client.RestTemplate
import pl.piomin.samples.kubernetes.department.interceptor.RestTemplateInterceptor
import java.time.Duration

@SpringBootApplication
class DepartmentApp {

@Autowired
lateinit var interceptor: RestTemplateInterceptor

@Bean
fun restTemplate(): RestTemplate =
RestTemplateBuilder()
.interceptors(interceptor)
.setReadTimeout(Duration.ofMillis(1000L))
.build()
}
Expand Down
@@ -0,0 +1,20 @@
package pl.piomin.samples.kubernetes.department.interceptor

import org.springframework.http.HttpRequest
import org.springframework.http.client.ClientHttpRequestExecution
import org.springframework.http.client.ClientHttpRequestInterceptor
import org.springframework.http.client.ClientHttpResponse
import org.springframework.stereotype.Component
import pl.piomin.samples.kubernetes.department.service.AppVersion

@Component
class RestTemplateInterceptor(val appVersion: AppVersion): ClientHttpRequestInterceptor {

override fun intercept(req: HttpRequest,
body: ByteArray,
execution: ClientHttpRequestExecution): ClientHttpResponse {
req.headers.add("X-Version", appVersion.getVersion())
return execution.execute(req, body)
}

}
@@ -0,0 +1,16 @@
package pl.piomin.samples.kubernetes.department.service

import org.springframework.stereotype.Service
import java.io.File

@Service
class AppVersion {

fun getVersion(): String? {
val file = File("/etc/podinfo/labels")
return if(file.exists()) {
file.readLines().first{ it.startsWith("version=")}
.split("=")[1]
} else null
}
}
45 changes: 44 additions & 1 deletion simple-microservices/employee-service/k8s/deployment.yaml
@@ -1,21 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: employee-deployment
name: employee-deployment-v1
spec:
selector:
matchLabels:
app: employee
version: v1
template:
metadata:
labels:
app: employee
version: v1
spec:
containers:
- name: employee
image: piomin/employee-service
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /etc/podinfo
name: podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: employee-deployment-v2
spec:
selector:
matchLabels:
app: employee
version: v2
template:
metadata:
labels:
app: employee
version: v2
spec:
containers:
- name: employee
image: piomin/employee-service
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /etc/podinfo
name: podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
---
apiVersion: v1
kind: Service
Expand Down
42 changes: 42 additions & 0 deletions simple-microservices/employee-service/k8s/istio.yaml
@@ -0,0 +1,42 @@
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: employee-service-destination
spec:
host: employee-service.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: employee-service-route
spec:
hosts:
- employee-service.default.svc.cluster.local
http:
- match:
- headers:
X-Version:
exact: v1
route:
- destination:
host: employee-service.default.svc.cluster.local
subset: v1
- match:
- headers:
X-Version:
exact: v2
route:
- destination:
host: employee-service.default.svc.cluster.local
subset: v2
- route:
- destination:
host: employee-service.default.svc.cluster.local
subset: v1
@@ -1,28 +1,49 @@
package pl.piomin.samples.kubernetes.employee.controller

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import pl.piomin.samples.kubernetes.employee.domain.Employee
import pl.piomin.samples.kubernetes.employee.domain.dto.AbstractEmployeeDTO
import pl.piomin.samples.kubernetes.employee.domain.dto.EmployeeV1DTO
import pl.piomin.samples.kubernetes.employee.domain.dto.EmployeeV2DTO
import pl.piomin.samples.kubernetes.employee.repository.EmployeeRepository
import pl.piomin.samples.kubernetes.employee.service.AppVersion
import java.util.*

@RestController
@RequestMapping("/employees")
class EmployeeController(val repository: EmployeeRepository) {
class EmployeeController(val repository: EmployeeRepository,
val appVersion: AppVersion) {

val logger: Logger = LoggerFactory.getLogger(EmployeeController::class.java)

@PostMapping
fun add(@RequestBody employee: Employee): Employee = repository.save(employee)

@GetMapping("/{id}")
fun findById(@PathVariable id: Int): Optional<Employee> = repository.findById(id)
fun findById(@PathVariable id: Int): Optional<AbstractEmployeeDTO> = repository.findById(id)
.map { mapEmployee(it) }

@GetMapping
fun findAll(): Iterable<Employee> = repository.findAll()
fun findAll(): Iterable<AbstractEmployeeDTO> = repository.findAll().map { mapEmployee(it) }

@GetMapping("/organization/{organizationId}")
fun findByOrganizationId(@PathVariable organizationId: Int): Set<Employee> =
repository.findByOrganizationId(organizationId)
fun findByOrganizationId(@PathVariable organizationId: Int): List<AbstractEmployeeDTO> =
repository.findByOrganizationId(organizationId).map { mapEmployee(it) }

@GetMapping("/department/{departmentId}")
fun findByDepartmentId(@PathVariable departmentId: Int): Set<Employee> =
repository.findByDepartmentId(departmentId)
fun findByDepartmentId(@PathVariable departmentId: Int): List<AbstractEmployeeDTO> =
repository.findByDepartmentId(departmentId).map { mapEmployee(it) }

fun mapEmployee(employee: Employee): AbstractEmployeeDTO {
logger.info("Version: {}", appVersion.getVersion())
return if (appVersion.getVersion()!!.contains("v1"))
EmployeeV1DTO(employee.id, employee.firstName, employee.lastName, employee.position,
employee.organizationId, employee.departmentId)
else
EmployeeV2DTO(employee.id, "${employee.firstName} ${employee.lastName}", employee.position,
employee.organizationId, employee.departmentId)
}

}
@@ -0,0 +1,6 @@
package pl.piomin.samples.kubernetes.employee.domain.dto

abstract class AbstractEmployeeDTO(var id: Int? = null,
val position: String = "",
val organizationId: Int = 0,
val departmentId: Int = 0)
@@ -0,0 +1,9 @@
package pl.piomin.samples.kubernetes.employee.domain.dto

class EmployeeV1DTO(id: Int? = null,
val firstName: String = "",
val lastName: String = "",
position: String = "",
organizationId: Int = 0,
departmentId: Int = 0):
AbstractEmployeeDTO(id, position, organizationId, departmentId)
@@ -0,0 +1,8 @@
package pl.piomin.samples.kubernetes.employee.domain.dto

class EmployeeV2DTO(id: Int? = null,
val name: String = "",
position: String = "",
organizationId: Int = 0,
departmentId: Int = 0):
AbstractEmployeeDTO(id, position, organizationId, departmentId)
@@ -0,0 +1,16 @@
package pl.piomin.samples.kubernetes.employee.service

import org.springframework.stereotype.Service
import java.io.File

@Service
class AppVersion {

fun getVersion(): String? {
val file = File("/etc/podinfo/labels")
return if(file.exists()) {
file.readLines().first{ it.startsWith("version=")}
.split("=")[1]
} else null
}
}

0 comments on commit c1e182d

Please sign in to comment.