From 289b8bc7843615c7e15c0bdd04bbfcd26d7ca0c6 Mon Sep 17 00:00:00 2001 From: Vadim Tkachenko Date: Wed, 28 Aug 2024 20:48:31 -0700 Subject: [PATCH] hcc-cli can now retrieve and verify HCC instance meta (#324) --- app/hcc-cli/build.gradle.kts | 3 + .../homeclimatecontrol/hcc/cli/HccCLI.java | 15 +++- .../hcc/client/http/HccHttpClient.java | 85 +++++++++++++++++++ app/hcc-cli/src/main/resources/log4j2.xml | 27 +++--- 4 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/client/http/HccHttpClient.java diff --git a/app/hcc-cli/build.gradle.kts b/app/hcc-cli/build.gradle.kts index 60b4d8752..362190292 100644 --- a/app/hcc-cli/build.gradle.kts +++ b/app/hcc-cli/build.gradle.kts @@ -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 { diff --git a/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/cli/HccCLI.java b/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/cli/HccCLI.java index 53d3f4a60..80bb5a434 100644 --- a/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/cli/HccCLI.java +++ b/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/cli/HccCLI.java @@ -3,6 +3,8 @@ 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; @@ -10,6 +12,9 @@ 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 { @@ -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) @@ -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(); } diff --git a/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/client/http/HccHttpClient.java b/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/client/http/HccHttpClient.java new file mode 100644 index 000000000..b628decba --- /dev/null +++ b/app/hcc-cli/src/main/java/com/homeclimatecontrol/hcc/client/http/HccHttpClient.java @@ -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 © Vadim Tkachenko 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(); + } + } +} diff --git a/app/hcc-cli/src/main/resources/log4j2.xml b/app/hcc-cli/src/main/resources/log4j2.xml index 55ae43731..d9a29cca8 100644 --- a/app/hcc-cli/src/main/resources/log4j2.xml +++ b/app/hcc-cli/src/main/resources/log4j2.xml @@ -13,15 +13,15 @@ + fileName="${logDir}/hcc-cli-trace.log" + filePattern="${logDir}/hcc-cli-trace.log.%d{yyyy-MM-dd}.gz"> - + @@ -32,15 +32,15 @@ + fileName="${logDir}/hcc-cli-debug.log" + filePattern="${logDir}/hcc-cli-debug.log.%d{yyyy-MM-dd}.gz"> - + @@ -51,15 +51,15 @@ + fileName="${logDir}/hcc-cli-info.log" + filePattern="${logDir}/hcc-cli-info.log.%d{yyyy-MM-dd}.gz"> - + @@ -71,15 +71,15 @@ + fileName="${logDir}/hcc-cli-warn.log" + filePattern="${logDir}/hcc-cli-warn.log.%d{yyyy-MM-dd}.gz"> - + @@ -95,9 +95,8 @@ - - +