1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. 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 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.http.auth.aws.internal.signer.util; 17 18 import java.time.Clock; 19 import software.amazon.awssdk.annotations.SdkInternalApi; 20 import software.amazon.awssdk.http.auth.aws.crt.internal.signer.DefaultAwsCrtV4aHttpSigner; 21 import software.amazon.awssdk.http.auth.aws.eventstream.internal.signer.EventStreamV4PayloadSigner; 22 import software.amazon.awssdk.http.auth.aws.internal.signer.CredentialScope; 23 import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; 24 import software.amazon.awssdk.utils.ClassLoaderHelper; 25 import software.amazon.awssdk.utils.Logger; 26 27 /** 28 * Utilities for loading of classes and objects which have optional dependencies, and therefore need to be safely checked at 29 * runtime in order to use. 30 */ 31 @SdkInternalApi 32 public final class OptionalDependencyLoaderUtil { 33 private static final Logger LOG = Logger.loggerFor(OptionalDependencyLoaderUtil.class); 34 35 private static final String HTTP_AUTH_AWS_CRT_PATH = 36 "software.amazon.awssdk.http.auth.aws.crt.HttpAuthAwsCrt"; 37 private static final String HTTP_AUTH_AWS_CRT_MODULE = "software.amazon.awssdk:http-auth-aws-crt"; 38 private static final String HTTP_AUTH_AWS_EVENT_STREAM_PATH = 39 "software.amazon.awssdk.http.auth.aws.eventstream.HttpAuthAwsEventStream"; 40 private static final String HTTP_AUTH_AWS_EVENT_STREAM_MODULE = "software.amazon.awssdk:http-auth-aws-eventstream"; 41 OptionalDependencyLoaderUtil()42 private OptionalDependencyLoaderUtil() { 43 } 44 45 /** 46 * A helpful method that checks that some class is available on the class-path. If it fails to load, it will throw an 47 * exception based on why it failed to load. This should be used in cases where certain dependencies are optional, but the 48 * dependency is used at compile-time for strong typing (i.e. {@link EventStreamV4PayloadSigner}). 49 */ requireClass(String classPath, String module, String feature)50 private static void requireClass(String classPath, String module, String feature) { 51 try { 52 ClassLoaderHelper.loadClass(classPath, false); 53 } catch (ClassNotFoundException e) { 54 LOG.debug(() -> "Cannot find the " + classPath + " class: ", e); 55 String msg = String.format("Could not load class. You must add a dependency on the '%s' module to enable the %s " 56 + "feature: ", module, feature); 57 throw new RuntimeException(msg, e); 58 } catch (Exception e) { 59 throw new RuntimeException(String.format("Could not load class (%s): ", classPath), e); 60 } 61 } 62 getDefaultAwsCrtV4aHttpSigner()63 public static DefaultAwsCrtV4aHttpSigner getDefaultAwsCrtV4aHttpSigner() { 64 requireClass(HTTP_AUTH_AWS_CRT_PATH, HTTP_AUTH_AWS_CRT_MODULE, "CRT-V4a signing"); 65 return new DefaultAwsCrtV4aHttpSigner(); 66 } 67 getEventStreamV4PayloadSigner( AwsCredentialsIdentity credentials, CredentialScope credentialScope, Clock signingClock)68 public static EventStreamV4PayloadSigner getEventStreamV4PayloadSigner( 69 AwsCredentialsIdentity credentials, 70 CredentialScope credentialScope, 71 Clock signingClock) { 72 73 requireClass(HTTP_AUTH_AWS_EVENT_STREAM_PATH, HTTP_AUTH_AWS_EVENT_STREAM_MODULE, "Event-stream signing"); 74 return EventStreamV4PayloadSigner.builder() 75 .credentials(credentials) 76 .credentialScope(credentialScope) 77 .signingClock(signingClock) 78 .build(); 79 } 80 } 81