Java tutorial
/* * Copyright 2016 Copyright 2016 Akamai Technologies, Inc. All Rights Reserved. * * 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.akamai.edgegrid.signer; import java.util.HashSet; import java.util.Objects; import java.util.Set; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.Builder; import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; /** * This is a representation of client credential used to sign an EdgeGrid request. This object is * immutable, so you probably want to build an instance using {@link ClientCredentialBuilder} or one * of the static methods that reads from an EdgeRc file. * * @author mgawinec@akamai.com * @author mmeyer@akamai.com */ public class ClientCredential implements Comparable<ClientCredential> { /** This is the default {@code maxBodySize} to apply if not explicitly set in a credential. */ public static final int DEFAULT_MAX_BODY_SIZE_IN_BYTES = 131072; private String accessToken; private String clientSecret; private String clientToken; private Set<String> headersToSign; private String host; private Integer maxBodySize; ClientCredential(ClientCredentialBuilder b) { this.accessToken = b.accessToken; this.clientSecret = b.clientSecret; this.clientToken = b.clientToken; this.headersToSign = b.headersToSign; this.host = b.host; this.maxBodySize = b.maxBodySize; } /** * Returns a new builder. The returned builder is equivalent to the builder * generated by {@link ClientCredentialBuilder}. * * @return a fresh {@link ClientCredentialBuilder} */ public static ClientCredentialBuilder builder() { return new ClientCredentialBuilder(); } @Override public int compareTo(ClientCredential that) { return new CompareToBuilder().append(this.accessToken, that.accessToken) .append(this.clientSecret, that.clientSecret).append(this.clientToken, that.clientToken) .append(this.host, that.host).append(this.maxBodySize, that.maxBodySize).build(); } @Override public boolean equals(Object o) { if (o == null) return false; if (getClass() != o.getClass()) return false; final ClientCredential that = (ClientCredential) o; return compareTo(that) == 0; } public String getAccessToken() { return accessToken; } public String getClientSecret() { return clientSecret; } public String getClientToken() { return clientToken; } public Set<String> getHeadersToSign() { return headersToSign; } public String getHost() { return host; } public int getMaxBodySize() { if (maxBodySize == null) { return DEFAULT_MAX_BODY_SIZE_IN_BYTES; } return maxBodySize; } @Override public int hashCode() { return Objects.hash(accessToken, clientSecret, clientToken, headersToSign, host, maxBodySize); } @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.JSON_STYLE).append("accessToken", accessToken) .append("clientSecret", clientSecret).append("clientToken", clientToken) .append("headersToSign", headersToSign).append("host", host).append("maxBodySize", getMaxBodySize()) // note: intentionally using accessor here. .build(); } public static class ClientCredentialBuilder implements Builder<ClientCredential> { private String accessToken; private String clientSecret; private String clientToken; private Set<String> headersToSign = new HashSet<>(); private String host; private Integer maxBodySize; /** * Creates a new builder. The returned builder is equivalent to the builder * generated by {@link ClientCredential#builder}. */ public ClientCredentialBuilder() { } /** * Sets a token representing an OPEN API service client. * * @param clientToken a client token * @return reference back to this builder instance */ public ClientCredentialBuilder clientToken(String clientToken) { Validate.notBlank(clientToken, "clientToken cannot be blank"); this.clientToken = clientToken; return this; } /** * Sets a secret associated with a client token. * * @param clientSecret a client secret * @return reference back to this builder instance */ public ClientCredentialBuilder clientSecret(String clientSecret) { Validate.notBlank(clientSecret, "clientSecret cannot be blank"); this.clientSecret = clientSecret; return this; } /** * Sets an access token representing authorizations a client has for OPEN API service. * * @param accessToken an access token * @return reference back to this builder instance */ public ClientCredentialBuilder accessToken(String accessToken) { Validate.notBlank(accessToken, "accessToken cannot be blank"); this.accessToken = accessToken; return this; } /** * <p> * Adds all of {@code headersToSign} into the builder's internal collection. This can be * called multiple times to continue adding them. The set passed in is not stored directly, * a copy is made instead. * </p> * <p> * <i>NOTE: All header names are lower-cased for storage. In HTTP, header names are * case-insensitive anyway, and EdgeGrid does not support multiple headers with the same * name. Forcing to lowercase here improves our chance of detecting bad requests early.</i> * </p> * * @param headersToSign a {@link Set} of header names * @return reference back to this builder instance */ public ClientCredentialBuilder headersToSign(Set<String> headersToSign) { for (String headerName : headersToSign) { headerToSign(headerName); } return this; } /** * <p> * Adds {@code headerName} into the builder's internal collection. This can be called * multiple times to continue adding them. * </p> * <p> * <i>NOTE: All header names are lower-cased for storage. In HTTP, header names are * case-insensitive anyway, and EdgeGrid does not support multiple headers with the same * name. Forcing to lowercase here improves our chance of detecting bad requests early.</i> * </p> * * @param headerName a header name * @return reference back to this builder instance */ public ClientCredentialBuilder headerToSign(String headerName) { Validate.notBlank(headerName, "headerName cannot be blank"); this.headersToSign.add(headerName.toLowerCase()); return this; } /** * Sets a hostname to be used when making OPEN API requests with this credential. * * @param host a host name * @return reference back to this builder instance */ public ClientCredentialBuilder host(String host) { Validate.notBlank(host, "host cannot be blank"); this.host = host; return this; } /** * Sets the maximum body size that will be used for producing request signatures. * * @param maxBodySize a number of bytes * @return reference back to this builder instance */ public ClientCredentialBuilder maxBodySize(int maxBodySize) { this.maxBodySize = maxBodySize; return this; } /** * Returns a newly-created immutable client credential. * * @return reference back to this builder instance */ @Override public ClientCredential build() { Validate.notBlank(accessToken, "accessToken cannot be blank"); Validate.notBlank(clientSecret, "clientSecret cannot be blank"); Validate.notBlank(clientToken, "clientToken cannot be blank"); Validate.notBlank(host, "host cannot be blank"); return new ClientCredential(this); } } }