Skip to content

Commit 8519fe0

Browse files
committed
Remove usage of commons-lang3
We have had a request to minimize the external dependencies of the library. This patch removes all our usage of commons-lang3.
1 parent 7254410 commit 8519fe0

File tree

12 files changed

+210
-124
lines changed

12 files changed

+210
-124
lines changed

edgegrid-signer-core/pom.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
<groupId>ch.qos.logback</groupId>
1919
<artifactId>logback-classic</artifactId>
2020
</dependency>
21-
<dependency>
22-
<groupId>org.apache.commons</groupId>
23-
<artifactId>commons-lang3</artifactId>
24-
</dependency>
2521
<dependency>
2622
<groupId>org.hamcrest</groupId>
2723
<artifactId>hamcrest-all</artifactId>

edgegrid-signer-core/src/main/java/com/akamai/edgegrid/signer/AbstractEdgeGridRequestSigner.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
import com.akamai.edgegrid.signer.exceptions.NoMatchingCredentialException;
2020
import com.akamai.edgegrid.signer.exceptions.RequestSigningException;
2121

22-
import org.apache.commons.lang3.Validate;
23-
2422
import java.net.URI;
2523
import java.net.URISyntaxException;
24+
import java.util.Objects;
2625

2726
/**
2827
* <p> This is an abstract base class for implementing EdgeGrid request signing in a
@@ -92,8 +91,7 @@ public void sign(RequestT request, MutableRequestT requestToUpdate) throws Reque
9291
throw new NoMatchingCredentialException();
9392
}
9493
String newHost = credential.getHost();
95-
URI originalUri = requestUri(request);
96-
Validate.notNull(originalUri, "Request-URI cannot be null");
94+
URI originalUri = Objects.requireNonNull(requestUri(request), "Request-URI cannot be null");
9795
URI newUri = withNewHost(originalUri, newHost);
9896
setHost(requestToUpdate, newHost, newUri);
9997
String authorization = edgeGridSigner.getSignature(req, credential);

edgegrid-signer-core/src/main/java/com/akamai/edgegrid/signer/ClientCredential.java

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,11 @@
1616

1717
package com.akamai.edgegrid.signer;
1818

19+
import java.util.Comparator;
1920
import java.util.Objects;
2021
import java.util.Set;
2122
import java.util.TreeSet;
2223

23-
import org.apache.commons.lang3.Validate;
24-
import org.apache.commons.lang3.builder.Builder;
25-
import org.apache.commons.lang3.builder.CompareToBuilder;
26-
import org.apache.commons.lang3.builder.ToStringBuilder;
27-
import org.apache.commons.lang3.builder.ToStringStyle;
28-
2924
/**
3025
* This is a representation of client credential used to sign an EdgeGrid request. This object is
3126
* immutable, so you probably want to build an instance using {@link ClientCredentialBuilder} or one
@@ -39,6 +34,12 @@ public class ClientCredential implements Comparable<ClientCredential> {
3934
/** This is the default {@code maxBodySize} to apply if not explicitly set in a credential. */
4035
public static final int DEFAULT_MAX_BODY_SIZE_IN_BYTES = 131072;
4136

