Ether Framework
Unified API docs for Ether modules
Loading...
Searching...
No Matches
StatusCapturingHttpExchange.java
Go to the documentation of this file.
1package dev.rafex.ether.glowroot.jetty12;
2
3import java.util.List;
4import java.util.Map;
5import java.util.Set;
6
7import org.glowroot.agent.api.Glowroot;
8
9/*-
10 * #%L
11 * ether-glowroot-jetty12
12 * %%
13 * Copyright (C) 2025 - 2026 Raúl Eduardo González Argote
14 * %%
15 * Permission is hereby granted, free of charge, to any person obtaining a copy
16 * of this software and associated documentation files (the "Software"), to deal
17 * in the Software without restriction, including without limitation the rights
18 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 * copies of the Software, and to permit persons to whom the Software is
20 * furnished to do so, subject to the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be included in
23 * all copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31 * THE SOFTWARE.
32 * #L%
33 */
34
35import dev.rafex.ether.http.core.HttpExchange;
36
37/**
38 * Package-private {@link HttpExchange} decorator that intercepts all response
39 * methods to record the HTTP status code as a Glowroot transaction attribute.
40 *
41 * <p>
42 * Adds two attributes on every response:
43 * </p>
44 * <ul>
45 * <li>{@code http.status} — e.g. {@code "200"}, {@code "404"},
46 * {@code "500"}</li>
47 * <li>{@code http.status_class} — e.g. {@code "2xx"}, {@code "4xx"},
48 * {@code "5xx"}</li>
49 * </ul>
50 */
51final class StatusCapturingHttpExchange implements HttpExchange {
52
53 private final HttpExchange delegate;
54
55 StatusCapturingHttpExchange(final HttpExchange delegate) {
56 this.delegate = delegate;
57 }
58
59 /* ── delegation: read-only methods ── */
60
61 @Override
62 public String method() {
63 return delegate.method();
64 }
65
66 @Override
67 public String path() {
68 return delegate.path();
69 }
70
71 @Override
72 public String pathParam(final String name) {
73 return delegate.pathParam(name);
74 }
75
76 @Override
77 public String queryFirst(final String name) {
78 return delegate.queryFirst(name);
79 }
80
81 @Override
82 public List<String> queryAll(final String name) {
83 return delegate.queryAll(name);
84 }
85
86 @Override
87 public Map<String, String> pathParams() {
88 return delegate.pathParams();
89 }
90
91 @Override
92 public Map<String, List<String>> queryParams() {
93 return delegate.queryParams();
94 }
95
96 @Override
97 public Set<String> allowedMethods() {
98 return delegate.allowedMethods();
99 }
100
101 /* ── interception: response-writing methods ── */
102
103 @Override
104 public void json(final int status, final Object body) {
105 recordStatus(status);
106 delegate.json(status, body);
107 }
108
109 @Override
110 public void text(final int status, final String body) {
111 recordStatus(status);
112 delegate.text(status, body);
113 }
114
115 @Override
116 public void noContent(final int status) {
117 recordStatus(status);
118 delegate.noContent(status);
119 }
120
121 /**
122 * Overridden to capture 405 and preserve the delegate's Allow-header logic.
123 */
124 @Override
125 public void methodNotAllowed() {
126 recordStatus(405);
127 delegate.methodNotAllowed();
128 }
129
130 /**
131 * Overridden to capture 204 and preserve the delegate's Allow-header logic.
132 */
133 @Override
134 public void options() {
135 recordStatus(204);
136 delegate.options();
137 }
138
139 /* ── private helpers ── */
140
141 private static void recordStatus(final int status) {
142 try {
143 Glowroot.addTransactionAttribute("http.status", String.valueOf(status));
144 Glowroot.addTransactionAttribute("http.status_class", (status / 100) + "xx");
145 } catch (final Throwable ignore) {
146 // Glowroot agent not present; do not affect response
147 }
148 }
149}
Map< String, List< String > > queryParams()
Map< String, String > pathParams()