com.linkedin.restli.client.util.RestliRequestUriSignature Maven / Gradle / Ivy
Show all versions of restli-client Show documentation
/*
Copyright (c) 2014 LinkedIn Corp.
Licensed 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 com.linkedin.restli.client.util;
import com.linkedin.data.Data;
import com.linkedin.data.DataMap;
import com.linkedin.restli.client.DeleteRequest;
import com.linkedin.restli.client.FindRequest;
import com.linkedin.restli.client.GetAllRequest;
import com.linkedin.restli.client.GetRequest;
import com.linkedin.restli.client.PartialUpdateRequest;
import com.linkedin.restli.client.Request;
import com.linkedin.restli.client.UpdateRequest;
import com.linkedin.restli.common.CompoundKey;
import com.linkedin.restli.common.ProtocolVersion;
import com.linkedin.restli.internal.client.QueryParamsUtil;
import com.linkedin.restli.internal.common.AllProtocolVersions;
import com.linkedin.restli.internal.common.URIParamUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
/**
*
* A "summary" object for the URI of a {@link Request}.
*
*
*
* Rest.li does not expose request URI directly because it is part of wire protocol and
* is subject to change from version to version. This class is meant to provide a robust way to
* compare and textify request URI. For example, when creating a {@link HashMap} to match request and response pairs,
* this class can be used as the key.
*
*
*
* A request URI consists of multiple fields, such as base URI template, query parameters, etc.
* This class allows user to specify which fields to be captured in the signature.
* Arbitrary combination of captured fields can be used for flexibility.
*
*
*
* The mask fields value is not used when computing hashCode(), equals() or toString().
*
*
*
* The signature does not expose the actual field values. If needed, please get them from the original {@link Request} object.
*
*
* @author Keren Jin
*/
public class RestliRequestUriSignature
{
public static enum SignatureField
{
BASE_URI_TEMPLATE,
PATH_KEYS,
ID,
QUERY_PARAMS
}
public static final Set ALL_FIELDS =
Collections.unmodifiableSet(new HashSet(Arrays.asList(SignatureField.values())));
private final Set _maskFields;
private final String _baseUriTemplate;
private final Map _pathKeys;
private final Object _id;
private final Map _queryParams;
private final Map> _queryParamClasses;
public RestliRequestUriSignature(Request> request, Set maskFields)
{
if (maskFields.isEmpty())
{
throw new IllegalArgumentException("Signature fields must include at least one field.");
}
_maskFields = maskFields;
if (maskFields.contains(SignatureField.BASE_URI_TEMPLATE))
{
_baseUriTemplate = request.getBaseUriTemplate();
}
else
{
_baseUriTemplate = null;
}
if (maskFields.contains(SignatureField.PATH_KEYS))
{
_pathKeys = request.getPathKeys();
}
else
{
_pathKeys = null;
}
if (!maskFields.contains(SignatureField.ID))
{
_id = null;
}
else if (request instanceof GetRequest)
{
_id = ((GetRequest) request).getObjectId();
}
else if (request instanceof UpdateRequest)
{
_id = ((UpdateRequest) request).getId();
}
else if (request instanceof PartialUpdateRequest)
{
_id = ((PartialUpdateRequest) request).getId();
}
else if (request instanceof DeleteRequest)
{
_id = ((DeleteRequest) request).getId();
}
else if (request instanceof FindRequest)
{
final CompoundKey assocKey = ((FindRequest) request).getAssocKey();
_id = assocKey.getNumParts() == 0 ? null : assocKey;
}
else if (request instanceof GetAllRequest)
{
final CompoundKey assocKey = ((GetAllRequest) request).getAssocKey();
_id = assocKey.getNumParts() == 0 ? null : assocKey;
}
else
{
_id = null;
}
if (maskFields.contains(SignatureField.QUERY_PARAMS))
{
// query param comparison is slightly different
// if the first level values are collections, consider unordered and do set equality check
// for deeper level values, do regular equality check
final Map rawQueryParams = request.getQueryParamsObjects();
if (rawQueryParams == null)
{
_queryParams = null;
_queryParamClasses = null;
}
else
{
_queryParams = new HashMap();
for (Map.Entry entry : rawQueryParams.entrySet())
{
if (entry.getValue() instanceof Collection)
{
_queryParams.put(entry.getKey(), new HashSet