Skip to content

Commit

Permalink
Merge branch 'gh273-docker-springboot' into gh47 (#gh47, #gh273)
Browse files Browse the repository at this point in the history
  • Loading branch information
climategadgets committed Aug 29, 2023
2 parents ca2d257 + 65a10a7 commit 9905ee3
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 49 deletions.
47 changes: 47 additions & 0 deletions dz3r-app-springboot/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
buildscript {
dependencies {
classpath("com.google.cloud.tools:jib-layer-filter-extension-gradle:0.3.0")
}
}

plugins {
// See https://github.com/home-climate-control/dz/issues/230
// Should that bug be fixed, this goes to the parent
id("com.gorylenko.gradle-git-properties")

id("org.springframework.boot")
id("io.spring.dependency-management")

id("com.google.cloud.tools.jib") version "3.3.2"
}

dependencies {
Expand All @@ -27,3 +35,42 @@ configurations {
exclude("org.springframework.boot", "spring-boot-starter-logging")
}
}

jib {

from {
// JDK, not JRE (which is the default). Necessary to support sane exception traces for Project Reactor.
image = "eclipse-temurin:17-jdk"
}

to {
// Final name when the dust settles: "climategadgets/home-climate-control-springboot
image = "climategadgets/hcc-springboot-experimental"
}

pluginExtensions {
pluginExtension {
implementation = "com.google.cloud.tools.jib.gradle.extension.layerfilter.JibLayerFilterExtension"
configuration(Action<com.google.cloud.tools.jib.gradle.extension.layerfilter.Configuration> {
filters {
filter {
// Filter out all custom configurations that may be present in the source tree protected by .gitignore
glob = "**/application-*.yaml"
}
filter {
// ...but retain the Docker specific configuration
glob = "**/application-docker.yaml"
toLayer = "Docker profile"
}
}
})
}
}

container {
// Whatever profiles that are provided on the command line will be added to this one
args = listOf("--spring.profiles.active=docker")
workingDirectory = "${jib.container.appRoot}/app/"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ public static void main(String[] args) {

builder.headless(false);

// VT: NOTE: call close() or exit() on this when all the kinks are ironed out, to support a controlled lifecycle
builder.run(args);
var context = builder.run(args);

// VT: NOTE: this gets ignored by loose ends, need to fix them *and* the workflow, then we're golden
context.close();
}

@Override
Expand Down
10 changes: 10 additions & 0 deletions dz3r-app-springboot/src/main/resources/application-docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Docker specific configuration.
#
# Don't forget that DNS resolution needs to be specifically configured when you run the image.

management:
influx:
metrics:
export:
# The emitter is included into the image and will spam if kept enabled
enabled: false
35 changes: 35 additions & 0 deletions dz3r-app-springboot/src/main/resources/application-localhost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# The "localhost" profile.
#
# This profile is intended for development, it assumes all companion services to be either running locally,
# or at well known or reasonably default locations.
#
# Do NOT use this anywhere where unauthorized access is possible.
# Don't forget to include this profile when running locally.

# VT: Note to self: don't forget the /actuator/metrics endpoint

management:
endpoints:
jmx:
exposure:
include: '*'
web:
exposure:
include: '*'

influx:
metrics:
export:
enabled: true
db: hcc-micrometer
step: 10s
uri: http://localhost:8086
jmx:
metrics:
export:
enabled: true
domain: net.sf.dz3.springboot

logging:
level:
io.micrometer: INFO
32 changes: 3 additions & 29 deletions dz3r-app-springboot/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@

# /actuator/metrics endpoint

management:
endpoints:
jmx:
exposure:
include: '*'
web:
exposure:
include: '*'

influx:
metrics:
export:
enabled: true
db: hcc-micrometer
step: 10s
uri: http://localhost:8086
jmx:
metrics:
export:
enabled: true
domain: net.sf.dz3.springboot


logging:
level:
io.micrometer: INFO
# Barebones configuration.
#
# Use application-localhost.yaml as a template to create the configuration you want. Don't forget to secure it.

home-climate-control:
# From this point on, your custom configuration starts. Use a custom configuration file (application-${PROFILE}.yaml),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,5 @@ protected final void run(C rawConfig) {
new ConfigurationParser().parse(config).start().block();

logger.warn("run complete");

logger.info("");
logger.fatal("DON'T YOU EVER HOPE THIS WORKS. MORE WORK UNDERWAY, STAY TUNED");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public HccParsedConfig parse(HccRawConfig source) {
new OnewireConfigurationParser(ctx).parse(source.onewire()).block();

// VT: FIXME: Need to resolve XBee sensors and switches
logger.error("FIXME: NOT IMPLEMENTED: XBee");

// VT: FIXME: Need to resolve shell sensors and switches
logger.error("FIXME: NOT IMPLEMENTED: Shell sensors and switches");

var mocks = new MockConfigurationParser(ctx).parse(source.mocks());

Expand Down Expand Up @@ -120,8 +122,6 @@ public HccParsedConfig parse(HccRawConfig source) {
logger.error("Neither WebUI nor console are configured, how are you going to control this? Starting anyway");
}

logger.error("ConfigurationParser::parse(): NOT IMPLEMENTED");

return new HccParsedConfig();
} finally {
m.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Optional;
import java.util.Set;

public class MockConfigurationParser extends ConfigurationContextAware {
Expand All @@ -20,7 +21,7 @@ public Mono<List<Switch>> parse(Set<MockConfig> source) {

// Trivial operation, no need to bother with parallelizing
return Flux
.fromIterable(source)
.fromIterable(Optional.ofNullable(source).orElse(Set.of()))
.flatMap(c -> Flux.fromIterable(c.switches()))
.map(SwitchConfig::address)
.map(NullSwitch::new)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import reactor.core.publisher.Flux;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
Expand All @@ -20,7 +21,7 @@ public abstract class SensorSwitchResolver<T> {
protected final Set<T> source;

protected SensorSwitchResolver(Set<T> source) {
this.source = source;
this.source = Optional.ofNullable(source).orElse(Set.of());
}

public abstract Flux<Map.Entry<String, Flux<Signal<Double, Void>>>> getSensorFluxes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public ConnectorConfigurationParser(ConfigurationContext context) {

public void parse(Set<ConnectorConfig> source) {

for (var entry : source) {
for (var entry : Optional.ofNullable(source).orElse(Set.of())) {
Optional.ofNullable(entry.http()).ifPresent(this::parseHttp);
Optional.ofNullable(entry.influx()).ifPresent(this::parseInflux);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void parse(Set<FilterConfig> source) {
// VT: NOTE: Some trickery might need to be required if a feed from one filter is fed as an input
// into another; have to be smart about dependency resolution here

for (var s: source) {
for (var s: Optional.ofNullable(source).orElse(Set.of())) {
parseMedian(s.median());
parseMedianSet(s.medianSet());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public HvacConfigurationParser(ConfigurationContext context) {

public void parse(Set<HvacDeviceConfig> source) {

for (var entry : source) {
for (var entry : Optional.ofNullable(source).orElse(Set.of())) {
Flux
.fromIterable(Optional
.ofNullable(entry.heatpump())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public UnitConfigurationParser(ConfigurationContext context) {

public void parse(Set<UnitControllerConfig> source) {

for (var entry : source) {
for (var entry : Optional.ofNullable(source).orElse(Set.of())) {
Flux
.fromIterable(Optional
.ofNullable(entry.singleStage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ public ReactiveConsole parse(String instance, ConsoleConfig cf) {

// VT: NOTE: next step - just remove block() and make the constructor consume the fluxes, it iterates through them anyway

return new ReactiveConsole(instance, directors, sensors, ic, Optional.ofNullable(cf.units()).orElse(TemperatureUnit.C));
try {
return new ReactiveConsole(instance, directors, sensors, ic, Optional.ofNullable(cf.units()).orElse(TemperatureUnit.C));
} catch (UnsatisfiedLinkError ex) {
// Not really an actionable message, more like noise. No big deal, we just skip instantiation
logger.error("Did you by chance configure the Swing Console for headless environment? See debug log for details");
logger.debug("Original exception trace", ex);
return null;
}
}

private boolean isConfigured(Set<String> sensors, Map.Entry<String, Flux<Signal<Double, Void>>> s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import reactor.core.publisher.Flux;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -21,7 +22,7 @@ public DirectorConfigurationParser(ConfigurationContext context) {
public void parse(Set<UnitDirectorConfig> source) {

Flux
.fromIterable(source)
.fromIterable(Optional.ofNullable(source).orElse(Set.of()))
.map(this::parse)
.subscribe(d -> context.directors.register(d.getAddress(), d));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ public ZoneConfigurationParser(ConfigurationContext context) {

public void parse(Set<ZoneConfig> source) {

var nonNullSource = Optional.ofNullable(source).orElse(Set.of());

if (nonNullSource.isEmpty()) {

// There's a slight chance that they wanted to have just the sensors, let them be
logger.warn("No zones configured, are you sure?");
}

Flux
.fromIterable(source)
.fromIterable(nonNullSource)
.map(this::createZone)
.subscribe(kv -> context.zones.register(kv.getKey(), kv.getValue()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ public ScheduleConfigurationParser(ConfigurationContext context) {

public void parse(ScheduleConfig cf) {

parseGCal(cf.googleCalendar());

if (cf == null || cf.googleCalendar() == null) {
logger.warn("No calendar integration, proceeding anyway");
return;
}

parseGCal(cf.googleCalendar());
}

private void parseGCal(Set<CalendarConfigEntry> source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ public Flux<Signal<SystemStatus, Void>> getFlux() {

connectSensors();
connectSwitches();
connectHvacDevices();

logger.error("FIXME: NOT IMPLEMENTED: getFlux(SystemStatus)");
logger.error("FIXME: NOT IMPLEMENTED: getFlux(dampers)");
logger.error("FIXME: NOT IMPLEMENTED: getFlux(collectors)");
logger.error("FIXME: NOT IMPLEMENTED: getFlux(connectors)");

connectHvacDevices();

return statusSink.asFlux();
}
Expand Down

0 comments on commit 9905ee3

Please sign in to comment.