Skip to content

Commit c870f5d

Browse files
authored
Merge pull request thombergs#104 from thombergs/zero-downtime
Zero downtime
2 parents 36a5bdd + 946a9de commit c870f5d

File tree

11 files changed

+154
-19
lines changed

11 files changed

+154
-19
lines changed

build-all.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ if [[ "$MODULE" == "module6" ]]
8686
then
8787
# ADD NEW MODULES HERE
8888
# (add new modules above the rest so you get quicker feedback if it fails)
89+
build_maven_module "spring-boot/zero-downtime"
8990
build_maven_module "resilience4j/springboot-resilience4j"
9091
build_maven_module "spring-boot/feature-flags"
91-
build maven_module "aws/springcloudses"
92+
build_maven_module "aws/springcloudses"
9293
build_gradle_module "aws/spring-cloud-caching-redis"
93-
build maven_module "spring-boot/spring-boot-camel"
94+
build_maven_module "spring-boot/spring-boot-camel"
9495
build_maven_module "logging/spring-boot"
9596
build_maven_module "logging/logback"
9697
build_maven_module "logging/log4j"
@@ -103,7 +104,7 @@ fi
103104

104105
if [[ "$MODULE" == "module5" ]]
105106
then
106-
build maven_module "aws/aws-dynamodb"
107+
build_maven_module "aws/aws-dynamodb"
107108
build_maven_module "spring-boot/spring-boot-testconfiguration"
108109
build_maven_module "aws/springcloudrds"
109110
build_maven_module "aws/springcloudsqs"

spring-boot/zero-downtime/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
<artifactId>h2</artifactId>
4343
</dependency>
4444

45+
<!-- LAUNCHDARKLY -->
46+
<dependency>
47+
<groupId>com.launchdarkly</groupId>
48+
<artifactId>launchdarkly-java-server-sdk</artifactId>
49+
<version>5.3.0</version>
50+
</dependency>
51+
4552
</dependencies>
4653

4754
<build>

spring-boot/zero-downtime/src/main/java/io/reflectoring/zerodowntime/CustomerController.java

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,62 @@
11
package io.reflectoring.zerodowntime;
22

33
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.PathVariable;
45
import org.springframework.web.bind.annotation.RestController;
56

