Adding and improving javadocs. Removing unused code.

Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
Max Lambrecht 2020-06-15 11:18:16 -03:00
parent f3b2a411fc
commit d00c6072bf
32 changed files with 99 additions and 237 deletions

View File

@ -4,6 +4,9 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
* Represents JWT Algorithms.
*/
public enum Algorithm { public enum Algorithm {
/** /**
@ -66,6 +69,9 @@ public enum Algorithm {
return name; return name;
} }
/**
* Represents families of algorithms.
*/
public enum Family { public enum Family {
RSA("RSA", RS256, RS384, RS512, PS256, PS384, PS512), RSA("RSA", RS256, RS384, RS512, PS256, PS384, PS512),
EC("EC", ES256, ES384, ES512), EC("EC", ES256, ES384, ES512),

View File

@ -6,7 +6,7 @@ import spiffe.exception.BundleNotFoundException;
import spiffe.spiffeid.TrustDomain; import spiffe.spiffeid.TrustDomain;
/** /**
* A <code>BundleSource</code> represents a source of bundles of type T keyed by trust domain. * Represents a source of bundles of type T keyed by trust domain.
*/ */
public interface BundleSource<T> { public interface BundleSource<T> {

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* A <code>JwtBundle</code> represents a collection of trusted JWT authorities (Public Keys) for a trust domain. * Represents a collection of trusted JWT authorities (Public Keys) for a trust domain.
*/ */
@Value @Value
public class JwtBundle implements BundleSource<JwtBundle> { public class JwtBundle implements BundleSource<JwtBundle> {

View File

@ -14,7 +14,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* A <code>JwtBundleSet</code> represents a set of JWT bundles keyed by trust domain. * Represents a set of JWT bundles keyed by trust domain.
*/ */
@Value @Value
public class JwtBundleSet implements BundleSource<JwtBundle> { public class JwtBundleSet implements BundleSource<JwtBundle> {

View File

@ -20,7 +20,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* A <code>X509Bundle</code> represents a collection of trusted X.509 authorities for a trust domain. * Represents a collection of trusted X.509 authorities for a trust domain.
*/ */
@Value @Value
public class X509Bundle implements BundleSource<X509Bundle> { public class X509Bundle implements BundleSource<X509Bundle> {

View File

@ -14,7 +14,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* A <code>X509BundleSet</code> represents a set of X.509 bundles keyed by trust domain. * Represents a set of X.509 bundles keyed by trust domain.
*/ */
@Value @Value
public class X509BundleSet implements BundleSource<X509Bundle> { public class X509BundleSet implements BundleSource<X509Bundle> {

View File

@ -1,8 +1,8 @@
package spiffe.exception; package spiffe.exception;
/** /**
* Checked exception thrown to indicate that an authority could not be * Checked exception thrown to indicate that an Authority could not be
* found in the bundle source. * found in the Bundle Source.
*/ */
public class AuthorityNotFoundException extends Exception { public class AuthorityNotFoundException extends Exception {
public AuthorityNotFoundException(String message) { public AuthorityNotFoundException(String message) {

View File

@ -1,8 +1,8 @@
package spiffe.exception; package spiffe.exception;
/** /**
* Checked exception thrown to indicate that a bundle could not be * Checked exception thrown to indicate that a Bundle could not be
* found in the bundle source. * found in the Bundle Source.
*/ */
public class BundleNotFoundException extends Exception { public class BundleNotFoundException extends Exception {
public BundleNotFoundException(String message) { public BundleNotFoundException(String message) {

View File

@ -1,7 +1,7 @@
package spiffe.exception; package spiffe.exception;
/** /**
* Checked exception thrown when there is an error creating a JwtBundle * Checked exception thrown when there is an error creating a JWT Bundle.
*/ */
public class JwtBundleException extends Exception { public class JwtBundleException extends Exception {
public JwtBundleException(String message) { public JwtBundleException(String message) {
@ -11,8 +11,4 @@ public class JwtBundleException extends Exception {
public JwtBundleException(String message, Throwable cause) { public JwtBundleException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public JwtBundleException(Throwable cause) {
super(cause);
}
} }

View File

@ -1,7 +1,7 @@
package spiffe.exception; package spiffe.exception;
/** /**
* Checked thrown when there is an error creating or initializing a JWT source * Checked thrown when there is an error creating or initializing a JWT Source.
*/ */
public class JwtSourceException extends Exception { public class JwtSourceException extends Exception {
@ -12,8 +12,4 @@ public class JwtSourceException extends Exception {
public JwtSourceException(String message, Throwable cause) { public JwtSourceException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public JwtSourceException(Throwable cause) {
super(cause);
}
} }

View File

@ -13,8 +13,4 @@ public class JwtSvidException extends Exception {
public JwtSvidException(String message, Throwable cause) { public JwtSvidException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public JwtSvidException(Throwable cause) {
super(cause);
}
} }

View File

@ -12,8 +12,4 @@ public class SocketEndpointAddressException extends Exception {
public SocketEndpointAddressException(String message, Throwable cause) { public SocketEndpointAddressException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public SocketEndpointAddressException(Throwable cause) {
super(cause);
}
} }

View File

@ -2,7 +2,7 @@ package spiffe.exception;
/** /**
* Checked exception thrown when a there was an error retrieving * Checked exception thrown when a there was an error retrieving
* or processing a X509Context. * or processing an X.509 Context.
*/ */
public class X509ContextException extends Exception { public class X509ContextException extends Exception {
public X509ContextException(String message) { public X509ContextException(String message) {
@ -12,8 +12,4 @@ public class X509ContextException extends Exception {
public X509ContextException(String message, Throwable cause) { public X509ContextException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public X509ContextException(Throwable cause) {
super(cause);
}
} }

View File

@ -1,7 +1,7 @@
package spiffe.exception; package spiffe.exception;
/** /**
* Checked thrown when there is an error creating or initializing a X.509 source * Checked thrown when there is an error creating or initializing a X.509 Source.
*/ */
public class X509SourceException extends Exception { public class X509SourceException extends Exception {
public X509SourceException(String message) { public X509SourceException(String message) {
@ -11,8 +11,4 @@ public class X509SourceException extends Exception {
public X509SourceException(String message, Throwable cause) { public X509SourceException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public X509SourceException(Throwable cause) {
super(cause);
}
} }

View File

@ -5,7 +5,6 @@ package spiffe.exception;
* the components of an X.509 SVID. * the components of an X.509 SVID.
*/ */
public class X509SvidException extends Exception { public class X509SvidException extends Exception {
public X509SvidException(String message) { public X509SvidException(String message) {
super(message); super(message);
} }
@ -13,8 +12,4 @@ public class X509SvidException extends Exception {
public X509SvidException(String message, Throwable cause) { public X509SvidException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public X509SvidException(Throwable cause) {
super(cause);
}
} }

View File

@ -10,7 +10,7 @@ import java.util.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* A <code>SpiffeId</code> represents a SPIFFE ID as defined in SPIFFE standard. * Represents a SPIFFE ID as defined in SPIFFE standard.
* <p> * <p>
* @see <a href="https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md">https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md</a> * @see <a href="https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md">https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md</a>
*/ */
@ -70,15 +70,19 @@ public class SpiffeId {
} }
/** /**
* Returns true if the trust domain of this SPIFFE ID is the same as the given trust domain. * Returns true if the trust domain of this SPIFFE ID is the same as trust domain given as parameter.
* *
* @param trustDomain instance of a {@link TrustDomain} * @param trustDomain an instance of a {@link TrustDomain}
* @return <code>true</code> if the given trust domain equals the trust domain of this object, <code>false</code> otherwise * @return <code>true</code> if the given trust domain equals the trust domain of this object, <code>false</code> otherwise
*/ */
public boolean memberOf(final TrustDomain trustDomain) { public boolean memberOf(final TrustDomain trustDomain) {
return this.trustDomain.equals(trustDomain); return this.trustDomain.equals(trustDomain);
} }
/**
* Returns the string representation of the SPIFFE ID, concatenating schema, trust domain,
* and path segments (e.g. 'spiffe://example.org/path1/path2')
*/
@Override @Override
public String toString() { public String toString() {
return String.format("%s://%s%s", SPIFFE_SCHEME, this.trustDomain.toString(), this.path); return String.format("%s://%s%s", SPIFFE_SCHEME, this.trustDomain.toString(), this.path);

View File

@ -1,12 +1,10 @@
package spiffe.spiffeid; package spiffe.spiffeid;
import lombok.val; import lombok.val;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.Security;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -22,51 +20,6 @@ public class SpiffeIdUtils {
private static final char DEFAULT_CHAR_SEPARATOR = ','; private static final char DEFAULT_CHAR_SEPARATOR = ',';
/**
* Reads the Accepted SPIFFE IDs from a system property and parses them to {@link SpiffeId} instances.
*
* @param systemProperty name of the system property that contains a list of SPIFFE IDs separated by a commas.
* @return a list of {@link SpiffeId} parsed from the values read from the security property, in case there's no values
* in the System property, it returns an emtpy list
*
* @throws IllegalArgumentException if the given system property is empty or if any of the SPIFFE IDs
* cannot be parsed
*/
public static List<SpiffeId> getSpiffeIdsFromSystemProperty(final String systemProperty) {
if (isBlank(systemProperty)) {
throw new IllegalArgumentException("Argument systemProperty cannot be empty");
}
val spiffeIds = System.getProperty(systemProperty);
if (StringUtils.isBlank(spiffeIds)) {
return EMPTY_LIST;
}
return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
}
/**
* Reads the accepted SPIFFE IDs from a security Property (defined in java.security file) and parses
* them to {@link SpiffeId} instances.
*
* @param securityProperty name of the security property that contains a list of SPIFFE IDs separated by commas.
* @return a List of {@link SpiffeId} parsed from the values read from the given security property
*
* @throws IllegalArgumentException if the security property is empty or if any of the SPIFFE IDs
* cannot be parsed
*/
public static List<SpiffeId> getSpiffeIdsFromSecurityProperty(final String securityProperty) {
if (isBlank(securityProperty)) {
throw new IllegalArgumentException("Argument securityProperty cannot be empty");
}
val spiffeIds = Security.getProperty(securityProperty);
if (StringUtils.isBlank(spiffeIds)) {
return EMPTY_LIST;
}
return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
}
/** /**
* Reads a file containing a list of SPIFFE IDs and parses them to {@link SpiffeId} instances. * Reads a file containing a list of SPIFFE IDs and parses them to {@link SpiffeId} instances.
* <p> * <p>
@ -74,8 +27,7 @@ public class SpiffeIdUtils {
* *
* @param spiffeIdsFile the path to the file containing a list of SPIFFE IDs * @param spiffeIdsFile the path to the file containing a list of SPIFFE IDs
* @return a List of {@link SpiffeId} parsed from the file provided * @return a List of {@link SpiffeId} parsed from the file provided
* * @throws IOException if the given spiffeIdsFile cannot be read
* @throws IOException if the given spiffeIdsFile cannot be read
* @throws IllegalArgumentException if any of the SPIFFE IDs in the file cannot be parsed * @throws IllegalArgumentException if any of the SPIFFE IDs in the file cannot be parsed
*/ */
public static List<SpiffeId> getSpiffeIdListFromFile(final Path spiffeIdsFile) throws IOException { public static List<SpiffeId> getSpiffeIdListFromFile(final Path spiffeIdsFile) throws IOException {
@ -92,9 +44,7 @@ public class SpiffeIdUtils {
* *
* @param spiffeIds a list of SPIFFE IDs represented in a string * @param spiffeIds a list of SPIFFE IDs represented in a string
* @param separator used to separate the SPIFFE IDs in the string. * @param separator used to separate the SPIFFE IDs in the string.
*
* @return a list of {@link SpiffeId} instances. * @return a list of {@link SpiffeId} instances.
*
* @throws IllegalArgumentException is the string provided is blank * @throws IllegalArgumentException is the string provided is blank
*/ */
public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds, final char separator) { public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds, final char separator) {
@ -108,9 +58,17 @@ public class SpiffeIdUtils {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* Return the list of the SPIFFE IDs parsed from the String parameter, using the default separator (comma)
*
* @param spiffeIds a String representing a list of SPIFFE IDs separeated by comma
* @return a list of {@link SpiffeId} instances
* @throws IllegalArgumentException is the string provided is blank
*/
public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds) { public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds) {
return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR); return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
} }
private SpiffeIdUtils() {} private SpiffeIdUtils() {
}
} }

View File

@ -12,7 +12,7 @@ import java.net.URISyntaxException;
import static spiffe.spiffeid.SpiffeId.SPIFFE_SCHEME; import static spiffe.spiffeid.SpiffeId.SPIFFE_SCHEME;
/** /**
* A <code>TrustDomain</code> represents a normalized SPIFFE trust domain (e.g. domain.test). * Represents a normalized SPIFFE trust domain (e.g. 'domain.test').
*/ */
@Value @Value
public class TrustDomain { public class TrustDomain {
@ -28,7 +28,6 @@ public class TrustDomain {
* *
* @param trustDomain a trust domain represented as a string, must not be blank. * @param trustDomain a trust domain represented as a string, must not be blank.
* @return an instance of a {@link TrustDomain} * @return an instance of a {@link TrustDomain}
*
* @throws IllegalArgumentException if the given string is blank or cannot be parsed * @throws IllegalArgumentException if the given string is blank or cannot be parsed
*/ */
public static TrustDomain of(@NonNull String trustDomain) { public static TrustDomain of(@NonNull String trustDomain) {
@ -50,8 +49,24 @@ public class TrustDomain {
return new TrustDomain(host); return new TrustDomain(host);
} }
public SpiffeId newSpiffeId(String ...path) { /**
return SpiffeId.of(this, path); * Creates a SPIFFE ID from this trust domain and the given path segments.
*
* @param segments path segments
* @return a {@link SpiffeId} with the current trust domain and the given path segments
*/
public SpiffeId newSpiffeId(String... segments) {
return SpiffeId.of(this, segments);
}
/**
* Returns the trust domain as a String.
*
* @return a String with the trust domain
*/
@Override
public String toString() {
return name;
} }
private static void validateHost(String host) { private static void validateHost(String host) {
@ -79,14 +94,4 @@ public class TrustDomain {
} }
return s; return s;
} }
/**
* Returns the trust domain as a string.
*
* @return a String with the trust domain
*/
@Override
public String toString() {
return name;
}
} }

View File

@ -28,33 +28,33 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* A <code>JwtSvid</code> represents a SPIFFE JWT-SVID. * Represents a SPIFFE JWT-SVID.
*/ */
@Value @Value
public class JwtSvid { public class JwtSvid {
/** /**
* SPIFFE ID of the JWT-SVID as present in the 'sub' claim * SPIFFE ID of the JWT-SVID as present in the 'sub' claim.
*/ */
SpiffeId spiffeId; SpiffeId spiffeId;
/** /**
* Audience is the intended recipients of JWT-SVID as present in the 'aud' claim * Audience is the intended recipients of JWT-SVID as present in the 'aud' claim.
*/ */
List<String> audience; List<String> audience;
/** /**
* Expiration time of JWT-SVID as present in 'exp' claim * Expiration time of JWT-SVID as present in 'exp' claim.
*/ */
Date expiry; Date expiry;
/** /**
* Parsed claims from token * Parsed claims from token.
*/ */
Map<String, Object> claims; Map<String, Object> claims;
/** /**
* Serialized JWT token * Serialized JWT token.
*/ */
String token; String token;
@ -67,13 +67,14 @@ public class JwtSvid {
} }
/** /**
* Parses and validates a JWT-SVID token and returns the * Parses and validates a JWT-SVID token and returns an instance of JwtSvid.
* JWT-SVID. The JWT-SVID signature is verified using the JWT bundle source. * <p>
* The JWT-SVID signature is verified using the JWT bundle source.
* *
* @param token a token as a string that is parsed and validated * @param token a token as a string that is parsed and validated
* @param jwtBundleSource an implementation of a {@link BundleSource} that provides the authority to verify the signature * @param jwtBundleSource an implementation of a {@link BundleSource} that provides the authority to verify the signature
* @param audience audience as a List of String used to validate the 'aud' claim * @param audience audience as a List of String used to validate the 'aud' claim
* @return an instance of a {@link JwtSvid} with a spiffe id parsed from the 'sub', audience from 'aud', and expiry * @return an instance of a {@link JwtSvid} with a SPIFFE ID parsed from the 'sub', audience from 'aud', and expiry
* from 'exp' claim. * from 'exp' claim.
* @throws spiffe.exception.JwtSvidException when the token expired or the expiration claim is missing, * @throws spiffe.exception.JwtSvidException when the token expired or the expiration claim is missing,
* when the algorithm is not supported, when the header 'kid' is missing, when the signature cannot be verified, or * when the algorithm is not supported, when the header 'kid' is missing, when the signature cannot be verified, or
@ -118,7 +119,9 @@ public class JwtSvid {
} }
/** /**
* Parses and validates a JWT-SVID token and returns the JWT-SVID. The JWT-SVID signature is not verified. * Parses and validates a JWT-SVID token and returns an instance of a JwtSvid.
* <p>
* The JWT-SVID signature is not verified.
* *
* @param token a token as a string that is parsed and validated * @param token a token as a string that is parsed and validated
* @param audience audience as a List of String used to validate the 'aud' claim * @param audience audience as a List of String used to validate the 'aud' claim

View File

@ -4,16 +4,16 @@ import spiffe.exception.JwtSvidException;
import spiffe.spiffeid.SpiffeId; import spiffe.spiffeid.SpiffeId;
/** /**
* A <code>JwtSvidSource</code> represents a source of SPIFFE JWT-SVIDs. * Represents a source of SPIFFE JWT-SVIDs.
*/ */
public interface JwtSvidSource { public interface JwtSvidSource {
/** /**
* Fetches a JWT-SVID from the source with the given parameters. * Fetches a JWT-SVID from the source with the given subject and audiences.
* *
* @param subject a {@link SpiffeId} * @param subject a {@link SpiffeId}
* @param audience the audience * @param audience the audience
* @param extraAudiences an array of Strings * @param extraAudiences a list of extra audiences as an array of String
* @return a {@link JwtSvid} * @return a {@link JwtSvid}
* @throws JwtSvidException when there is an error fetching the JWT SVID * @throws JwtSvidException when there is an error fetching the JWT SVID
*/ */

View File

@ -21,7 +21,7 @@ import java.util.List;
import static spiffe.internal.CertificateUtils.*; import static spiffe.internal.CertificateUtils.*;
/** /**
* A <code>X509Svid</code> represents a SPIFFE X.509 SVID. * Represents a SPIFFE X.509 SVID.
* <p> * <p>
* Contains a SPIFFE ID, a private key and a chain of X.509 certificates. * Contains a SPIFFE ID, a private key and a chain of X.509 certificates.
*/ */
@ -33,7 +33,7 @@ public class X509Svid implements X509SvidSource {
/** /**
* The X.509 certificates of the X.509-SVID. The leaf certificate is * The X.509 certificates of the X.509-SVID. The leaf certificate is
* the X.509-SVID certificate. Any remaining certificates (if any) chain * the X.509-SVID certificate. Any remaining certificates (if any) chain
* the X.509-SVID certificate back to a X.509 root for the trust domain. * the X.509-SVID certificate back to an X.509 root for the trust domain.
*/ */
List<X509Certificate> chain; List<X509Certificate> chain;
@ -88,7 +88,7 @@ public class X509Svid implements X509SvidSource {
} }
/** /**
* Return the chain of certificates as an array. * Return the chain of certificates as an array of {@link X509Certificate}
*/ */
public X509Certificate[] getChainArray() { public X509Certificate[] getChainArray() {
return chain.toArray(new X509Certificate[0]); return chain.toArray(new X509Certificate[0]);

View File

@ -1,7 +1,7 @@
package spiffe.svid.x509svid; package spiffe.svid.x509svid;
/** /**
* A <code>X509SvidSource</code> represents a source of X.509 SVIDs. * Represents a source of X.509 SVIDs.
*/ */
public interface X509SvidSource { public interface X509SvidSource {

View File

@ -16,8 +16,7 @@ import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
* A <code>X509SvidValidator</code> provides methods to validate * Provides methods to validate a chain of X.509 certificates using an X.509 bundle source.
* a chain of X.509 certificates using an X.509 bundle source.
*/ */
public class X509SvidValidator { public class X509SvidValidator {

View File

@ -27,7 +27,7 @@ public class Address {
/** /**
* Returns the default Workload API address hold by the system environment variable * Returns the default Workload API address hold by the system environment variable
* defined by SOCKET_ENV_VARIABLE * defined by SOCKET_ENV_VARIABLE.
*/ */
public static String getDefaultAddress() { public static String getDefaultAddress() {
return System.getenv(Address.SOCKET_ENV_VARIABLE); return System.getenv(Address.SOCKET_ENV_VARIABLE);

View File

@ -29,8 +29,7 @@ import java.util.logging.Level;
import static spiffe.workloadapi.internal.ThreadUtils.await; import static spiffe.workloadapi.internal.ThreadUtils.await;
/** /**
* A <code>JwtSource</code> represents a source of SPIFFE JWT SVIDs and JWT bundles * Represents a source of SPIFFE JWT SVIDs and JWT bundles maintained via the Workload API.
* maintained via the Workload API.
*/ */
@Log @Log
public class JwtSource implements JwtSvidSource, BundleSource<JwtBundle>, Closeable { public class JwtSource implements JwtSvidSource, BundleSource<JwtBundle>, Closeable {

View File

@ -1,7 +1,7 @@
package spiffe.workloadapi; package spiffe.workloadapi;
/** /**
* a <code>Watcher</code> handles updates of type T. * Watches updates of type T.
* *
* @param <T> is the type of the updates. * @param <T> is the type of the updates.
*/ */

View File

@ -36,7 +36,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Level; import java.util.logging.Level;
/** /**
* A <code>WorkloadApiClient</code> represents a client to interact with the Workload API. * Represents a client to interact with the Workload API.
* <p> * <p>
* Supports one-shot calls and watch updates for X.509 and JWT SVIDs and bundles. * Supports one-shot calls and watch updates for X.509 and JWT SVIDs and bundles.
* <p> * <p>
@ -74,7 +74,7 @@ public class WorkloadApiClient implements Closeable {
} }
/** /**
* Creates a new Workload API client. * Creates a new Workload API client configured with the given client options.
* <p> * <p>
* If the SPIFFE socket endpoint address is not provided in the options, it uses the default address. * If the SPIFFE socket endpoint address is not provided in the options, it uses the default address.
* *
@ -121,11 +121,11 @@ public class WorkloadApiClient implements Closeable {
} }
private WorkloadApiClient(SpiffeWorkloadAPIStub workloadApiAsyncStub, private WorkloadApiClient(SpiffeWorkloadAPIStub workloadApiAsyncStub,
SpiffeWorkloadAPIBlockingStub workloadApiBlockingStub, SpiffeWorkloadAPIBlockingStub workloadApiBlockingStub,
ManagedChannelWrapper managedChannel, ManagedChannelWrapper managedChannel,
BackoffPolicy backoffPolicy, BackoffPolicy backoffPolicy,
ScheduledExecutorService retryExecutor, ScheduledExecutorService retryExecutor,
ExecutorService executorService) { ExecutorService executorService) {
this.workloadApiAsyncStub = workloadApiAsyncStub; this.workloadApiAsyncStub = workloadApiAsyncStub;
this.workloadApiBlockingStub = workloadApiBlockingStub; this.workloadApiBlockingStub = workloadApiBlockingStub;
this.managedChannel = managedChannel; this.managedChannel = managedChannel;
@ -182,6 +182,7 @@ public class WorkloadApiClient implements Closeable {
* @param audience the audience of the JWT-SVID * @param audience the audience of the JWT-SVID
* @param extraAudience the extra audience for the JWT_SVID * @param extraAudience the extra audience for the JWT_SVID
* @return an instance of a {@link JwtSvid} * @return an instance of a {@link JwtSvid}
* @throws JwtSvidException if there is an error fetching or processing the JWT from the Workload API
*/ */
public JwtSvid fetchJwtSvid(@NonNull SpiffeId subject, @NonNull String audience, String... extraAudience) throws JwtSvidException { public JwtSvid fetchJwtSvid(@NonNull SpiffeId subject, @NonNull String audience, String... extraAudience) throws JwtSvidException {
List<String> audParam = new ArrayList<>(); List<String> audParam = new ArrayList<>();
@ -210,8 +211,7 @@ public class WorkloadApiClient implements Closeable {
} }
/** /**
* Validates the JWT-SVID token. The parsed and validated * Validates the JWT-SVID token. The parsed and validated JWT-SVID is returned.
* JWT-SVID is returned.
* *
* @param token JWT token * @param token JWT token
* @param audience audience of the JWT * @param audience audience of the JWT

View File

@ -8,7 +8,7 @@ import spiffe.svid.x509svid.X509Svid;
import java.util.List; import java.util.List;
/** /**
* A <code>X509Context</code> represents the X.509 materials that are fetched from the Workload API. * Represents the X.509 materials that are fetched from the Workload API.
* <p> * <p>
* Contains a list of {@link X509Svid} and a {@link X509BundleSet}. * Contains a list of {@link X509Svid} and a {@link X509BundleSet}.
*/ */

View File

@ -28,8 +28,7 @@ import java.util.logging.Level;
import static spiffe.workloadapi.internal.ThreadUtils.await; import static spiffe.workloadapi.internal.ThreadUtils.await;
/** /**
* A <code>X509Source</code> represents a source of X.509 SVIDs and X.509 bundles maintained via the * Represents a source of X.509 SVIDs and X.509 bundles maintained via the Workload API.
* Workload API.
* <p> * <p>
* It handles a {@link X509Svid} and a {@link X509BundleSet} that are updated automatically * It handles a {@link X509Svid} and a {@link X509BundleSet} that are updated automatically
* whenever there is an update from the Workload API. * whenever there is an update from the Workload API.
@ -97,7 +96,7 @@ public class X509Source implements X509SvidSource, BundleSource<X509Bundle>, Clo
* Creates a new X.509 source. It blocks until the initial update * Creates a new X.509 source. It blocks until the initial update
* has been received from the Workload API or until the timeout configured * has been received from the Workload API or until the timeout configured
* through the system property `spiffe.newX509Source.timeout` expires. * through the system property `spiffe.newX509Source.timeout` expires.
* If no timeout is configured, it blocks until it gets a X.509 update from the Workload API. * If no timeout is configured, it blocks until it gets an X.509 update from the Workload API.
* <p> * <p>
* The {@link WorkloadApiClient} can be provided in the options, if it is not, a new client is created. * The {@link WorkloadApiClient} can be provided in the options, if it is not, a new client is created.
* *

View File

@ -7,6 +7,9 @@ import lombok.val;
import java.time.Duration; import java.time.Duration;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
/**
* Represents a backoff policy for performing retries using exponential increasing delays.
*/
@Data @Data
public class BackoffPolicy { public class BackoffPolicy {
@ -55,8 +58,8 @@ public class BackoffPolicy {
* Calculate the nextDelay based on a currentDelay, applying the backoff function * Calculate the nextDelay based on a currentDelay, applying the backoff function
* If the calculated delay is greater than maxDelay, it returns maxDelay * If the calculated delay is greater than maxDelay, it returns maxDelay
* *
* @param currentDelay * @param currentDelay a {@link Duration} representing the current delay
* @return next delay * @return a {@link Duration} representing the next delay
*/ */
public Duration nextDelay(Duration currentDelay) { public Duration nextDelay(Duration currentDelay) {
val next = backoffFunction.apply(currentDelay); val next = backoffFunction.apply(currentDelay);
@ -71,7 +74,7 @@ public class BackoffPolicy {
* or if the retriesCount param is lower than the maxRetries * or if the retriesCount param is lower than the maxRetries
* *
* @param retriesCount the current number of retries * @param retriesCount the current number of retries
* @return * @return false if the number of retries did not reach the max number of retries, true otherwise
*/ */
public boolean didNotReachMaxRetries(int retriesCount) { public boolean didNotReachMaxRetries(int retriesCount) {
return (maxRetries == UNLIMITED_RETRIES || retriesCount < maxRetries); return (maxRetries == UNLIMITED_RETRIES || retriesCount < maxRetries);

View File

@ -5,7 +5,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Provides methods to schedule the execution of retries based on a backoff policy * Provides methods to schedule the execution of retries based on a backoff policy.
*/ */
public class RetryHandler { public class RetryHandler {

View File

@ -8,96 +8,11 @@ import java.net.URISyntaxException;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.Security;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class piffeIdUtilsTest { class SpiffeIdUtilsTest {
@Test
void getSpiffeIdsFromSystemProperty() {
System.setProperty("spiffe.property", " spiffe://example.org/workload1, spiffe://example.org/workload2 ");
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSystemProperty("spiffe.property");
assertNotNull(spiffeIdList);
assertEquals(2, spiffeIdList.size());
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
}
@Test
void getSpiffeIdsFromSystemPropertyThatHasNoValue_returnsEmptyList() {
System.setProperty("spiffe.property", "");
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSystemProperty("spiffe.property");
assertNotNull(spiffeIdList);
assertEquals(0, spiffeIdList.size());
}
@Test
void getSpiffeIdsFromBlankSystemProperty_throwsIllegalArgumentException() {
try {
SpiffeIdUtils.getSpiffeIdsFromSystemProperty("");
fail("should have thrown exception");
} catch (IllegalArgumentException e) {
//expected
}
}
@Test
void getSpiffeIdsFromNullSystemProperty_throwsIllegalArgumentException() {
try {
SpiffeIdUtils.getSpiffeIdsFromSystemProperty(null);
fail("should have thrown exception");
} catch (IllegalArgumentException e) {
//expected
}
}
@Test
void getSpiffeIdsFromSecurityProperty() {
Security.setProperty("spiffe.property", " spiffe://example.org/workload1, spiffe://example.org/workload2 ");
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("spiffe.property");
assertNotNull(spiffeIdList);
assertEquals(2, spiffeIdList.size());
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
}
@Test
void getSpiffeIdsFromSecurityPropertyThatHasNoValue_returnsEmptyList() {
Security.setProperty("spiffe.property", "");
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("spiffe.property");
assertNotNull(spiffeIdList);
assertEquals(0, spiffeIdList.size());
}
@Test
void getSpiffeIdsFromBlankSecurityProperty_throwsIllegalArgumentException() {
try {
SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("");
fail("should have thrown exception");
} catch (IllegalArgumentException e) {
//expected
}
}
@Test
void getSpiffeIdsFromNullSecurityProperty_throwsIllegalArgumentException() {
try {
SpiffeIdUtils.getSpiffeIdsFromSecurityProperty(null);
fail("should have thrown exception");
} catch (IllegalArgumentException e) {
//expected
}
}
@Test @Test
void getSpiffeIdListFromFile() throws URISyntaxException { void getSpiffeIdListFromFile() throws URISyntaxException {