From 730110dc5566f26e3075f7da4e6a00099ff84980 Mon Sep 17 00:00:00 2001 From: John Blum Date: Mon, 16 Sep 2019 19:17:11 -0700 Subject: [PATCH] Add Example Code demonstrating how to get started with SBDG. Resolves gh-54. --- .../intro/getting-started/lombok.config | 2 + .../intro/getting-started/manifest.yml | 10 +++ ...pring-geode-samples-getting-started.gradle | 34 +++++++++ .../java/example/app/crm/CrmApplication.java | 74 ++++++++++++++++++ .../app/crm/config/CustomerConfiguration.java | 41 ++++++++++ .../crm/controller/CustomerController.java | 76 +++++++++++++++++++ .../java/example/app/crm/model/Customer.java | 48 ++++++++++++ .../app/crm/repo/CustomerRepository.java | 37 +++++++++ 8 files changed, 322 insertions(+) create mode 100644 spring-geode-samples/intro/getting-started/lombok.config create mode 100644 spring-geode-samples/intro/getting-started/manifest.yml create mode 100644 spring-geode-samples/intro/getting-started/spring-geode-samples-getting-started.gradle create mode 100644 spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/CrmApplication.java create mode 100644 spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/config/CustomerConfiguration.java create mode 100644 spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/controller/CustomerController.java create mode 100644 spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/model/Customer.java create mode 100644 spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/repo/CustomerRepository.java diff --git a/spring-geode-samples/intro/getting-started/lombok.config b/spring-geode-samples/intro/getting-started/lombok.config new file mode 100644 index 00000000..6aa51d71 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/lombok.config @@ -0,0 +1,2 @@ +# This file is generated by the 'io.freefair.lombok' Gradle plugin +config.stopBubbling = true diff --git a/spring-geode-samples/intro/getting-started/manifest.yml b/spring-geode-samples/intro/getting-started/manifest.yml new file mode 100644 index 00000000..21d7d164 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/manifest.yml @@ -0,0 +1,10 @@ +--- +applications: + - name: crm-app + memory: 768M + instances: 1 + path: ./build/libs/spring-geode-samples-getting-started-1.2.0.BUILD-SNAPSHOT.jar + services: + - pccService + buildpacks: + - https://github.com/cloudfoundry/java-buildpack.git diff --git a/spring-geode-samples/intro/getting-started/spring-geode-samples-getting-started.gradle b/spring-geode-samples/intro/getting-started/spring-geode-samples-getting-started.gradle new file mode 100644 index 00000000..fba3faac --- /dev/null +++ b/spring-geode-samples/intro/getting-started/spring-geode-samples-getting-started.gradle @@ -0,0 +1,34 @@ +import org.apache.tools.ant.filters.ReplaceTokens + +plugins { + id "io.freefair.lombok" version "3.2.1" +} + +apply plugin: 'io.spring.convention.spring-sample-boot' + +description = "Spring Geode Sample for Getting Started with Spring Boot for Apache Geode quickly, easily and reliably." + +dependencies { + + compile project(":spring-geode-starter") + compile project(":spring-geode-starter-test") + + compile "org.assertj:assertj-core" + compile "org.projectlombok:lombok" + compile "org.springframework.boot:spring-boot-starter-web" + + testCompile "org.springframework.boot:spring-boot-starter-test" + +} + +processResources { + eachFile { file -> + if (!file.name.endsWith(".jks")) { + file.filter ReplaceTokens, tokens: [ + 'project-dir' : rootProject.projectDir.path, + 'project-version' : project.version, + 'samples-dir' : rootProject.projectDir.path + '/spring-geode-samples' + ] + } + } +} diff --git a/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/CrmApplication.java b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/CrmApplication.java new file mode 100644 index 00000000..22808df6 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/CrmApplication.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.crm; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import example.app.crm.model.Customer; +import example.app.crm.repo.CustomerRepository; + +/** + * {@link SpringBootApplication Spring Boot application} implementing a Customer Relationship Management service (CRM). + * + * @author John Blum + * @see org.springframework.boot.SpringApplication + * @see org.springframework.boot.autoconfigure.SpringBootApplication + * @since 1.2.0 + */ +// tag::class[] +@SpringBootApplication +public class CrmApplication { + + public static void main(String[] args) { + SpringApplication.run(CrmApplication.class, args); + } + + // tag::runner[] + @Bean + ApplicationRunner runner(CustomerRepository customerRepository) { + + return args -> { + + assertThat(customerRepository.count()).isEqualTo(0); + + Customer jonDoe = Customer.newCustomer(1L, "JonDoe"); + + System.err.printf("Saving Customer [%s]...%n", jonDoe); + + jonDoe = customerRepository.save(jonDoe); + + assertThat(jonDoe).isNotNull(); + assertThat(jonDoe.getId()).isEqualTo(1L); + assertThat(jonDoe.getName()).isEqualTo("JonDoe"); + assertThat(customerRepository.count()).isEqualTo(1); + + System.err.println("Querying for Customer [SELECT * FROM /Customers WHERE name LIKE '%Doe']..."); + + Customer queriedJonDoe = customerRepository.findByNameLike("%Doe"); + + assertThat(queriedJonDoe).isEqualTo(jonDoe); + + System.err.printf("Customer was [%s]%n", queriedJonDoe); + }; + } + // tag::runner[] +} +// end::class[] diff --git a/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/config/CustomerConfiguration.java b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/config/CustomerConfiguration.java new file mode 100644 index 00000000..8dd373a1 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/config/CustomerConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.crm.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions; +import org.springframework.geode.config.annotation.EnableClusterAware; + +import example.app.crm.model.Customer; + +/** + * Spring {@link Configuration} class used to configure and initialize Apache Geode for the CRM application + * beyond Spring Boot {@literal auto-configuration}. + * + * @author John Blum + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions + * @see org.springframework.geode.config.annotation.EnableClusterAware + * @since 1.2.0 + */ +// tag::class[] +@Configuration +@EnableClusterAware +@EnableEntityDefinedRegions(basePackageClasses = Customer.class) +public class CustomerConfiguration { + +} +// end::class[] diff --git a/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/controller/CustomerController.java b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/controller/CustomerController.java new file mode 100644 index 00000000..c6b000c0 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/controller/CustomerController.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.crm.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import example.app.crm.model.Customer; +import example.app.crm.repo.CustomerRepository; + +/** + * Spring Web MVC {@link RestController} used to implement a crude CRM application REST interface. + * + * @author John Blum + * @see org.springframework.web.bind.annotation.GetMapping + * @see org.springframework.web.bind.annotation.PostMapping + * @see org.springframework.web.bind.annotation.RestController + * @see example.app.crm.model.Customer + * @see example.app.crm.repo.CustomerRepository + * @since 1.2.0 + */ +// tag::class[] +@RestController +public class CustomerController { + + private static final String HTML = "

