org.apache.geode.management.internal.web.http.ClientHttpRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geode-core Show documentation
Show all versions of geode-core Show documentation
Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.management.internal.web.http;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.geode.internal.lang.Filter;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.util.CollectionUtils;
import org.apache.geode.management.internal.cli.multistep.CLIMultiStepHelper;
import org.apache.geode.management.internal.web.domain.Link;
import org.apache.geode.management.internal.web.util.UriUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriTemplate;
/**
* The ClientHttpRequest class is an abstraction modeling an HTTP request sent by a client and
* serves as the envelop encapsulating all the necessary information (headers, request parameters,
* body, etc) to send the client's request using HTTP.
*
* The required information for an HTTP request comes from a combination of the Link class
* containing the reference uniquely identifying the resource or location of where the request will
* be sent, along with the HttpHeaders class capturing the headers for the request as well as the
* generic container, HttpEntity to write the body of the request.
*
* This implementation of HttpRequest should not be confused with Spring's
* org.springframework.http.client.ClientHttpRequest interface, which is often created by factory
* using a specific HTTP client technology, like the Java HttpURLConnection or Apache's HTTP
* components, and so on.
*
*
* @see java.net.URI
* @see org.apache.geode.management.internal.web.http.HttpHeader
* @see org.apache.geode.management.internal.web.http.HttpMethod
* @see org.apache.geode.management.internal.web.domain.Link
* @see org.springframework.http.HttpEntity
* @see org.springframework.http.HttpHeaders
* @see org.springframework.http.HttpMethod
* @see org.springframework.http.HttpRequest
* @see org.springframework.http.MediaType
* @see org.springframework.util.MultiValueMap
* @see org.springframework.web.util.UriComponentsBuilder
* @see org.springframework.web.util.UriTemplate
* @since GemFire 8.0
*/
@SuppressWarnings("unused")
public class ClientHttpRequest implements HttpRequest {
// the HTTP headers to be sent with the client's request message
private final HttpHeaders requestHeaders = new HttpHeaders();
// the Link referencing the URI and method used with HTTP for the client's request
private final Link link;
// the mapping of request parameter name and values encoded for HTTP and sent with/in the client's
// request message
private final MultiValueMap requestParameters =
new LinkedMultiValueMap();
// the content/media or payload for the body of the client's HTTP request
private Object content;
/**
* Constructs an instance of the ClientHttpRequest class initialized with the specified Link
* containing the URI and method for the client's HTTP request.
*
*
* @param link the Link encapsulating the URI and method for the client's HTTP request.
* @see org.apache.geode.management.internal.web.domain.Link
*/
public ClientHttpRequest(final Link link) {
assert link != null : "The Link containing the URI and method for the client's HTTP request cannot be null!";
this.link = link;
}
/**
* Gets the HTTP headers that will be sent in the client's HTTP request message.
*
*
* @return the HTTP headers that will be sent in the client's HTTP request message.
* @see org.springframework.http.HttpHeaders
* @see org.springframework.http.HttpMessage#getHeaders()
*/
@Override
public HttpHeaders getHeaders() {
return requestHeaders;
}
/**
* Gets the Link containing the URI and method used to send the client's HTTP request.
*
*
* @return the Link encapsulating the URI and method for the client's HTTP request.
* @see org.apache.geode.management.internal.web.domain.Link
*/
public final Link getLink() {
return link;
}
/**
* Gets the HTTP method indicating the operation to perform on the resource identified in the
* client's HTTP request. This method converts GemFire's HttpMethod enumerated value from the Link
* into a corresponding Spring HttpMethod enumerated value.
*
*
* @return a Spring HttpMethod enumerated value indicating the operation to perform on the
* resource identified in the client's HTTP request.
* @see org.apache.geode.management.internal.web.http.HttpMethod
* @see org.apache.geode.management.internal.web.domain.Link#getMethod()
* @see org.springframework.http.HttpMethod
* @see org.springframework.http.HttpRequest#getMethod()
*/
@Override
public HttpMethod getMethod() {
switch (getLink().getMethod()) {
case DELETE:
return HttpMethod.DELETE;
case HEAD:
return HttpMethod.HEAD;
case OPTIONS:
return HttpMethod.OPTIONS;
case POST:
return HttpMethod.POST;
case PUT:
return HttpMethod.PUT;
case TRACE:
return HttpMethod.TRACE;
case GET:
default:
return HttpMethod.GET;
}
}
/**
* Determines whether this is an HTTP DELETE request.
*
*
* @return a boolean value indicating if the HTTP method is DELETE.
* @see #getMethod()
* @see org.springframework.http.HttpMethod#DELETE
*/
public boolean isDelete() {
return HttpMethod.DELETE.equals(getMethod());
}
/**
* Determines whether this is an HTTP GET request.
*
*
* @return a boolean value indicating if the HTTP method is GET.
* @see #getMethod()
* @see org.springframework.http.HttpMethod#GET
*/
public boolean isGet() {
return HttpMethod.GET.equals(getMethod());
}
/**
* Determines whether this is an HTTP POST request.
*
*
* @return a boolean value indicating if the HTTP method is POST.
* @see #getMethod()
* @see org.springframework.http.HttpMethod#POST
*/
public boolean isPost() {
return HttpMethod.POST.equals(getMethod());
}
/**
* Determines whether this is an HTTP PUT request.
*
*
* @return a boolean value indicating if the HTTP method is PUT.
* @see #getMethod()
* @see org.springframework.http.HttpMethod#PUT
*/
public boolean isPut() {
return HttpMethod.PUT.equals(getMethod());
}
/**
* Gets the request parameters that will be sent in the client's HTTP request message.
*
*
* @return a MultiValueMap of request parameters and values that will be sent in the client's HTTP
* request message.
* @see org.springframework.util.MultiValueMap
*/
public MultiValueMap getParameters() {
return requestParameters;
}
/**
* Gets the path variables in the URI template. Note, this would be better placed in the Link
* class, but Link cannot contain an Spring dependencies!
*
*
* @return a List of Strings for each path variable in the URI template.
* @see #getURI()
* @see org.springframework.web.util.UriTemplate
*/
protected List getPathVariables() {
return Collections
.unmodifiableList(new UriTemplate(UriUtils.decode(getURI().toString())).getVariableNames());
}
/**
* Gets the URI for the client's HTTP request. The URI may actually be an encoded URI template
* containing path variables requiring expansion.
*
*
* @return the URI of the resource targeted in the request by the client using HTTP.
* @see java.net.URI
* @see org.springframework.http.HttpRequest#getURI()
*/
@Override
public URI getURI() {
return getLink().getHref();
}
/**
* Gets the URL for the client's HTTP request.
*
*
* @return a URL as a URI referring to the location of the resource requested by the client via
* HTTP.
* @see #getURL(java.util.Map)
* @see java.net.URI
*/
public URI getURL() {
return getURL(Collections.emptyMap());
}
/**
* Gets the URL for the client's HTTP request.
*
*
* @param uriVariables a Map of URI path variables to values in order to expand the URI template
* into a URI.
* @return a URL as a URI referring to the location of the resource requested by the client via
* HTTP.
* @see #getURI()
* @see java.net.URI
* @see org.springframework.web.util.UriComponents
* @see org.springframework.web.util.UriComponentsBuilder
*/
public URI getURL(final Map uriVariables) {
final UriComponentsBuilder uriBuilder =
UriComponentsBuilder.fromUriString(UriUtils.decode(getURI().toString()));
if (isGet() || isDelete()) {
final List pathVariables = getPathVariables();
// get query parameters to append to the URI/URL based on the request parameters that are not
// path variables...
final Map> queryParameters =
CollectionUtils.removeKeys(new LinkedMultiValueMap(getParameters()),
new Filter>>() {
@Override
public boolean accept(final Map.Entry> entry) {
// GEODE-1469: since stepArgs has json string in there, we will need to encode it
// so that it won't interfere with the expand() call afterwards
if (entry.getKey().contains(CLIMultiStepHelper.STEP_ARGS)) {
List