Skip to content

Commit d3ba8de

Browse files
committed
fix flakes in sql relater adapters
1 parent 00db2f3 commit d3ba8de

File tree

6 files changed

+54
-37
lines changed

6 files changed

+54
-37
lines changed

hivemq-edge/src/main/java/com/hivemq/api/model/adapters/ProtocolAdapter.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import java.util.Objects;
2727
import java.util.Set;
2828

29-
import static java.util.Objects.requireNonNullElse;
30-
3129
/**
3230
* The API representation of a Protocol Adapter type.
3331
*/
@@ -44,16 +42,16 @@ public class ProtocolAdapter {
4442
private final @NotNull String name;
4543
@JsonProperty("description")
4644
@Schema(description = "The description")
47-
private final @NotNull String description;
45+
private final @Nullable String description;
4846
@JsonProperty("url")
4947
@Schema(description = "The url of the adapter")
50-
private final @NotNull String url;
48+
private final @Nullable String url;
5149
@JsonProperty("version")
5250
@Schema(description = "The installed version of the adapter")
5351
private final @NotNull String version;
5452
@JsonProperty("logoUrl")
5553
@Schema(description = "The logo of the adapter")
56-
private final @NotNull String logoUrl;
54+
private final @Nullable String logoUrl;
5755
@JsonProperty("provisioningUrl")
5856
@Schema(description = "The provisioning url of the adapter")
5957
private final @Nullable String provisioningUrl;
@@ -62,7 +60,7 @@ public class ProtocolAdapter {
6260
private final @NotNull String author;
6361
@JsonProperty("installed")
6462
@Schema(description = "Is the adapter installed?")
65-
private final @NotNull Boolean installed;
63+
private final @Nullable Boolean installed;
6664
@JsonProperty("category")
6765
@Schema(description = "The category of the adapter")
6866
private final @Nullable ProtocolAdapterCategory category;
@@ -83,10 +81,10 @@ public ProtocolAdapter(
8381
@JsonProperty("id") final @NotNull String id,
8482
@JsonProperty("protocol") final @NotNull String protocol,
8583
@JsonProperty("name") final @NotNull String name,
86-
@JsonProperty("description") final @NotNull String description,
87-
@JsonProperty("url") final @NotNull String url,
84+
@JsonProperty("description") final @Nullable String description,
85+
@JsonProperty("url") final @Nullable String url,
8886
@JsonProperty("version") final @NotNull String version,
89-
@JsonProperty("logoUrl") final @NotNull String logoUrl,
87+
@JsonProperty("logoUrl") final @Nullable String logoUrl,
9088
@JsonProperty("provisioningUrl") final @Nullable String provisioningUrl,
9189
@JsonProperty("author") final @NotNull String author,
9290
@JsonProperty("installed") final @Nullable Boolean installed,
@@ -105,7 +103,7 @@ public ProtocolAdapter(
105103
this.provisioningUrl = provisioningUrl;
106104
this.author = author;
107105
this.capabilities = capabilities;
108-
this.installed = requireNonNullElse(installed, Boolean.FALSE);
106+
this.installed = installed;
109107
this.category = category;
110108
this.tags = tags;
111109
this.configSchema = configSchema;
@@ -124,19 +122,19 @@ public ProtocolAdapter(
124122
return name;
125123
}
126124

127-
public @NotNull String getDescription() {
125+
public @Nullable String getDescription() {
128126
return description;
129127
}
130128

131-
public @NotNull String getUrl() {
129+
public @Nullable String getUrl() {
132130
return url;
133131
}
134132

135133
public @NotNull String getVersion() {
136134
return version;
137135
}
138136

139-
public @NotNull String getLogoUrl() {
137+
public @Nullable String getLogoUrl() {
140138
return logoUrl;
141139
}
142140

@@ -156,7 +154,7 @@ public ProtocolAdapter(
156154
return capabilities;
157155
}
158156

159-
public @NotNull Boolean getInstalled() {
157+
public @Nullable Boolean getInstalled() {
160158
return installed;
161159
}
162160

hivemq-edge/src/main/java/com/hivemq/api/model/adapters/ProtocolAdapterCategory.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import org.jetbrains.annotations.NotNull;
2222
import org.jetbrains.annotations.Nullable;
2323

24-
import static java.util.Objects.requireNonNullElse;
25-
2624
/**
2725
* A category is a unique entity and represents a curated grouping of a protocol adapter. A protocol adapter
2826
* maybe in 1 category.
@@ -49,11 +47,11 @@ public class ProtocolAdapterCategory {
4947

5048
@JsonProperty("description")
5149
@Schema(name = "description", description = "The description associated with the category.", format = "string")
52-
private final @NotNull String description;
50+
private final @Nullable String description;
5351

5452
@JsonProperty("image")
5553
@Schema(name = "image", description = "The image associated with the category.", format = "string")
56-
private final @NotNull String image;
54+
private final @Nullable String image;
5755

5856
public ProtocolAdapterCategory(
5957
@JsonProperty("name") final @NotNull String name,
@@ -62,8 +60,8 @@ public ProtocolAdapterCategory(
6260
@JsonProperty("image") final @Nullable String image) {
6361
this.name = name;
6462
this.displayName = displayName;
65-
this.description = requireNonNullElse(description, "");
66-
this.image = requireNonNullElse(image, "");
63+
this.description = description;
64+
this.image = image;
6765
}
6866

6967
public @NotNull String getName() {
@@ -74,11 +72,11 @@ public ProtocolAdapterCategory(
7472
return displayName;
7573
}
7674

77-
public @NotNull String getDescription() {
75+
public @Nullable String getDescription() {
7876
return description;
7977
}
8078

81-
public @NotNull String getImage() {
79+
public @Nullable String getImage() {
8280
return image;
8381
}
8482
}

hivemq-edge/src/main/java/com/hivemq/api/resources/impl/ProtocolAdapterApiUtils.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
import java.util.Set;
4444
import java.util.stream.Collectors;
4545

46-
import static java.util.Objects.requireNonNullElse;
47-
4846
/**
4947
* Utilities that handle the display, sort and filter logic relating to protocol adapters.
5048
*/
@@ -149,8 +147,8 @@ public class ProtocolAdapterApiUtils {
149147
return new ProtocolAdapter(module.getId(),
150148
module.getId(),
151149
module.getName(),
152-
requireNonNullElse(module.getDescription(), ""),
153-
module.getDocumentationLink() != null ? module.getDocumentationLink().getUrl() : "",
150+
module.getDescription(),
151+
module.getDocumentationLink() != null ? module.getDocumentationLink().getUrl() : null,
154152
module.getVersion(),
155153
getLogoUrl(module, configurationService),
156154
module.getProvisioningLink() != null ? module.getProvisioningLink().getUrl() : null,
@@ -163,7 +161,7 @@ public class ProtocolAdapterApiUtils {
163161
null);
164162
}
165163

166-
private static @NotNull String getLogoUrl(
164+
private static @Nullable String getLogoUrl(
167165
final @NotNull Module module,
168166
final @NotNull ConfigurationService configurationService) {
169167
if (module.getLogoUrl() != null) {
@@ -174,10 +172,10 @@ public class ProtocolAdapterApiUtils {
174172
configurationService);
175173
}
176174
}
177-
return "";
175+
return null;
178176
}
179177

180-
private static @NotNull String getLogoUrl(
178+
private static @Nullable String getLogoUrl(
181179
final @NotNull ProtocolAdapterInformation info,
182180
final @NotNull ConfigurationService configurationService,
183181
final @Nullable String xOriginalURI) {
@@ -199,12 +197,13 @@ public class ProtocolAdapterApiUtils {
199197
}
200198
}
201199
logoUrl = applyAbsoluteServerAddressInDeveloperMode(logoUrl, configurationService);
200+
return logoUrl;
202201
} else {
203202
// although it is marked as not null it is input from outside (possible customer adapter),
204203
// so we should trust but validate and at least log.
205204
log.warn("Logo url for adapter '{}' was null. ", info.getDisplayName());
205+
return null;
206206
}
207-
return logoUrl;
208207
}
209208

210209
@VisibleForTesting

modules/hivemq-edge-module-databases/src/main/java/com/hivemq/edge/adapters/databases/DatabaseConnection.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,17 @@ public void connect() {
9696
}
9797

9898
public void close() {
99-
if (ds != null) {
100-
ds.close();
99+
if (ds != null && !ds.isClosed()) {
100+
log.debug("Closing HikariCP datasource");
101+
try {
102+
// Hard shutdown of HikariCP to ensure threads are terminated
103+
ds.close();
104+
log.debug("HikariCP datasource closed successfully");
105+
} catch (final Exception e) {
106+
log.error("Error closing HikariCP datasource", e);
107+
} finally {
108+
ds = null; // Clear reference to allow GC
109+
}
101110
}
102111
}
103112
}

modules/hivemq-edge-module-databases/src/main/java/com/hivemq/edge/adapters/databases/DatabasesPollingProtocolAdapter.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ public void stop(
151151
protocolAdapterStopOutput.stoppedSuccessfully();
152152
}
153153

154+
@Override
155+
public void destroy() {
156+
log.debug("Destroying database adapter with id '{}'", adapterId);
157+
// Ensure connection pool is fully closed to prevent thread leaks
158+
databaseConnection.close();
159+
}
154160

155161
@Override
156162
public @NotNull ProtocolAdapterInformation getProtocolAdapterInformation() {
@@ -163,7 +169,7 @@ public void poll(final @NotNull BatchPollingInput pollingInput, final @NotNull B
163169
log.debug("Handling tags for the adapter");
164170
tags.forEach(tag -> loadDataFromDB(pollingOutput, (DatabasesAdapterTag) tag));
165171

166-
protocolAdapterState.setConnectionStatus(STATELESS);
172+
// Don't manually set connection status - FSM manages this automatically
167173
pollingOutput.finish();
168174
}
169175

modules/hivemq-edge-module-http/src/main/java/com/hivemq/edge/adapters/http/HttpProtocolAdapter.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public void start(
115115
final @NotNull ProtocolAdapterStartInput input,
116116
final @NotNull ProtocolAdapterStartOutput output) {
117117
try {
118-
protocolAdapterState.setConnectionStatus(STATELESS);
118+
// Don't manually set connection status - FSM manages this automatically
119119
if (httpClient == null) {
120120
final HttpClient.Builder builder = HttpClient.newBuilder();
121121
builder.version(HttpClient.Version.HTTP_1_1)
@@ -138,6 +138,13 @@ public void stop(final @NotNull ProtocolAdapterStopInput input, final @NotNull P
138138
output.stoppedSuccessfully();
139139
}
140140

141+
@Override
142+
public void destroy() {
143+
log.debug("Destroying HTTP adapter with id '{}'", adapterId);
144+
// Clear the HTTP client reference to allow GC to clean up the internal executor
145+
httpClient = null;
146+
}
147+
141148
@Override
142149
public @NotNull ProtocolAdapterInformation getProtocolAdapterInformation() {
143150
return adapterInformation;
@@ -164,11 +171,11 @@ public void poll(
164171
try {
165172
for (final CompletableFuture<HttpData> future : pollingFutures) {
166173
final var data = future.get();
167-
if (data.isSuccessStatusCode()) {
168-
protocolAdapterState.setConnectionStatus(STATELESS);
169-
} else {
174+
// Update connection status to ERROR if HTTP request failed
175+
if (!data.isSuccessStatusCode()) {
170176
protocolAdapterState.setConnectionStatus(ERROR);
171177
}
178+
// FSM manages STATELESS/CONNECTED status automatically
172179
if (data.isSuccessStatusCode() ||
173180
!adapterConfig.getHttpToMqttConfig().isHttpPublishSuccessStatusCodeOnly()) {
174181
data.getDataPoints().forEach(pollingOutput::addDataPoint);

0 commit comments

Comments
 (0)