]> git.basschouten.com Git - openhab-addons.git/blob
946e5a6616f3d81d642b80672b2113b34b031cf6
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.millheat.internal.client;
14
15 import java.nio.charset.Charset;
16 import java.nio.charset.StandardCharsets;
17 import java.util.Locale;
18 import java.util.concurrent.atomic.AtomicLong;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jetty.client.api.Request;
22 import org.eclipse.jetty.http.HttpField;
23 import org.eclipse.jetty.http.HttpFields;
24 import org.eclipse.jetty.http.HttpHeader;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import com.google.gson.Gson;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonParser;
31 import com.google.gson.JsonSyntaxException;
32
33 /**
34  * Logs HttpClient request/response traffic.
35  *
36  * @author Gili Tzabari - Initial contribution https://stackoverflow.com/users/14731/gili
37  *         https://stackoverflow.com/questions/50318736/how-to-log-httpclient-requests-response-including-body
38  * @author Arne Seime - adapted for Millheat binding
39  */
40 @NonNullByDefault
41 public final class RequestLogger {
42     private final Logger logger = LoggerFactory.getLogger(RequestLogger.class);
43     private final AtomicLong nextId = new AtomicLong();
44     private final Gson gson;
45     private final String prefix;
46
47     public RequestLogger(final String prefix, final Gson gson) {
48         this.gson = gson;
49         this.prefix = prefix;
50     }
51
52     private void dump(final Request request) {
53         final long idV = nextId.getAndIncrement();
54         if (logger.isDebugEnabled()) {
55             final String id = prefix + "-" + idV;
56             final StringBuilder group = new StringBuilder();
57             request.onRequestBegin(theRequest -> group.append(
58                     String.format("Request %s\n%s > %s %s\n", id, id, theRequest.getMethod(), theRequest.getURI())));
59             request.onRequestHeaders(theRequest -> {
60                 for (final HttpField header : theRequest.getHeaders()) {
61                     group.append(String.format("%s > %s\n", id, header));
62                 }
63             });
64             final StringBuilder contentBuffer = new StringBuilder();
65             request.onRequestContent((theRequest, content) -> contentBuffer
66                     .append(reformatJson(getCharset(theRequest.getHeaders()).decode(content).toString())));
67             request.onRequestSuccess(theRequest -> {
68                 if (contentBuffer.length() > 0) {
69                     group.append("\n");
70                     group.append(contentBuffer);
71                 }
72                 String dataToLog = group.toString();
73                 logger.debug(dataToLog);
74                 contentBuffer.delete(0, contentBuffer.length());
75                 group.delete(0, group.length());
76             });
77             request.onResponseBegin(theResponse -> {
78                 group.append(String.format("Response %s\n%s < %s %s", id, id, theResponse.getVersion(),
79                         theResponse.getStatus()));
80                 if (theResponse.getReason() != null) {
81                     group.append(" ");
82                     group.append(theResponse.getReason());
83                 }
84                 group.append("\n");
85             });
86             request.onResponseHeaders(theResponse -> {
87                 for (final HttpField header : theResponse.getHeaders()) {
88                     group.append(String.format("%s < %s\n", id, header));
89                 }
90             });
91             request.onResponseContent((theResponse, content) -> contentBuffer
92                     .append(reformatJson(getCharset(theResponse.getHeaders()).decode(content).toString())));
93             request.onResponseSuccess(theResponse -> {
94                 if (contentBuffer.length() > 0) {
95                     group.append("\n");
96                     group.append(contentBuffer);
97                 }
98                 String dataToLog = group.toString();
99                 logger.debug(dataToLog);
100             });
101         }
102     }
103
104     private Charset getCharset(final HttpFields headers) {
105         final String contentType = headers.get(HttpHeader.CONTENT_TYPE);
106         if (contentType == null) {
107             return StandardCharsets.UTF_8;
108         }
109         final String[] tokens = contentType.toLowerCase(Locale.US).split("charset=");
110         if (tokens.length != 2) {
111             return StandardCharsets.UTF_8;
112         }
113
114         final String encoding = tokens[1].replaceAll("[;\"]", "");
115         return Charset.forName(encoding);
116     }
117
118     public Request listenTo(final Request request) {
119         dump(request);
120         return request;
121     }
122
123     private String reformatJson(final String jsonString) {
124         try {
125             final JsonElement json = JsonParser.parseString(jsonString);
126             return gson.toJson(json);
127         } catch (final JsonSyntaxException e) {
128             logger.debug("Could not reformat malformed JSON due to '{}'", e.getMessage());
129             return jsonString;
130         }
131     }
132 }