import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.AuthenticationStore;
import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.StringContentProvider;
+import org.eclipse.jetty.http.HttpMethod;
/**
* The {@link RateLimitedHttpClient} is a wrapper for a Jetty HTTP client that limits the number of requests by delaying
* Create a new request to the given URL respecting rate-limits
*
* @param finalUrl the request URL
+ * @param method http request method GET/PUT/POST
+ * @param content the content (if method PUT/POST)
* @return a CompletableFuture that completes with the request
*/
- public CompletableFuture<Request> newRequest(URI finalUrl) {
+ public CompletableFuture<Request> newRequest(URI finalUrl, HttpMethod method, String content) {
// if no delay is set, return a completed CompletableFuture
- if (delay == 0) {
- return CompletableFuture.completedFuture(httpClient.newRequest(finalUrl));
- }
CompletableFuture<Request> future = new CompletableFuture<>();
- if (!requestQueue.offer(new RequestQueueEntry(finalUrl, future))) {
- future.completeExceptionally(new RejectedExecutionException("Maximum queue size exceeded."));
+ RequestQueueEntry queueEntry = new RequestQueueEntry(finalUrl, method, content, future);
+ if (delay == 0) {
+ queueEntry.completeFuture(httpClient);
+ } else {
+ if (!requestQueue.offer(queueEntry)) {
+ future.completeExceptionally(new RejectedExecutionException("Maximum queue size exceeded."));
+ }
}
return future;
}
private void processQueue() {
RequestQueueEntry queueEntry = requestQueue.poll();
if (queueEntry != null) {
- queueEntry.future.complete(httpClient.newRequest(queueEntry.finalUrl));
+ queueEntry.completeFuture(httpClient);
}
}
private static class RequestQueueEntry {
- public URI finalUrl;
- public CompletableFuture<Request> future;
+ private URI finalUrl;
+ private HttpMethod method;
+ private String content;
+ private CompletableFuture<Request> future;
- public RequestQueueEntry(URI finalUrl, CompletableFuture<Request> future) {
+ public RequestQueueEntry(URI finalUrl, HttpMethod method, String content, CompletableFuture<Request> future) {
this.finalUrl = finalUrl;
+ this.method = method;
+ this.content = content;
this.future = future;
}
+
+ /**
+ * complete the future with a request
+ *
+ * @param httpClient the client to create the request
+ */
+ public void completeFuture(HttpClient httpClient) {
+ Request request = httpClient.newRequest(finalUrl).method(method);
+ if (method != HttpMethod.GET && !content.isEmpty()) {
+ request.content(new StringContentProvider(content));
+ }
+ future.complete(request);
+ }
}
}
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
<config-description uri="channel-type:http:channel-config">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="mode" type="text">
<label>Read/Write Mode</label>
</config-description>
<config-description uri="channel-type:http:channel-config-color">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="onValue" type="text">
<label>On Value</label>
</config-description>
<config-description uri="channel-type:http:channel-config-contact">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="openValue" type="text" required="true">
<label>Open Value</label>
</config-description>
<config-description uri="channel-type:http:channel-config-dimmer">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="onValue" type="text">
<label>On Value</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<advanced>true</advanced>
</parameter>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
+ </parameter>
</config-description>
<config-description uri="channel-type:http:channel-config-number">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="mode" type="text">
<label>Read/Write Mode</label>
</config-description>
<config-description uri="channel-type:http:channel-config-player">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
-
<parameter name="playValue" type="text">
<label>Play Value</label>
<description>The value that represents PLAY</description>
</config-description>
<config-description uri="channel-type:http:channel-config-rollershutter">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="upValue" type="text">
<label>Up Value</label>
</config-description>
<config-description uri="channel-type:http:channel-config-switch">
+ <parameter name="stateTransformation" type="text">
+ <label>State Transformation</label>
+ <description>Transformation pattern used when receiving values.</description>
+ </parameter>
+ <parameter name="commandTransformation" type="text">
+ <label>Command Transformation</label>
+ <description>Transformation pattern used when sending values.</description>
+ </parameter>
<parameter name="stateExtension" type="text">
<label>State URL Extension</label>
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
<description>This value is added to the base URL configured in the thing for sending values.</description>
<advanced>true</advanced>
</parameter>
- <parameter name="stateTransformation" type="text">
- <label>State Transformation</label>
- <description>Transformation pattern used when receiving values.</description>
- </parameter>
- <parameter name="commandTransformation" type="text">
- <label>Command Transformation</label>
- <description>Transformation pattern used when sending values.</description>
+ <parameter name="stateContent" type="text">
+ <label>State Content</label>
+ <description>Content for state request (only used if method is POST/PUT)</description>
+ <advanced>true</advanced>
</parameter>
<parameter name="onValue" type="text" required="true">
<label>On Value</label>