%s

"; + + @Autowired + private CustomerRepository customerRepository; + + @GetMapping("/customers") + public Iterable findAll() { + return this.customerRepository.findAll(); + } + + @PostMapping("/customers") + public Customer save(Customer customer) { + return this.customerRepository.save(customer); + } + + @GetMapping("/customers/{name}") + public Customer findByName(@PathVariable("name") String name) { + return this.customerRepository.findByNameLike(name); + } + + @GetMapping("/") + public String home() { + return format("Customer Relationship Management"); + } + + @GetMapping("/ping") + public String ping() { + return format("PONG"); + } + + private String format(String value) { + return String.format(HTML, value); + } +} +// end::class[] diff --git a/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/model/Customer.java b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/model/Customer.java new file mode 100644 index 00000000..794733be --- /dev/null +++ b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/model/Customer.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.crm.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.annotation.Region; + +/** + * Abstract Data Type (ADT) modeling a {@link Customer}. + * + * @author John Blum + * @see org.springframework.data.annotation.Id + * @see org.springframework.data.gemfire.mapping.annotation.Region + * @since 1.2.0 + */ +// tag::class[] +@Region("Customers") +@Data +@ToString(of = "name") +@NoArgsConstructor +@AllArgsConstructor(staticName = "newCustomer") +public class Customer { + + @Id + private Long id; + + private String name; + +} +// end::class[] diff --git a/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/repo/CustomerRepository.java b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/repo/CustomerRepository.java new file mode 100644 index 00000000..7662c160 --- /dev/null +++ b/spring-geode-samples/intro/getting-started/src/main/java/example/app/crm/repo/CustomerRepository.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.crm.repo; + +import org.springframework.data.repository.CrudRepository; + +import example.app.crm.model.Customer; + +/** + * Spring Data {@link CrudRepository} or Data Access Object (DAO) implementing basic CRUD and simple Query data access + * operations on {@link Customer} objects. + * + * @author John Blum + * @see org.springframework.data.repository.CrudRepository + * @see example.app.crm.model.Customer + * @since 1.2.0 + */ +// tag::class[] +public interface CustomerRepository extends CrudRepository { + + Customer findByNameLike(String name); + +} +// end::class[]