Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,14 @@

### Notes
- If you previously consumed `0.1.1`, update to `0.1.2` to pick up the dependency fix. Dependency metadata for `0.1.1` may be cached by your build; a version bump ensures the fix is resolved.
## 0.1.3 — 2025-09-13

### Enhancements
- Add structured logging via Lombok `@Slf4j` in core components.
- Logs config resolution source (ENV, system property, file) and file load location.
- Logs HTTP requests (method, URI, timeout) and responses (status), with safe truncation and redaction.
- Improve configuration discovery in fat jars/containers: try TCCL first, then class loader; support JVM system properties.

### Notes
- Enable debug logs with `logging.level.xyz.tcheeric=DEBUG` to see detailed request and configuration traces.

6 changes: 5 additions & 1 deletion phoenixd-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
</parent>

<artifactId>phoenixd-base</artifactId>
Expand All @@ -18,6 +18,10 @@
</properties>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.net.URL;
Expand All @@ -13,6 +14,7 @@
import java.util.Set;

@RequiredArgsConstructor
@Slf4j
@Data
public class Configuration {

Expand All @@ -30,10 +32,18 @@

private String resolve(@NonNull String key) {
String env = envValue(key);
if (env != null) return env;
if (env != null) {
if (log.isDebugEnabled()) log.debug("Config '{}' resolved from ENV", key);
return env;
}
String sys = System.getProperty(prefix + "." + key);
if (sys != null && !sys.isEmpty()) return sys;
return properties.getProperty(prefix + "." + key);
if (sys != null && !sys.isEmpty()) {
if (log.isDebugEnabled()) log.debug("Config '{}' resolved from system properties", key);
return sys;
}
String fileVal = properties.getProperty(prefix + "." + key);
if (fileVal != null && log.isDebugEnabled()) log.debug("Config '{}' resolved from app.properties", key);
return fileVal;
}

@SneakyThrows
Expand Down Expand Up @@ -62,9 +72,13 @@
try (InputStream in = resource.openStream()) {
if (in != null) {
this.properties.load(in);
if (log.isInfoEnabled()) log.info("Loaded configuration from '{}'", resource);
}
}
}
if (properties.isEmpty()) {
log.warn("No app.properties found on classpath; relying on ENV and system properties only");
}
}

