From b8d9a18626082b338b915363a30b5b0e84f0d00d Mon Sep 17 00:00:00 2001 From: Eric Goebelbecker Date: Wed, 21 Mar 2018 10:43:53 -0400 Subject: [PATCH] BAEL-1554 (#3864) * BAEL-1554 - Flips code * BAEL-1554 - Flips code, round 2 * BAEL-1554 - Guide to Flips * BAEL-1554 - update read me * BAEL-1554 - rename "Thing" to "Foo" * BAEL-1554 - rename module to spring-4 --- pom.xml | 1 + spring-4/README.md | 2 + spring-4/pom.xml | 62 ++++++++++++++++ .../com/baeldung/flips/ApplicationConfig.java | 15 ++++ .../flips/controller/FlipController.java | 65 ++++++++++++++++ .../java/com/baeldung/flips/model/Foo.java | 11 +++ .../baeldung/flips/service/FlipService.java | 50 +++++++++++++ .../flips/service/NewFlipService.java | 13 ++++ .../src/main/resources/application.properties | 5 ++ .../flips/controller/FlipControllerTest.java | 74 +++++++++++++++++++ 10 files changed, 298 insertions(+) create mode 100644 spring-4/README.md create mode 100644 spring-4/pom.xml create mode 100644 spring-4/src/main/java/com/baeldung/flips/ApplicationConfig.java create mode 100644 spring-4/src/main/java/com/baeldung/flips/controller/FlipController.java create mode 100644 spring-4/src/main/java/com/baeldung/flips/model/Foo.java create mode 100644 spring-4/src/main/java/com/baeldung/flips/service/FlipService.java create mode 100644 spring-4/src/main/java/com/baeldung/flips/service/NewFlipService.java create mode 100644 spring-4/src/main/resources/application.properties create mode 100644 spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java diff --git a/pom.xml b/pom.xml index cf9de13ba4..f8e1910b9b 100644 --- a/pom.xml +++ b/pom.xml @@ -150,6 +150,7 @@ testing-modules/selenium-junit-testng persistence-modules/solr spark-java + spring-4 spring-5 spring-5-reactive spring-5-mvc diff --git a/spring-4/README.md b/spring-4/README.md new file mode 100644 index 0000000000..0c62173b6a --- /dev/null +++ b/spring-4/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Guide to Flips For Spring](http://www.baeldung.com/guide-to-flips-for-spring/) diff --git a/spring-4/pom.xml b/spring-4/pom.xml new file mode 100644 index 0000000000..8a57888e56 --- /dev/null +++ b/spring-4/pom.xml @@ -0,0 +1,62 @@ + + 4.0.0 + + spring-4 + spring-4 + 0.0.1-SNAPSHOT + jar + + spring-4 + + + UTF-8 + 1.8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + 1.5.10.RELEASE + + + + org.springframework.boot + spring-boot-starter-test + 1.5.9.RELEASE + + + + com.github.feature-flip + flips-web + 1.0.1 + + + + org.projectlombok + lombok + + 1.16.18 + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + diff --git a/spring-4/src/main/java/com/baeldung/flips/ApplicationConfig.java b/spring-4/src/main/java/com/baeldung/flips/ApplicationConfig.java new file mode 100644 index 0000000000..7001aeb991 --- /dev/null +++ b/spring-4/src/main/java/com/baeldung/flips/ApplicationConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.flips; + +import org.flips.describe.config.FlipWebContextConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(FlipWebContextConfiguration.class) +public class ApplicationConfig { + + public static void main(String[] args) { + SpringApplication.run(ApplicationConfig.class, args); + } +} \ No newline at end of file diff --git a/spring-4/src/main/java/com/baeldung/flips/controller/FlipController.java b/spring-4/src/main/java/com/baeldung/flips/controller/FlipController.java new file mode 100644 index 0000000000..50458023b3 --- /dev/null +++ b/spring-4/src/main/java/com/baeldung/flips/controller/FlipController.java @@ -0,0 +1,65 @@ +package com.baeldung.flips.controller; + +import com.baeldung.flips.model.Foo; +import com.baeldung.flips.service.FlipService; +import org.flips.annotation.FlipOnDateTime; +import org.flips.annotation.FlipOnDaysOfWeek; +import org.flips.annotation.FlipOnEnvironmentProperty; +import org.flips.annotation.FlipOnProfiles; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.time.DayOfWeek; +import java.util.List; + +@RestController +public class FlipController { + + private FlipService flipService; + + @Autowired + public FlipController(FlipService flipService) { + this.flipService = flipService; + } + + @RequestMapping(value = "/foos", method = RequestMethod.GET) + @FlipOnProfiles(activeProfiles = "dev") + public List getAllFoos() { + return flipService.getAllFoos(); + } + + @RequestMapping(value = "/foo/{id}", method = RequestMethod.GET) + @FlipOnDaysOfWeek(daysOfWeek = { + DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY + }) + public Foo getFooByNewId(@PathVariable int id) { + return flipService.getFooById(id).orElse(new Foo("Not Found", -1)); + } + + @RequestMapping(value = "/foo/last", method = RequestMethod.GET) + @FlipOnDateTime(cutoffDateTimeProperty = "last.active.after") + public Foo getLastFoo() { + return flipService.getLastFoo(); + } + + @RequestMapping(value = "/foo/first", method = RequestMethod.GET) + @FlipOnDateTime(cutoffDateTimeProperty = "first.active.after") + public Foo getFirstFoo() { + return flipService.getLastFoo(); + } + + @RequestMapping(value = "/foos/{id}", method = RequestMethod.GET) + @FlipOnEnvironmentProperty(property = "feature.foo.by.id", expectedValue = "Y") + public Foo getFooById(@PathVariable int id) { + return flipService.getFooById(id).orElse(new Foo("Not Found", -1)); + } + + @RequestMapping(value = "/foo/new", method = RequestMethod.GET) + public Foo getNewThing() { + return flipService.getNewFoo(); + } +} \ No newline at end of file diff --git a/spring-4/src/main/java/com/baeldung/flips/model/Foo.java b/spring-4/src/main/java/com/baeldung/flips/model/Foo.java new file mode 100644 index 0000000000..d98abb79a9 --- /dev/null +++ b/spring-4/src/main/java/com/baeldung/flips/model/Foo.java @@ -0,0 +1,11 @@ +package com.baeldung.flips.model; + +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Data +@RequiredArgsConstructor +public class Foo { + private final String name; + private final int id; +} diff --git a/spring-4/src/main/java/com/baeldung/flips/service/FlipService.java b/spring-4/src/main/java/com/baeldung/flips/service/FlipService.java new file mode 100644 index 0000000000..9f7fb325a5 --- /dev/null +++ b/spring-4/src/main/java/com/baeldung/flips/service/FlipService.java @@ -0,0 +1,50 @@ +package com.baeldung.flips.service; + +import com.baeldung.flips.model.Foo; +import org.flips.annotation.FlipBean; +import org.flips.annotation.FlipOnSpringExpression; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class FlipService { + + private final List foos; + + public FlipService() { + foos = new ArrayList<>(); + foos.add(new Foo("Foo1", 1)); + foos.add(new Foo("Foo2", 2)); + foos.add(new Foo("Foo3", 3)); + foos.add(new Foo("Foo4", 4)); + foos.add(new Foo("Foo5", 5)); + foos.add(new Foo("Foo6", 6)); + + } + + public List getAllFoos() { + return foos; + } + + public Optional getFooById(int id) { + return foos.stream().filter(foo -> (foo.getId() == id)).findFirst(); + } + + @FlipBean(with = NewFlipService.class) + @FlipOnSpringExpression(expression = "(2 + 2) == 4") + public Foo getNewFoo() { + return new Foo("New Foo!", 99); + } + + public Foo getLastFoo() { + return foos.get(foos.size() - 1); + } + + public Foo getFirstFoo() { + return foos.get(0); + } + +} \ No newline at end of file diff --git a/spring-4/src/main/java/com/baeldung/flips/service/NewFlipService.java b/spring-4/src/main/java/com/baeldung/flips/service/NewFlipService.java new file mode 100644 index 0000000000..1dcda9b6ca --- /dev/null +++ b/spring-4/src/main/java/com/baeldung/flips/service/NewFlipService.java @@ -0,0 +1,13 @@ +package com.baeldung.flips.service; + +import com.baeldung.flips.model.Foo; +import org.springframework.stereotype.Service; + +@Service +public class NewFlipService { + + public Foo getNewFoo() { + return new Foo("Shiny New Foo!", 100); + } + +} \ No newline at end of file diff --git a/spring-4/src/main/resources/application.properties b/spring-4/src/main/resources/application.properties new file mode 100644 index 0000000000..274896be15 --- /dev/null +++ b/spring-4/src/main/resources/application.properties @@ -0,0 +1,5 @@ +feature.foo.by.id=Y +feature.new.foo=Y +last.active.after=2018-03-14T00:00:00Z +first.active.after=2999-03-15T00:00:00Z +logging.level.org.flips=info \ No newline at end of file diff --git a/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java b/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java new file mode 100644 index 0000000000..1b8c78e2a4 --- /dev/null +++ b/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java @@ -0,0 +1,74 @@ +package com.baeldung.flips.controller; + +import org.hamcrest.Matchers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { + "feature.foo.by.id=Y", + "feature.new.foo=Y", + "last.active.after=2018-03-14T00:00:00Z", + "first.active.after=2999-03-15T00:00:00Z", + "logging.level.org.flips=info" + +}) +@AutoConfigureMockMvc +@ActiveProfiles("dev") +public class FlipControllerTest { + + @Autowired private MockMvc mvc; + + @Test + public void givenValidDayOfWeek_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/1")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1))); + } + + @Test + public void givenValidDate_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/last")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo6"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(6))); + } + + @Test + public void givenInvalidDate_APINotAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/first")) + .andExpect(MockMvcResultMatchers.status().is(501)); + } + + @Test + public void givenCorrectProfile_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foos")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(6))); + } + + @Test + public void givenPropertySet_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foos/1")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1))); + } + + @Test + public void getValidExpression_FlipBean() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/new")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Shiny New Foo!"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(100))); + } +} \ No newline at end of file