Skip to content

Commit

Permalink
hcc-cli can now retrieve and verify HCC instance meta (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
climategadgets committed Aug 29, 2024
1 parent 8feb06d commit 289b8bc
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 16 deletions.
3 changes: 3 additions & 0 deletions app/hcc-cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ application {

dependencies {

implementation(libs.httpclient)
implementation(libs.jcommander)
implementation(libs.springboot.starter)
implementation(libs.springboot.starter.log4j2)
implementation(libs.springboot.starter.rsocket)

implementation(project(":modules:hcc-data-source-api"))
}

configurations {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.homeclimatecontrol.hcc.client.http.HccHttpClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

import java.io.IOException;
import java.net.URL;

@SpringBootApplication
public class HccCLI implements CommandLineRunner {

Expand All @@ -18,6 +23,9 @@ public class HccCLI implements CommandLineRunner {
private static final String COMMAND_GET_META = "get-meta";
private static final String COMMAND_MDNS_SCAN = "mdns-scan";

private final ObjectMapper objectMapper = new ObjectMapper();
private final HccHttpClient httpClient = new HccHttpClient();

public abstract class CommandBase {

@Parameter(names = { "--url" }, description = "URL to connect to", required = true)
Expand Down Expand Up @@ -82,11 +90,14 @@ public void run(String... args) throws Exception {
}
}

private void getMeta(String url) {
private void getMeta(String url) throws IOException {
ThreadContext.push("getMeta");
try {
logger.info("url={}", url);
throw new UnsupportedOperationException("Stay tuned");
var meta = httpClient.getMeta(new URL(url));
var metaPrint = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(meta);
logger.info("META/parsed: {}", metaPrint);

} finally {
ThreadContext.pop();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.homeclimatecontrol.hcc.client.http;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.homeclimatecontrol.hcc.meta.EndpointMeta;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.net.URL;

/**
* HCC remote client using HTTP protocol.
*
* @author Copyright &copy; <a href="mailto:vt@homeclimatecontrol.com">Vadim Tkachenko</a> 2001-2024
*/
public class HccHttpClient {

private final Logger logger = LogManager.getLogger();
private final ObjectMapper objectMapper = new ObjectMapper();

private HttpClient httpClient;

private synchronized HttpClient getHttpClient() {

if (httpClient == null) {

// VT: NOTE: This is about 100ms on a decent workstation. Unexpected.
// ... but only if it is called from the constructor, otherwise it takes 2ms :O
httpClient = createClient();
}

return httpClient;
}

private HttpClient createClient() {

// VT: NOTE: Copypasted with abbreviations from HttpClientFactory (search the whole project).
// Important fact not to forget: https://github.com/home-climate-control/dz/issues/80

return HttpClientBuilder
.create()
.setMaxConnPerRoute(100)
.setDefaultRequestConfig(
RequestConfig
.custom()
.setConnectionRequestTimeout(10 * 1000)
.setConnectTimeout(10 * 1000)
.setSocketTimeout(10 * 1000)
.build()
)
.build();
}

public EndpointMeta getMeta(URL targetUrl) throws IOException {

var get = new HttpGet(targetUrl.toString());

try {

var rsp = getHttpClient().execute(get);
var rc = rsp.getStatusLine().getStatusCode();

if (rc != 200) {

logger.error("HTTP rc={}, text follows:", rc);
logger.error(EntityUtils.toString(rsp.getEntity())); // NOSONAR Not worth the effort

throw new IOException("Request to " + targetUrl + " failed with HTTP code " + rc);
}

var response = EntityUtils.toString(rsp.getEntity());

logger.trace("META/raw: {}", response);
return objectMapper.readValue(response, EndpointMeta.class);

} finally {
get.releaseConnection();
}
}
}
27 changes: 13 additions & 14 deletions app/hcc-cli/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
</Console>
<RollingFile
name="TraceAppender"
fileName="${logDir}/dz-trace.log"
filePattern="${logDir}/dz-trace.log.%d{yyyy-MM-dd}.gz">
fileName="${logDir}/hcc-cli-trace.log"
filePattern="${logDir}/hcc-cli-trace.log.%d{yyyy-MM-dd}.gz">
<PatternLayout pattern="%highlight{%d{yyyy-MM-dd HH:mm:ss,SSS} %level %class{1} %t %NDC %message%n}{TRACE=white}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logDir}" maxDepth="2">
<IfFileName glob="dz-trace.log.*.gz" />
<IfFileName glob="hcc-cli-trace.log.*.gz" />
<!-- Trace level logs are HUGE -->
<IfLastModified age="P1D" />
</Delete>
Expand All @@ -32,15 +32,15 @@
</RollingFile>
<RollingFile
name="DebugAppender"
fileName="${logDir}/dz-debug.log"
filePattern="${logDir}/dz-debug.log.%d{yyyy-MM-dd}.gz">
fileName="${logDir}/hcc-cli-debug.log"
filePattern="${logDir}/hcc-cli-debug.log.%d{yyyy-MM-dd}.gz">
<PatternLayout pattern="%highlight{%d{yyyy-MM-dd HH:mm:ss,SSS} %level %class{1} %t %NDC %message%n}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logDir}" maxDepth="2">
<IfFileName glob="dz-debug.log.*.gz" />
<IfFileName glob="hcc-cli-debug.log.*.gz" />
<!-- Debug level logs are BIG -->
<IfLastModified age="P7D" />
</Delete>
Expand All @@ -51,15 +51,15 @@
</RollingFile>
<RollingFile
name="InfoAppender"
fileName="${logDir}/dz-info.log"
filePattern="${logDir}/dz-info.log.%d{yyyy-MM-dd}.gz">
fileName="${logDir}/hcc-cli-info.log"
filePattern="${logDir}/hcc-cli-info.log.%d{yyyy-MM-dd}.gz">
<PatternLayout pattern="%highlight{%d{yyyy-MM-dd HH:mm:ss,SSS} %level %class{1} %t %NDC %message%n}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logDir}" maxDepth="2">
<IfFileName glob="dz-info.log.*.gz" />
<IfFileName glob="hcc-cli-info.log.*.gz" />
<!-- Debug level logs are BIG -->
<IfLastModified age="P7D" />
</Delete>
Expand All @@ -71,15 +71,15 @@
</RollingFile>
<RollingFile
name="WarnAppender"
fileName="${logDir}/dz-warn.log"
filePattern="${logDir}/dz-warn.log.%d{yyyy-MM-dd}.gz">
fileName="${logDir}/hcc-cli-warn.log"
filePattern="${logDir}/hcc-cli-warn.log.%d{yyyy-MM-dd}.gz">
<PatternLayout pattern="%highlight{%d{yyyy-MM-dd HH:mm:ss,SSS} %level %class{1} %t %NDC %message%n}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logDir}" maxDepth="2">
<IfFileName glob="dz-warn.log.*.gz" />
<IfFileName glob="hcc-cli-warn.log.*.gz" />
<IfLastModified age="P30D" />
</Delete>
</DefaultRolloverStrategy>
Expand All @@ -95,9 +95,8 @@
<Logger name="com.dalsemi" level="info" />
<Logger name="org.springframework" level="info" />

<!-- Reactive classes -->

<Logger name="net.sf.dz3r" level="trace" />
<Logger name="com.homeclimatecontrol" level="trace" />

<Root level="INFO">

Expand Down

0 comments on commit 289b8bc

Please sign in to comment.