37+
/** An {@link Integer} {@link Comparator}. */
38+
private static Comparator<Integer> integerComparator = new NullSafeComparator<>();
39+
40+
/** A {@link String} {@link Comparator}. */
41+
private static Comparator<String> stringComparator = new NullSafeComparator<>();
42+
4243
private String accessToken;
4344
private String clientSecret;
4445
private String clientToken;
@@ -67,13 +68,24 @@ public static ClientCredentialBuilder builder() {
6768

6869
@Override
6970
public int compareTo(ClientCredential that) {
70-
return new CompareToBuilder()
71-
.append(this.accessToken, that.accessToken)
72-
.append(this.clientSecret, that.clientSecret)
73-
.append(this.clientToken, that.clientToken)
74-
.append(this.host, that.host)
75-
.append(this.maxBodySize, that.maxBodySize)
76-
.build();
71+
if (that == null) {
72+
return 1;
73+
}
74+
int comparison = 0;
75+
comparison = stringComparator.compare(this.accessToken, that.accessToken);
76+
if (comparison == 0) {
77+
comparison = stringComparator.compare(this.clientSecret, that.clientSecret);
78+
}
79+
if (comparison == 0) {
80+
comparison = stringComparator.compare(this.clientToken, that.clientToken);
81+
}
82+
if (comparison == 0) {
83+
comparison = stringComparator.compare(this.host, that.host);
84+
}
85+
if (comparison == 0) {
86+
comparison = integerComparator.compare(this.maxBodySize, that.maxBodySize);
87+
}
88+
return comparison;
7789
}
7890

7991
@Override
@@ -118,17 +130,18 @@ public int hashCode() {
118130

119131
@Override
120132
public String toString() {
121-
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
122-
.append("accessToken", accessToken)
123-
.append("clientSecret", clientSecret)
124-
.append("clientToken", clientToken)
125-
.append("headersToSign", headersToSign)
126-
.append("host", host)
127-
.append("maxBodySize", getMaxBodySize()) // note: intentionally using accessor here.
128-
.build();
133+
return new StringBuilder("[ ")
134+
.append("accessToken: ").append(accessToken).append("; ")
135+
.append("clientSecret: ").append(clientSecret).append("; ")
136+
.append("clientToken: ").append(clientToken).append("; ")
137+
.append("headersToSign: ").append(headersToSign).append("; ")
138+
.append("host: ").append(host).append("; ")
139+
.append("maxBodySize: ").append(getMaxBodySize()) // note: intentionally using accessor here.
140+
.append(" ]")
141+
.toString();
129142
}
130143

131-
public static class ClientCredentialBuilder implements Builder<ClientCredential> {
144+
public static class ClientCredentialBuilder {
132145
private String accessToken;
133146
private String clientSecret;
134147
private String clientToken;
@@ -151,7 +164,9 @@ public ClientCredentialBuilder() {
151164
* @return reference back to this builder instance
152165
*/
153166
public ClientCredentialBuilder clientToken(String clientToken) {
154-
Validate.notBlank(clientToken, "clientToken cannot be blank");
167+
if (Objects.isNull(clientToken) || "".equals(clientToken)) {
168+
throw new IllegalArgumentException("clientToken cannot be empty");
169+
}
155170
this.clientToken = clientToken;
156171
return this;
157172
}
@@ -164,7 +179,9 @@ public ClientCredentialBuilder clientToken(String clientToken) {
164179
* @return reference back to this builder instance
165180
*/
166181
public ClientCredentialBuilder clientSecret(String clientSecret) {
167-
Validate.notBlank(clientSecret, "clientSecret cannot be blank");
182+
if (Objects.isNull(clientSecret) || "".equals(clientSecret)) {
183+
throw new IllegalArgumentException("clientSecret cannot be empty");
184+
}
168185
this.clientSecret = clientSecret;
169186
return this;
170187
}
@@ -176,7 +193,9 @@ public ClientCredentialBuilder clientSecret(String clientSecret) {
176193
* @return reference back to this builder instance
177194
*/
178195
public ClientCredentialBuilder accessToken(String accessToken) {
179-
Validate.notBlank(accessToken, "accessToken cannot be blank");
196+
if (Objects.isNull(accessToken) || "".equals(accessToken)) {
197+
throw new IllegalArgumentException("accessToken cannot be empty");
198+
}
180199
this.accessToken = accessToken;
181200
return this;
182201
}
@@ -218,8 +237,9 @@ public ClientCredentialBuilder headersToSign(Set<String> headersToSign) {
218237
* @return reference back to this builder instance
219238
*/
220239
public ClientCredentialBuilder headerToSign(String headerName) {
221-
Validate.notBlank(headerName, "headerName cannot be blank");
222-
240+
if (Objects.isNull(headerName) || "".equals(headerName)) {
241+
throw new IllegalArgumentException("headerName cannot be empty");
242+
}
223243
this.headersToSign.add(headerName.toLowerCase());
224244
return this;
225245
}
@@ -231,7 +251,9 @@ public ClientCredentialBuilder headerToSign(String headerName) {
231251
* @return reference back to this builder instance
232252
*/
233253
public ClientCredentialBuilder host(String host) {
234-
Validate.notBlank(host, "host cannot be blank");
254+
if (Objects.isNull(host) || "".equals(host)) {
255+
throw new IllegalArgumentException("host cannot be empty");
256+
}
235257
this.host = host;
236258
return this;
237259
}
@@ -252,12 +274,11 @@ public ClientCredentialBuilder maxBodySize(int maxBodySize) {
252274
*
253275
* @return reference back to this builder instance
254276
*/
255-
@Override
256277
public ClientCredential build() {
257-
Validate.notBlank(accessToken, "accessToken cannot be blank");
258-
Validate.notBlank(clientSecret, "clientSecret cannot be blank");
259-
Validate.notBlank(clientToken, "clientToken cannot be blank");
260-
Validate.notBlank(host, "host cannot be blank");
278+
Objects.requireNonNull(accessToken, "accessToken cannot be empty");
279+
Objects.requireNonNull(clientSecret, "clientSecret cannot be empty");
280+
Objects.requireNonNull(clientToken, "clientToken cannot be empty");
281+
Objects.requireNonNull(host, "host cannot be empty");
261282
return new ClientCredential(this);
262283
}
263284

edgegrid-signer-core/src/main/java/com/akamai/edgegrid/signer/DefaultClientCredentialProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.akamai.edgegrid.signer;
1818

19-
import org.apache.commons.lang3.Validate;
19+
import java.util.Objects;
2020

2121
/**
2222
* This is a basic implementation of {@link ClientCredentialProvider} that returns the same
@@ -29,7 +29,7 @@ public class DefaultClientCredentialProvider implements ClientCredentialProvider
2929
private ClientCredential clientCredential;
3030

3131
public DefaultClientCredentialProvider(ClientCredential clientCredential) {
32-
this.clientCredential = Validate.notNull(clientCredential, "clientCredential cannot be null");
32+
this.clientCredential = Objects.requireNonNull(clientCredential, "clientCredential cannot be null");
3333
}
3434
@Override
3535
public ClientCredential getClientCredential(Request request) {

edgegrid-signer-core/src/main/java/com/akamai/edgegrid/signer/EdgeGridV1Signer.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@
2727
import java.util.Date;
2828
import java.util.List;
2929
import java.util.Map;
30+
import java.util.Objects;
3031
import java.util.TimeZone;
3132
import java.util.UUID;
3233
import java.util.regex.Matcher;
3334
import java.util.regex.Pattern;
35+
import java.util.stream.Collectors;
3436

3537
import javax.crypto.Mac;
3638
import javax.crypto.spec.SecretKeySpec;
3739

38-
import org.apache.commons.lang3.StringEscapeUtils;
39-
import org.apache.commons.lang3.StringUtils;
40-
import org.apache.commons.lang3.Validate;
41-
import org.apache.commons.lang3.builder.Builder;
4240
import org.slf4j.Logger;
4341
import org.slf4j.LoggerFactory;
4442

@@ -63,7 +61,7 @@
6361
* The main entry point to produce a signature is
6462
* {@link #getSignature(Request, ClientCredential)}. This method's two arguments are
6563
* immutable representations of exactly what they sound like: an API request and your client
66-
* credentials. They should be built with their {@link Builder} classes ({@link RequestBuilder} and
64+
* credentials. They should be built with their builder classes ({@link RequestBuilder} and
6765
* {@link ClientCredentialBuilder} respectively).
6866
* </p>
6967
*
@@ -158,7 +156,7 @@ private static String formatTimeStamp(long time) {
158156
}
159157

160158
private static String canonicalizeUri(String uri) {
161-
if (StringUtils.isEmpty(uri)) {
159+
if (uri == null || "".equals(uri)) {
162160
return "/";
163161
}
164162

@@ -171,8 +169,8 @@ private static String canonicalizeUri(String uri) {
171169

172170
String getSignature(Request request, ClientCredential credential, long timestamp, String nonce)
173171
throws RequestSigningException {
174-
Validate.notNull(credential, "credential cannot be null");
175-
Validate.notNull(request, "request cannot be null");
172+
Objects.requireNonNull(credential, "credential cannot be null");
173+
Objects.requireNonNull(request, "request cannot be null");
176174

177175
String timeStamp = formatTimeStamp(timestamp);
178176
String authData = getAuthData(credential, timeStamp, nonce);
@@ -186,9 +184,9 @@ private String getSignature(Request request, ClientCredential credential, String
186184
String authData) throws RequestSigningException {
187185
String signingKey = getSigningKey(timeStamp, credential.getClientSecret());
188186
String canonicalizedRequest = getCanonicalizedRequest(request, credential);
189-
log.debug("Canonicalized request: {}", StringEscapeUtils.escapeJava(canonicalizedRequest));
187+
log.trace("Canonicalized request: {}", canonicalizedRequest);
190188
String dataToSign = getDataToSign(canonicalizedRequest, authData);
191-
log.debug("Data to sign: {}", StringEscapeUtils.escapeJava(dataToSign));
189+
log.trace("Data to sign: {}", dataToSign);
192190

193191
return signAndEncode(dataToSign, signingKey);
194192
}
@@ -275,21 +273,20 @@ private byte[] getHash(byte[] requestBody, int offset, int len) throws RequestSi
275273
}
276274

277275
private String canonicalizeHeaders(Map<String, String> requestHeaders, ClientCredential credential) {
278-
List<String> headers = new ArrayList<>();
279276
// NOTE: Headers are expected to be in order. ClientCredential#headersToSign is a TreeSet.
280-
for (String headerName : credential.getHeadersToSign()) {
281-
String headerValue = requestHeaders.get(headerName);
282-
if (StringUtils.isBlank(headerValue)) {
283-
continue;
284-
}
285-
headers.add(headerName.toLowerCase() + ":" + canonicalizeHeaderValue(headerValue));
286-
}
287-
return StringUtils.join(headers, "\t");
277+
return requestHeaders.entrySet().stream()
278+
.filter(entry -> credential.getHeadersToSign().contains(entry.getKey()))
279+
.filter(entry -> entry.getValue() != null)
280+
.filter(entry -> !"".equals(entry.getValue()))
281+
.map(entry -> {
282+
return entry.getKey().toLowerCase() + ":" + canonicalizeHeaderValue(entry.getValue());
283+
})
284+
.collect(Collectors.joining("\t"));
288285
}
289286

290287
private String canonicalizeHeaderValue(String headerValue) {
291288
headerValue = headerValue.trim();
292-
if (StringUtils.isNotBlank(headerValue)) {
289+
if (headerValue != null && !"".equals(headerValue)) {
293290
Matcher matcher = PATTERN_SPACES.matcher(headerValue);
294291
headerValue = matcher.replaceAll(" ");
295292
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2019 Akamai Technologies, Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.akamai.edgegrid.signer;
18+
19+
import java.util.Comparator;
20+
21+
/**
22+
* This is a null-safe {@link Comparator} implementation to make the classes {@link Comparable}
23+
* implementation simpler.
24+
*
25+
* @param <T> any type that implements {@link Comparable}
26+
*/
27+
public class NullSafeComparator<T extends Comparable<T>> implements Comparator<T> {
28+
29+
@Override
30+
public int compare(final T o1, final T o2) {
31+
if (o1 == null && o2 == null) {
32+
return 0;
33+
}
34+
if (o1 == null) {
35+
return -1;
36+
}
37+
if (o2 == null) {
38+
return 1;
39+
}
40+
return o1.compareTo(o2);
41+
}
42+
43+
}

0 commit comments

Comments
 (0)