Move Spring Boot Actuator Sample under the spring-geode-samples.
Declare the FreeFair Lombok Gradle Plugin in spring-geode-samples-boot-actuator.gradle.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
plugins {
|
||||
id "io.freefair.lombok" version "3.2.1"
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.spring-sample-boot'
|
||||
|
||||
description = "Spring Geode Sample demonstrating the use of Spring Boot Actuator with Apache Geode."
|
||||
|
||||
dependencies {
|
||||
|
||||
compile project(":spring-geode-starter-actuator")
|
||||
|
||||
compile ("org.springframework.boot:spring-boot-starter-web") {
|
||||
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
||||
}
|
||||
|
||||
compile "org.springframework.data:spring-data-geode-test"
|
||||
|
||||
runtime "org.springframework.shell:spring-shell"
|
||||
|
||||
runtime ("org.springframework.boot:spring-boot-starter-jetty") {
|
||||
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClassName = 'example.app.temp.geode.client.BootGeodeClientApplication'
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.event;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class BoilingTemperatureEvent extends TemperatureEvent {
|
||||
|
||||
public BoilingTemperatureEvent(Object source, TemperatureReading temperatureReading) {
|
||||
super(source, temperatureReading);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.event;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class FreezingTemperatureEvent extends TemperatureEvent {
|
||||
|
||||
public FreezingTemperatureEvent(Object source, TemperatureReading temperatureReading) {
|
||||
super(source, temperatureReading);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.event;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
|
||||
public class TemperatureEvent extends ApplicationEvent {
|
||||
|
||||
@Getter
|
||||
private final TemperatureReading temperatureReading;
|
||||
|
||||
public TemperatureEvent(Object source, TemperatureReading temperatureReading) {
|
||||
|
||||
super(source);
|
||||
|
||||
this.temperatureReading = temperatureReading;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.geode.client;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
import org.springframework.geode.config.annotation.UseGroups;
|
||||
import org.springframework.geode.config.annotation.UseMemberName;
|
||||
|
||||
import example.app.temp.event.BoilingTemperatureEvent;
|
||||
import example.app.temp.event.FreezingTemperatureEvent;
|
||||
import example.app.temp.event.TemperatureEvent;
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
import example.app.temp.service.TemperatureMonitor;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableEntityDefinedRegions(basePackageClasses = TemperatureReading.class)
|
||||
@UseGroups("TemperatureMonitors")
|
||||
@UseMemberName("TemperatureMonitoringService")
|
||||
@SuppressWarnings("unused")
|
||||
public class BootGeodeClientApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
new SpringApplicationBuilder(BootGeodeClientApplication.class)
|
||||
.web(WebApplicationType.SERVLET)
|
||||
.build()
|
||||
.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
TemperatureMonitor temperatureMonitor(ApplicationEventPublisher applicationEventPublisher) {
|
||||
return new TemperatureMonitor(applicationEventPublisher);
|
||||
}
|
||||
|
||||
@EventListener(classes = { BoilingTemperatureEvent.class, FreezingTemperatureEvent.class })
|
||||
public void temperatureEventHandler(TemperatureEvent temperatureEvent) {
|
||||
|
||||
System.err.printf("%1$s TEMPERATURE READING [%2$s]%n",
|
||||
temperatureEvent instanceof BoilingTemperatureEvent ? "HOT" : "COLD",
|
||||
temperatureEvent.getTemperatureReading());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.geode.server;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.data.gemfire.IndexFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableStatistics;
|
||||
import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
|
||||
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
|
||||
import org.springframework.geode.config.annotation.UseGroups;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
import example.app.temp.repo.TemperatureReadingRepository;
|
||||
import example.app.temp.service.TemperatureSensor;
|
||||
|
||||
@SpringBootApplication
|
||||
@CacheServerApplication(name = "TemperatureServiceServer")
|
||||
@EnableEntityDefinedRegions(basePackageClasses = TemperatureReading.class)
|
||||
@EnableGemfireRepositories(basePackageClasses = TemperatureReadingRepository.class)
|
||||
@EnableScheduling
|
||||
@EnableStatistics
|
||||
@UseGroups("TemperatureSensors")
|
||||
@SuppressWarnings("unused")
|
||||
public class BootGeodeServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
new SpringApplicationBuilder(BootGeodeServerApplication.class)
|
||||
.web(WebApplicationType.SERVLET)
|
||||
.build()
|
||||
.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
TemperatureSensor temperatureSensor(TemperatureReadingRepository repository) {
|
||||
return new TemperatureSensor(repository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
RegionConfigurer temperatureReadingsConfigurer() {
|
||||
|
||||
return new RegionConfigurer() {
|
||||
|
||||
@Override
|
||||
public void configure(String beanName, RegionFactoryBean<?, ?> regionBean) {
|
||||
|
||||
Optional.ofNullable(beanName)
|
||||
.filter("TemperatureReadings"::equals)
|
||||
.ifPresent(it -> regionBean.setStatisticsEnabled(true));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("TemperatureReadings")
|
||||
IndexFactoryBean temperatureReadingTemperatureIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean temperatureTimestampIndex = new IndexFactoryBean();
|
||||
|
||||
temperatureTimestampIndex.setCache(gemfireCache);
|
||||
temperatureTimestampIndex.setExpression("temperature");
|
||||
temperatureTimestampIndex.setFrom("/TemperatureReadings");
|
||||
temperatureTimestampIndex.setName("TemperatureReadingTemperatureIdx");
|
||||
|
||||
return temperatureTimestampIndex;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("TemperatureReadings")
|
||||
IndexFactoryBean temperatureReadingTimestampIndex(GemFireCache gemfireCache) {
|
||||
|
||||
IndexFactoryBean temperatureTimestampIndex = new IndexFactoryBean();
|
||||
|
||||
temperatureTimestampIndex.setCache(gemfireCache);
|
||||
temperatureTimestampIndex.setExpression("timestamp");
|
||||
temperatureTimestampIndex.setFrom("/TemperatureReadings");
|
||||
temperatureTimestampIndex.setName("TemperatureReadingTimestampIdx");
|
||||
|
||||
return temperatureTimestampIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.model;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
|
||||
@Data
|
||||
@Region("TemperatureReadings")
|
||||
@RequiredArgsConstructor(staticName = "newTemperatureReading")
|
||||
@SuppressWarnings("unused")
|
||||
public class TemperatureReading {
|
||||
|
||||
private static final int BOILING_TEMPERATURE = 212;
|
||||
private static final int FREEZING_TEMPERATURE = 32;
|
||||
|
||||
@Id
|
||||
private Long timestamp = System.currentTimeMillis();
|
||||
|
||||
@NonNull
|
||||
private Integer temperature;
|
||||
|
||||
@Transient
|
||||
public boolean isBoiling() {
|
||||
|
||||
Integer temperature = getTemperature();
|
||||
|
||||
return temperature != null && temperature >= BOILING_TEMPERATURE;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public boolean isNormal() {
|
||||
return !(isBoiling() || isFreezing());
|
||||
}
|
||||
|
||||
@Transient
|
||||
public boolean isFreezing() {
|
||||
|
||||
Integer temperature = getTemperature();
|
||||
|
||||
return temperature != null && temperature <= FREEZING_TEMPERATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d °F", getTemperature());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.repo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface TemperatureReadingRepository extends CrudRepository<TemperatureReading, Long> {
|
||||
|
||||
List<TemperatureReading> findByTimestampGreaterThanAndTimestampLessThan(Long timestampLowerBound,
|
||||
Long timestampUpperBound);
|
||||
|
||||
@Query("SELECT count(*) FROM /TemperatureReadings WHERE temperature >= 212")
|
||||
Integer countBoilingTemperatureReadings();
|
||||
|
||||
@Query("SELECT count(*) FROM /TemperatureReadings WHERE temperature <= 32")
|
||||
Integer countFreezingTemperatureReadings();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.service;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.query.CqEvent;
|
||||
import org.apache.shiro.util.Assert;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.gemfire.listener.annotation.ContinuousQuery;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import example.app.temp.event.BoilingTemperatureEvent;
|
||||
import example.app.temp.event.FreezingTemperatureEvent;
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
|
||||
@Service
|
||||
@SuppressWarnings("unused")
|
||||
public class TemperatureMonitor {
|
||||
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
public TemperatureMonitor(ApplicationEventPublisher applicationEventPublisher) {
|
||||
|
||||
Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher is required");
|
||||
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@ContinuousQuery(name = "BoilingTemperatureMonitor",
|
||||
query = "SELECT * FROM /TemperatureReadings WHERE temperature >= 212")
|
||||
public void boilingTemperatureReadings(CqEvent event) {
|
||||
|
||||
Optional.ofNullable(event)
|
||||
.map(CqEvent::getNewValue)
|
||||
.filter(TemperatureReading.class::isInstance)
|
||||
.map(TemperatureReading.class::cast)
|
||||
.map(it -> new BoilingTemperatureEvent(this, it))
|
||||
.ifPresent(this.applicationEventPublisher::publishEvent);
|
||||
}
|
||||
|
||||
@ContinuousQuery(name = "FreezingTemperatureMonitor",
|
||||
query = "SELECT * FROM /TemperatureReadings WHERE temperature <= 32")
|
||||
public void freezingTemperatureReadings(CqEvent event) {
|
||||
|
||||
Optional.ofNullable(event)
|
||||
.map(CqEvent::getNewValue)
|
||||
.filter(TemperatureReading.class::isInstance)
|
||||
.map(TemperatureReading.class::cast)
|
||||
.map(it -> new FreezingTemperatureEvent(this, it))
|
||||
.ifPresent(this.applicationEventPublisher::publishEvent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2018 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.temp.service;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import example.app.temp.model.TemperatureReading;
|
||||
import example.app.temp.repo.TemperatureReadingRepository;
|
||||
|
||||
@Service
|
||||
@SuppressWarnings("unused")
|
||||
public class TemperatureSensor {
|
||||
|
||||
private final PrimitiveIterator.OfInt temperatureStream = new Random(System.currentTimeMillis())
|
||||
.ints(-100, 400).iterator();
|
||||
|
||||
private final TemperatureReadingRepository repository;
|
||||
|
||||
public TemperatureSensor(TemperatureReadingRepository repository) {
|
||||
|
||||
Assert.notNull(repository, "TemperatureReadingRepository is required");
|
||||
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Scheduled(fixedRateString = "${example.app.temp.sensor.reading.schedule.rate:1000}")
|
||||
public void readTemperature() {
|
||||
this.repository.save(log(TemperatureReading.newTemperatureReading(temperatureStream.nextInt())));
|
||||
}
|
||||
|
||||
private TemperatureReading log(TemperatureReading temperatureReading) {
|
||||
|
||||
PrintStream out = temperatureReading.isNormal() ? System.out : System.err;
|
||||
|
||||
out.printf("TEMPERATURE READING [%s]%n", temperatureReading);
|
||||
|
||||
return temperatureReading;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Temperature Service client application configuration properties
|
||||
|
||||
server.port=9191
|
||||
@@ -0,0 +1,3 @@
|
||||
# Temperature Service server application configuration properties
|
||||
|
||||
server.port=8181
|
||||
@@ -0,0 +1,5 @@
|
||||
# Temperature Service application configuration properties
|
||||
|
||||
management.endpoint.health.show-details=always
|
||||
#management.endpoints.web.exposure.include=env
|
||||
spring.data.gemfire.cache.log-level=error
|
||||
Reference in New Issue
Block a user