public List<String> keys() {
Expand Down Expand Up @@ -115,7 +129,7 @@

public boolean getBoolean(@NonNull String key) {
String value = resolve(key);
return value != null ? Boolean.parseBoolean(value) : false;

Check warning on line 132 in phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/util/Configuration.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Simplifiable conditional expression

`value != null ? Boolean.parseBoolean(value) : false` can be simplified to 'value != null \&\& Boolean.parseBoolean(value)'
}

public String get(@NonNull String key, @NonNull String defaultValue) {
Expand Down
2 changes: 1 addition & 1 deletion phoenixd-mock/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
</parent>

<artifactId>phoenixd-mock</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion phoenixd-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
</parent>

<artifactId>phoenixd-model</artifactId>
Expand Down
24 changes: 22 additions & 2 deletions phoenixd-rest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
</parent>

<artifactId>phoenixd-rest</artifactId>
<packaging>jar</packaging>
<version>0.1.2</version>
<version>0.1.3</version>
<name>phoenixd-rest</name>
<url>https://maven.apache.org</url>

Expand All @@ -18,6 +18,16 @@
</properties>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>phoenixd-model</artifactId>
Expand Down Expand Up @@ -59,6 +69,16 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<org.slf4j.simpleLogger.defaultLogLevel>debug</org.slf4j.simpleLogger.defaultLogLevel>
<org.slf4j.simpleLogger.log.xyz.tcheeric>debug</org.slf4j.simpleLogger.log.xyz.tcheeric>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Data;
import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import xyz.tcheeric.phoenixd.operation.impl.PostOperation;
import xyz.tcheeric.phoenixd.common.rest.Operation;
import xyz.tcheeric.phoenixd.common.rest.Request;
Expand All @@ -25,6 +26,7 @@
import java.util.stream.Stream;

@Data
@Slf4j
public abstract class AbstractOperation implements Operation {

protected HttpRequest httpRequest;
Expand All @@ -46,13 +48,15 @@

private static String ensureScheme(String baseUrl) {
if (baseUrl == null || baseUrl.isBlank()) {
log.error("Missing required configuration 'phoenixd.base_url'");
throw new IllegalArgumentException("phoenixd.base_url is not set");
}
String trimmed = baseUrl.trim();
String lower = trimmed.toLowerCase();
if (lower.startsWith("http://") || lower.startsWith("https://")) {
return trimmed;
}
if (log.isDebugEnabled()) log.debug("No scheme in base_url '{}', defaulting to http://", baseUrl);
return "http://" + trimmed;
}

Expand Down Expand Up @@ -85,6 +89,9 @@
.timeout(Duration.ofMillis(timeout))
.method(method, bodyPublisher)
.build();
if (log.isDebugEnabled()) {
log.debug("Prepared HTTP request: method={}, uri={}, timeoutMs={}", method, this.httpRequest.uri(), timeout);
}
}

@SneakyThrows
Expand Down Expand Up @@ -112,19 +119,30 @@
.timeout(Duration.ofMillis(timeout))
.method(method, bodyPublisher)
.build();
if (log.isDebugEnabled()) {
log.debug("Prepared HTTP request: method={}, uri={}, timeoutMs={} (with params)", method, this.httpRequest.uri(), timeout);
}
}

@SneakyThrows
@Override
public Operation execute() {
if (log.isDebugEnabled()) {
log.debug("Sending HTTP request: {} {}", httpRequest.method(), httpRequest.uri());
}
CompletableFuture<HttpResponse<String>> response = HttpClient.newBuilder()
.build()

Check warning on line 134 in phoenixd-rest/src/main/java/xyz/tcheeric/phoenixd/operation/AbstractOperation.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

AutoCloseable used without 'try'-with-resources

'HttpClient' used without 'try'-with-resources statement
.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> httpResp = response.get();
this.responseBody = httpResp.body();
var statusCode = httpResp.statusCode();
if (log.isDebugEnabled()) {
log.debug("Received response: status={} uri={}", statusCode, httpRequest.uri());
}
if (statusCode < 200 || statusCode >= 300) {
throw new IOException("Failed to create invoice: " + statusCode + " " + responseBody);
String preview = responseBody == null ? "" : (responseBody.length() > 512 ? responseBody.substring(0, 512) + "..." : responseBody);
log.error("HTTP request failed: status={} uri={} bodyPreview={}", statusCode, httpRequest.uri(), preview);
throw new IOException("Failed HTTP request: " + statusCode + " " + preview);
}
return this;
}
Expand Down Expand Up @@ -154,6 +172,10 @@
.build();

this.setHttpRequest(newHttpRequest);
if (log.isDebugEnabled()) {
String safeVal = key.equalsIgnoreCase("Authorization") ? "<redacted>" : value;
log.debug("Updated header: {}={} for {} {}", key, safeVal, httpRequest.method(), httpRequest.uri());
}

return this;
}
Expand Down Expand Up @@ -185,6 +207,9 @@
throw new RuntimeException(e);
}
}
if (log.isDebugEnabled()) {
log.debug("Resolved path with variables: {}", path);
}
return path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package xyz.tcheeric.phoenixd.operation;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import xyz.tcheeric.phoenixd.operation.impl.PostOperation;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

class BaseUrlMissingTest {

@AfterEach
void cleanup() {
// Reset any system property override to avoid side effects on other tests
System.clearProperty("phoenixd.base_url");
}

// Ensures an explicit blank base_url triggers a clear configuration error
@Test
void blankBaseUrlThrows() {
System.setProperty("phoenixd.base_url", " ");
assertThatThrownBy(() -> new PostOperation("/items", "data"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("phoenixd.base_url is not set");
}

// Verifies path normalization when base_url has scheme but path lacks leading slash
@Test
void pathWithoutLeadingSlashIsNormalized() {
System.setProperty("phoenixd.base_url", "http://localhost:9740");
PostOperation op = new PostOperation("items", "data");
// URI should be http://localhost:9740/items (leading slash added)
org.assertj.core.api.Assertions.assertThat(op.getHttpRequest().uri().toString())
.isEqualTo("http://localhost:9740/items");
}
}

2 changes: 1 addition & 1 deletion phoenixd-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
</parent>

<artifactId>phoenixd-test</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.tcheeric</groupId>
<artifactId>phoenixd-java</artifactId>
<version>0.1.2</version>
<version>0.1.3</version>
<packaging>pom</packaging>

<modules>
Expand Down
Loading