Skip to content

Commit 0ca140d

Browse files
thcedclaude
andcommitted
feat(internal): DispatchHandler dispatches to registered HttpHandler by operationId
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5b89fbe commit 0ca140d

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.retailsvc.http;
2+
3+
public final class MissingOperationHandlerException extends RuntimeException {
4+
public MissingOperationHandlerException(String operationId) {
5+
super("no handler registered for operationId=" + operationId);
6+
}
7+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.retailsvc.http.internal;
2+
3+
import com.retailsvc.http.MissingOperationHandlerException;
4+
import com.retailsvc.http.Request;
5+
import com.sun.net.httpserver.HttpExchange;
6+
import com.sun.net.httpserver.HttpHandler;
7+
import java.io.IOException;
8+
import java.util.Map;
9+
10+
public final class DispatchHandler implements HttpHandler {
11+
private final Map<String, HttpHandler> handlers;
12+
13+
public DispatchHandler(Map<String, HttpHandler> handlers) {
14+
this.handlers = Map.copyOf(handlers);
15+
}
16+
17+
@Override
18+
public void handle(HttpExchange exchange) throws IOException {
19+
String opId = Request.operationId(exchange);
20+
HttpHandler h = handlers.get(opId);
21+
if (h == null) {
22+
throw new MissingOperationHandlerException(opId);
23+
}
24+
h.handle(exchange);
25+
}
26+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.retailsvc.http.internal;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import com.retailsvc.http.MissingOperationHandlerException;
6+
import com.retailsvc.http.Request;
7+
import com.sun.net.httpserver.HttpExchange;
8+
import com.sun.net.httpserver.HttpHandler;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
import org.junit.jupiter.api.Test;
12+
import org.mockito.Mockito;
13+
14+
class DispatchHandlerTest {
15+
private final Map<String, Object> attrs = new HashMap<>();
16+
17+
private HttpExchange exchange(String operationId) {
18+
HttpExchange ex = Mockito.mock(HttpExchange.class);
19+
Mockito.when(ex.getAttribute(Request.OPERATION_ID)).thenReturn(operationId);
20+
return ex;
21+
}
22+
23+
@Test
24+
void invokesRegisteredHandler() throws Exception {
25+
HttpHandler handler = Mockito.mock(HttpHandler.class);
26+
new DispatchHandler(Map.of("get-x", handler)).handle(exchange("get-x"));
27+
Mockito.verify(handler).handle(Mockito.any());
28+
}
29+
30+
@Test
31+
void throwsWhenHandlerMissing() {
32+
DispatchHandler d = new DispatchHandler(Map.of());
33+
assertThatThrownBy(() -> d.handle(exchange("ghost")))
34+
.isInstanceOf(MissingOperationHandlerException.class);
35+
}
36+
}

0 commit comments

Comments
 (0)