Merge pull request #104 from thombergs/zero-downtime

Zero downtime
This commit is contained in:
Tom Hombergs
2021-08-04 06:53:08 +10:00
committed by GitHub
11 changed files with 154 additions and 19 deletions

View File

@@ -86,11 +86,12 @@ if [[ "$MODULE" == "module6" ]]
then
# ADD NEW MODULES HERE
# (add new modules above the rest so you get quicker feedback if it fails)
build_maven_module "spring-boot/zero-downtime"
build_maven_module "resilience4j/springboot-resilience4j"
build_maven_module "spring-boot/feature-flags"
build maven_module "aws/springcloudses"
build_maven_module "aws/springcloudses"
build_gradle_module "aws/spring-cloud-caching-redis"
build maven_module "spring-boot/spring-boot-camel"
build_maven_module "spring-boot/spring-boot-camel"
build_maven_module "logging/spring-boot"
build_maven_module "logging/logback"
build_maven_module "logging/log4j"
@@ -103,7 +104,7 @@ fi
if [[ "$MODULE" == "module5" ]]
then
build maven_module "aws/aws-dynamodb"
build_maven_module "aws/aws-dynamodb"
build_maven_module "spring-boot/spring-boot-testconfiguration"
build_maven_module "aws/springcloudrds"
build_maven_module "aws/springcloudsqs"

View File

@@ -42,6 +42,13 @@
<artifactId>h2</artifactId>
</dependency>
<!-- LAUNCHDARKLY -->
<dependency>
<groupId>com.launchdarkly</groupId>
<artifactId>launchdarkly-java-server-sdk</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
<build>

View File

@@ -1,31 +1,62 @@
package io.reflectoring.zerodowntime;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
public class CustomerController {
private final CustomerRepository customerRepository;
private final CustomerRepository oldCustomerRepository;
private final NewCustomerRepository newCustomerRepository;
private final FeatureFlagService featureFlagService;
public CustomerController(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
public CustomerController(CustomerRepository oldCustomerRepository, NewCustomerRepository newCustomerRepository, FeatureFlagService featureFlagService) {
this.oldCustomerRepository = oldCustomerRepository;
this.newCustomerRepository = newCustomerRepository;
this.featureFlagService = featureFlagService;
}
@GetMapping("/customers/create")
String createUser() {
Customer customer = new Customer("Bob", "Builder", "21 Build Street");
customerRepository.save(customer);
String createCustomer() {
if (featureFlagService.writeToNewCustomerSchema()) {
NewCustomer customer = new NewCustomer("Bob", "Builder", "Build Street", "21");
newCustomerRepository.save(customer);
} else {
OldCustomer customer = new OldCustomer("Bob", "Builder", "21 Build Street");
oldCustomerRepository.save(customer);
}
return "customer created";
}
@GetMapping("/customers/{id}}")
String getCustomer(@PathVariable("id") Long id) {
if (featureFlagService.readFromNewCustomerSchema()) {
Optional<NewCustomer> customer = newCustomerRepository.findById(id);
return customer.get().toString();
} else {
Optional<OldCustomer> customer = oldCustomerRepository.findById(id);
return customer.get().toString();
}
}
@GetMapping("/customers/list")
String showUser() {
Iterable<Customer> customers = customerRepository.findAll();
String getCustomer() {
StringBuffer buffer = new StringBuffer();
for (Customer customer : customers) {
buffer.append("\n");
buffer.append(customer.toString());
if (featureFlagService.readFromNewCustomerSchema()) {
Iterable<NewCustomer> customers = newCustomerRepository.findAll();
for (NewCustomer customer : customers) {
buffer.append("\n");
buffer.append(customer.toString());
}
} else {
Iterable<OldCustomer> customers = oldCustomerRepository.findAll();
for (OldCustomer customer : customers) {
buffer.append("\n");
buffer.append(customer.toString());
}
}
return buffer.toString();
}

View File

@@ -2,5 +2,5 @@ package io.reflectoring.zerodowntime;
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
public interface CustomerRepository extends CrudRepository<OldCustomer, Long> {
}

View File

@@ -0,0 +1,24 @@
package io.reflectoring.zerodowntime;
import com.launchdarkly.sdk.LDUser;
import com.launchdarkly.sdk.server.LDClient;
import org.springframework.stereotype.Component;
@Component
public class FeatureFlagService {
private final LDClient launchdarklyClient;
public FeatureFlagService(LDClient launchdarklyClient) {
this.launchdarklyClient = launchdarklyClient;
}
public Boolean writeToNewCustomerSchema() {
return true;
}
public Boolean readFromNewCustomerSchema() {
return false;
}
}

View File

@@ -0,0 +1,27 @@
package io.reflectoring.zerodowntime;
import com.launchdarkly.sdk.server.LDClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PreDestroy;
import java.io.IOException;
@Configuration
public class LaunchDarklyConfiguration {
private LDClient launchdarklyClient;
@Bean
public LDClient launchdarklyClient(@Value("${launchdarkly.sdkKey}") String sdkKey) {
this.launchdarklyClient = new LDClient(sdkKey);
return this.launchdarklyClient;
}
@PreDestroy
public void destroy() throws IOException {
this.launchdarklyClient.close();
}
}

View File

@@ -0,0 +1,34 @@
package io.reflectoring.zerodowntime;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("CUSTOMER")
public class NewCustomer {
@Id
private long id;
private String firstName;
private String lastName;
private String addressStreet;
private String addressStreetNumber;
public NewCustomer(String firstName, String lastName, String addressStreet, String addressStreetNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.addressStreet = addressStreet;
this.addressStreetNumber = addressStreetNumber;
}
@Override
public String toString() {
return "NewCustomer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", addressStreet='" + addressStreet + '\'' +
", addressStreetNumber='" + addressStreetNumber + '\'' +
'}';
}
}

View File

@@ -0,0 +1,6 @@
package io.reflectoring.zerodowntime;
import org.springframework.data.repository.CrudRepository;
public interface NewCustomerRepository extends CrudRepository<NewCustomer, Long> {
}

View File

@@ -5,7 +5,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("CUSTOMER")
public class Customer {
public class OldCustomer {
@Id
private long id;
@@ -13,7 +13,7 @@ public class Customer {
private String lastName;
private String address;
public Customer(String firstName, String lastName, String address) {
public OldCustomer(String firstName, String lastName, String address) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
@@ -21,7 +21,7 @@ public class Customer {
@Override
public String toString() {
return "Customer{" +
return "OldCustomer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +

View File

@@ -6,4 +6,7 @@ spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
spring:
h2:
console:
enabled: true
enabled: true
launchdarkly:
sdkKey: <YOUR-SDK-KEY>

View File

@@ -0,0 +1,2 @@
alter table customer add column address_street varchar(100) null;
alter table customer add column address_street_number varchar(100) null;