7+
import java.util.Optional;
8+
69
@RestController
710
public class CustomerController {
811

9-
private final CustomerRepository customerRepository;
12+
private final CustomerRepository oldCustomerRepository;
13+
private final NewCustomerRepository newCustomerRepository;
14+
private final FeatureFlagService featureFlagService;
1015

11-
public CustomerController(CustomerRepository customerRepository) {
12-
this.customerRepository = customerRepository;
16+
public CustomerController(CustomerRepository oldCustomerRepository, NewCustomerRepository newCustomerRepository, FeatureFlagService featureFlagService) {
17+
this.oldCustomerRepository = oldCustomerRepository;
18+
this.newCustomerRepository = newCustomerRepository;
19+
this.featureFlagService = featureFlagService;
1320
}
1421

1522
@GetMapping("/customers/create")
16-
String createUser() {
17-
Customer customer = new Customer("Bob", "Builder", "21 Build Street");
18-
customerRepository.save(customer);
23+
String createCustomer() {
24+
if (featureFlagService.writeToNewCustomerSchema()) {
25+
NewCustomer customer = new NewCustomer("Bob", "Builder", "Build Street", "21");
26+
newCustomerRepository.save(customer);
27+
} else {
28+
OldCustomer customer = new OldCustomer("Bob", "Builder", "21 Build Street");
29+
oldCustomerRepository.save(customer);
30+
}
1931
return "customer created";
2032
}
2133

34+
@GetMapping("/customers/{id}}")
35+
String getCustomer(@PathVariable("id") Long id) {
36+
if (featureFlagService.readFromNewCustomerSchema()) {
37+
Optional<NewCustomer> customer = newCustomerRepository.findById(id);
38+
return customer.get().toString();
39+
} else {
40+
Optional<OldCustomer> customer = oldCustomerRepository.findById(id);
41+
return customer.get().toString();
42+
}
43+
}
44+
2245
@GetMapping("/customers/list")
23-
String showUser() {
24-
Iterable<Customer> customers = customerRepository.findAll();
46+
String getCustomer() {
2547
StringBuffer buffer = new StringBuffer();
26-
for (Customer customer : customers) {
27-
buffer.append("\n");
28-
buffer.append(customer.toString());
48+
if (featureFlagService.readFromNewCustomerSchema()) {
49+
Iterable<NewCustomer> customers = newCustomerRepository.findAll();
50+
for (NewCustomer customer : customers) {
51+
buffer.append("\n");
52+
buffer.append(customer.toString());
53+
}
54+
} else {
55+
Iterable<OldCustomer> customers = oldCustomerRepository.findAll();
56+
for (OldCustomer customer : customers) {
57+
buffer.append("\n");
58+
buffer.append(customer.toString());
59+
}
2960
}
3061
return buffer.toString();
3162
}

spring-boot/zero-downtime/src/main/java/io/reflectoring/zerodowntime/CustomerRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
import org.springframework.data.repository.CrudRepository;
44

5-
public interface CustomerRepository extends CrudRepository<Customer, Long> {
5+
public interface CustomerRepository extends CrudRepository<OldCustomer, Long> {
66
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.reflectoring.zerodowntime;
2+
3+
import com.launchdarkly.sdk.LDUser;
4+
import com.launchdarkly.sdk.server.LDClient;
5+
import org.springframework.stereotype.Component;
6+
7+
@Component
8+
public class FeatureFlagService {
9+
10+
private final LDClient launchdarklyClient;
11+
12+
public FeatureFlagService(LDClient launchdarklyClient) {
13+
this.launchdarklyClient = launchdarklyClient;
14+
}
15+
16+
public Boolean writeToNewCustomerSchema() {
17+
return true;
18+
}
19+
20+
public Boolean readFromNewCustomerSchema() {
21+
return false;
22+
}
23+
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.reflectoring.zerodowntime;
2+
3+
import com.launchdarkly.sdk.server.LDClient;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
import javax.annotation.PreDestroy;
9+
import java.io.IOException;
10+
11+
@Configuration
12+
public class LaunchDarklyConfiguration {
13+
14+
private LDClient launchdarklyClient;
15+
16+
@Bean
17+
public LDClient launchdarklyClient(@Value("${launchdarkly.sdkKey}") String sdkKey) {
18+
this.launchdarklyClient = new LDClient(sdkKey);
19+
return this.launchdarklyClient;
20+
}
21+
22+
@PreDestroy
23+
public void destroy() throws IOException {
24+
this.launchdarklyClient.close();
25+
}
26+
27+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.reflectoring.zerodowntime;
2+
3+
4+
import org.springframework.data.annotation.Id;
5+
import org.springframework.data.relational.core.mapping.Table;
6+
7+
@Table("CUSTOMER")
8+
public class NewCustomer {
9+
10+
@Id
11+
private long id;
12+
private String firstName;
13+
private String lastName;
14+
private String addressStreet;
15+
private String addressStreetNumber;
16+
17+
public NewCustomer(String firstName, String lastName, String addressStreet, String addressStreetNumber) {
18+
this.firstName = firstName;
19+
this.lastName = lastName;
20+
this.addressStreet = addressStreet;
21+
this.addressStreetNumber = addressStreetNumber;
22+
}
23+
24+
@Override
25+
public String toString() {
26+
return "NewCustomer{" +
27+
"id=" + id +
28+
", firstName='" + firstName + '\'' +
29+
", lastName='" + lastName + '\'' +
30+
", addressStreet='" + addressStreet + '\'' +
31+
", addressStreetNumber='" + addressStreetNumber + '\'' +
32+
'}';
33+
}
34+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package io.reflectoring.zerodowntime;
2+
3+
import org.springframework.data.repository.CrudRepository;
4+
5+
public interface NewCustomerRepository extends CrudRepository<NewCustomer, Long> {
6+
}

spring-boot/zero-downtime/src/main/java/io/reflectoring/zerodowntime/Customer.java renamed to spring-boot/zero-downtime/src/main/java/io/reflectoring/zerodowntime/OldCustomer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
import org.springframework.data.relational.core.mapping.Table;
66

77
@Table("CUSTOMER")
8-
public class Customer {
8+
public class OldCustomer {
99

1010
@Id
1111
private long id;
1212
private String firstName;
1313
private String lastName;
1414
private String address;
1515

16-
public Customer(String firstName, String lastName, String address) {
16+
public OldCustomer(String firstName, String lastName, String address) {
1717
this.firstName = firstName;
1818
this.lastName = lastName;
1919
this.address = address;
2020
}
2121

2222
@Override
2323
public String toString() {
24-
return "Customer{" +
24+
return "OldCustomer{" +
2525
"id=" + id +
2626
", firstName='" + firstName + '\'' +
2727
", lastName='" + lastName + '\'' +

spring-boot/zero-downtime/src/main/resources/application.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
66
spring:
77
h2:
88
console:
9-
enabled: true
9+
enabled: true
10+
11+
launchdarkly:
12+
sdkKey: <YOUR-SDK-KEY>

0 commit comments

Comments
 (0)