Skip to content

Commit bab5c71

Browse files
committed
Add richer information to server status
1 parent 8d5b618 commit bab5c71

File tree

8 files changed

+44
-33
lines changed

8 files changed

+44
-33
lines changed

schemacrawler-ai-mcpserver/src/main/java/schemacrawler/tools/ai/mcpserver/server/HealthController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class HealthController {
2424
@GetMapping(
2525
value = {"/", "/health"},
2626
produces = APPLICATION_JSON_VALUE)
27-
public Map<String, String> healthCheck() {
27+
public Map<String, Object> healthCheck() {
2828
return serverHealth.currentState();
2929
}
3030
}

schemacrawler-ai-mcpserver/src/main/java/schemacrawler/tools/ai/mcpserver/server/HeartbeatLogger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class HeartbeatLogger {
3535

3636
private final Supplier<String> heartbeatMessage =
3737
() -> {
38-
final Map<String, String> heartbeatMessage = serverHealth.currentState();
38+
final Map<String, Object> heartbeatMessage = serverHealth.currentState();
3939
try {
4040
return "\n"
4141
+ mapper.writerWithDefaultPrettyPrinter().writeValueAsString(heartbeatMessage);

schemacrawler-ai-mcpserver/src/main/java/schemacrawler/tools/ai/mcpserver/server/ServerHealth.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ public class ServerHealth {
3333
@Autowired private McpServerTransportType mcpTransport;
3434
@Autowired private ExcludeTools excludeTools;
3535

36-
public Map<String, String> currentState() {
37-
final Map<String, String> currentState = new HashMap<>();
36+
public Map<String, Object> currentState() {
37+
final Map<String, Object> currentState = new HashMap<>();
3838
currentState.put("_server", getServerName());
3939
currentState.put("current-timestamp", String.valueOf(ZonedDateTime.now(ZoneOffset.UTC)));
40-
currentState.put("in-error-state", Boolean.toString(isInErrorState));
40+
currentState.put("in-error-state", isInErrorState);
4141
currentState.put("server-uptime", String.valueOf(getServerUptime()));
4242
currentState.put("transport", mcpTransport.name());
43-
currentState.put("exclude-tools", excludeTools.excludeTools().toString());
43+
currentState.put("exclude-tools", excludeTools.excludeTools());
4444
return currentState;
4545
}
4646

schemacrawler-ai-mcpserver/src/main/java/schemacrawler/tools/ai/mcpserver/utility/EmptyFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public static DatabaseConnectionSource createEmptyDatabaseConnectionSource() {
6767
case "close":
6868
case "setFirstConnectionInitializer":
6969
return null; // No-op
70+
case "toString":
71+
return "empty-data-source"; // For debugging
7072
default:
7173
throw new UnsupportedOperationException("Method not supported: " + method.getName());
7274
}

schemacrawler-ai-mcpserver/src/test/java/schemacrawler/tools/ai/mcpserver/server/test/HealthControllerTest.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
package schemacrawler.tools.ai.mcpserver.server.test;
1010

11+
import static org.hamcrest.CoreMatchers.equalTo;
1112
import static org.hamcrest.MatcherAssert.assertThat;
12-
import static org.hamcrest.Matchers.is;
1313
import static org.hamcrest.Matchers.notNullValue;
1414
import static org.mockito.Mockito.mock;
1515
import static org.mockito.Mockito.when;
@@ -81,13 +81,10 @@ ServerHealth serverHealth() {
8181
}
8282
}
8383

84-
static Map<String, String> currentState() {
85-
final Map<String, String> state = new HashMap<>();
86-
state.put("_server", "SchemaCrawler AI MCP Server Test");
87-
state.put("current-timestamp", "2025-01-01T00:00:00");
88-
state.put("in-error-state", "false");
89-
state.put("server-uptime", "PT0S");
90-
state.put("transport", "stdio");
84+
static Map<String, Object> currentState() {
85+
final Map<String, Object> state = new HashMap<>();
86+
state.put("_server", "Test Server");
87+
state.put("some-junk", true);
9188
return state;
9289
}
9390

@@ -104,10 +101,12 @@ public void healthCheckEndpoint(final String endpoint) throws Exception {
104101
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
105102
.andReturn();
106103

104+
// -- Validate the message
107105
final String currentStatusJson = mvcResult.getResponse().getContentAsString();
108106
final JsonNode node = mapper.readTree(currentStatusJson);
109-
final Map<String, Object> currentStateMap = mapper.convertValue(node, HashMap.class);
110107
assertThat("Parsed JSON should not be null", node, notNullValue());
111-
assertThat("Current state should match", currentStateMap, is(currentState()));
108+
109+
final Map<String, Object> currentStateMap = mapper.convertValue(node, HashMap.class);
110+
assertThat("Current state should match", currentStateMap, equalTo(currentState()));
112111
}
113112
}

schemacrawler-ai-mcpserver/src/test/java/schemacrawler/tools/ai/mcpserver/server/test/HeartbeatLoggerTest.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package schemacrawler.tools.ai.mcpserver.server.test;
1010

11+
import static org.hamcrest.CoreMatchers.equalTo;
1112
import static org.hamcrest.MatcherAssert.assertThat;
1213
import static org.hamcrest.Matchers.is;
1314
import static org.hamcrest.Matchers.notNullValue;
@@ -80,13 +81,10 @@ ServerHealth serverHealth() {
8081
}
8182
}
8283

83-
static Map<String, String> currentState() {
84-
final Map<String, String> state = new HashMap<>();
85-
state.put("_server", "SchemaCrawler AI MCP Server Test");
86-
state.put("current-timestamp", "2025-01-01T00:00:00");
87-
state.put("in-error-state", "false");
88-
state.put("server-uptime", "PT0S");
89-
state.put("transport", "stdio");
84+
static Map<String, Object> currentState() {
85+
final Map<String, Object> state = new HashMap<>();
86+
state.put("_server", "Test Server");
87+
state.put("some-junk", true);
9088
return state;
9189
}
9290

@@ -125,11 +123,14 @@ public void publish(final LogRecord record) {
125123

126124
// Assert
127125
assertThat("A heartbeat message should be logged", messages.isEmpty(), is(false));
126+
127+
// -- Validate the message
128128
final String currentStatusJson = messages.get(messages.size() - 1);
129129
final JsonNode node = mapper.readTree(currentStatusJson);
130-
final Map<String, Object> currentStateMap = mapper.convertValue(node, HashMap.class);
131130
assertThat("Parsed JSON should not be null", node, notNullValue());
132-
assertThat("Current state should match", currentStateMap, is(currentState()));
131+
132+
final Map<String, Object> currentStateMap = mapper.convertValue(node, HashMap.class);
133+
assertThat("Current state should match", currentStateMap, equalTo(currentState()));
133134
} finally {
134135
logger.removeHandler(handler);
135136
logger.setLevel(previousLevel);

schemacrawler-ai-mcpserver/src/test/java/schemacrawler/tools/ai/mcpserver/server/test/ServerHealthTest.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import static org.hamcrest.Matchers.notNullValue;
1717

1818
import java.time.Duration;
19+
import java.util.Collections;
1920
import java.util.Map;
2021
import org.junit.jupiter.api.DisplayName;
2122
import org.junit.jupiter.api.Test;
@@ -63,24 +64,31 @@ McpServerTransportType mcpTransport() {
6364
@Test
6465
@DisplayName("ServerHealth.currentState should include expected keys and values")
6566
public void currentState_hasExpectedEntries() {
66-
final Map<String, String> state = serverHealth.currentState();
67+
final Map<String, Object> state = serverHealth.currentState();
6768

6869
assertThat(state, is(notNullValue()));
6970
assertThat(
7071
state.keySet(),
71-
hasItems("_server", "current-timestamp", "in-error-state", "server-uptime", "transport"));
72+
hasItems(
73+
"_server",
74+
"current-timestamp",
75+
"in-error-state",
76+
"server-uptime",
77+
"transport",
78+
"exclude-tools"));
7279

7380
assertThat(state.get("_server"), is("SchemaCrawler AI MCP Server TEST"));
74-
assertThat(state.get("in-error-state"), is("false"));
81+
assertThat(state.get("in-error-state"), is(false));
7582
assertThat(state.get("transport"), is("http"));
83+
assertThat(state.get("exclude-tools"), is(Collections.emptySet()));
7684

7785
// server-uptime should be a valid ISO-8601 duration (e.g., PT123S)
78-
final String uptimeStr = state.get("server-uptime");
86+
final String uptimeStr = String.valueOf(state.get("server-uptime"));
7987
assertThat(uptimeStr, not(emptyOrNullString()));
8088
// Will throw if invalid
8189
Duration.parse(uptimeStr);
8290

83-
final String timestamp = state.get("current-timestamp");
91+
final String timestamp = String.valueOf(state.get("current-timestamp"));
8492
assertThat(timestamp, not(emptyOrNullString()));
8593
}
8694
}

schemacrawler-ai-mcpserver/src/test/java/schemacrawler/tools/ai/mcpserver/test/SchemaCrawlerMCPServerTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import static org.mockito.Mockito.mock;
1616
import static org.mockito.Mockito.when;
1717

18+
import java.util.Collections;
1819
import java.util.HashMap;
1920
import java.util.Map;
2021
import org.junit.jupiter.api.BeforeEach;
@@ -89,13 +90,13 @@ FunctionDefinitionRegistry functionDefinitionRegistry() {
8990

9091
@BeforeEach
9192
public void _stubServerHealth() {
92-
final Map<String, String> state = new HashMap<>();
93+
final Map<String, Object> state = new HashMap<>();
9394
state.put("_server", "SchemaCrawler AI MCP Server Test");
9495
state.put("current-timestamp", "2025-01-01T00:00:00");
95-
state.put("in-error-state", "false");
96+
state.put("in-error-state", false);
9697
state.put("server-uptime", "PT0S");
9798
state.put("transport", "stdio");
98-
state.put("exclude-tools", "[]");
99+
state.put("exclude-tools", Collections.emptySet());
99100
when(serverHealth.currentState()).thenReturn(state);
100101
}
101102

0 commit comments

Comments
 (0)