|
1 |
| -# jax-rs-aws-signerv4 |
2 |
| -After scouring the Internet for a simple [AWS Signature Version 4 Signing](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) java library with limited dependencies and support for JAX-RS 2.0 and not finding one I decided to write one. |
| 1 | +# aws-java-sdk-v2-utils |
3 | 2 |
|
4 |
| -The main motivation for this library is to support JAX-RS calls to an AWS elasticsearch instance. the AWS Java API 2.0 has a client class for managing search domains but nothing for actually accessing the service. |
| 3 | +A few Java utility classes that extends the capabilities of the new aws-java-sdk-v2 library to handle use cases that are not supported by the new library yet. |
5 | 4 |
|
6 |
| -Previously I had used the AWS SDK 2.0 preview to create a [S3 presigning URL](https://gist.github.com/aaronanderson/f9e2806cc5e2c18fab4d7e60c589d160) Java utility but the current SDK codebase is geared for autogenerated clients and it is challenging to write a client by hand that initializes all the prerequisites. After examining several other Java AWS signing implementations and studying the AWS signing documentation I was able to develop a solution that meets my requirements. As an added bonus I was able to add presigning capabilities for S3 with little effort. |
| 5 | +## S3Presigner |
| 6 | +Presigning S3 download URLS is common requirement for sharing download links to S3 content. |
7 | 7 |
|
8 |
| -If including an entire JAX-RS implementation is not an option, perhaps due to an AWS Lambda library size constraint, there is an example of using the AWS 2.0 SDK to send a signed request to an endpoint. This example uses the bare minimum client configuration to avoid NPEs. |
9 |
| - |
10 |
| -## Configuration |
11 |
| -Create an instance of the AWSSignerClientRequestFilter class using the builder. Provide the AWS |
| 8 | + |
12 | 9 | ```
|
13 |
| -DefaultCredentialsProvider provider = DefaultCredentialsProvider.create(); |
14 |
| -credentials = provider.getCredentials(); |
15 |
| -AWSSignerClientRequestFilter.Builder builder = AWSSignerClientRequestFilter.builder().accessKeyID(credentials.accessKeyId()).secretAccessKey(credentials.secretAccessKey()).regionName("us-west-1").serviceName("es"); |
16 |
| -if (AwsSessionCredentials.class.isAssignableFrom(credentials.getClass())) { |
17 |
| - builder.sessionToken(() -> (((AwsSessionCredentials) credentials).sessionToken())); |
18 |
| -} |
19 |
| -AWSSignerClientRequestFilter signer = builder.build(); |
| 10 | +AwsCredentialsProviderChain credentials = AwsCredentialsProviderChain.of(InstanceProfileCredentialsProvider.builder().build(), DefaultCredentialsProvider.create()); |
| 11 | +S3Presigner s3Presigner = S3Presigner.builder().awsCredentials(credentials).build(); |
| 12 | +URI presigned = s3Presigner.presignS3UploadLink("some-bucket", "some-directory/some-file.txt"); |
20 | 13 | ```
|
21 |
| -Note I have not actually testes the token session feature but it should work. |
22 | 14 |
|
23 |
| -##JAX-RS |
24 |
| -Just register the filter/interceptor |
25 |
| -``` |
26 |
| -client.register(signer); |
27 |
| -``` |
| 15 | +## Elasticsearch |
| 16 | +the V2 SDK provides an API to manage the instances but not query the Elasticsearch endpoint. Since Elasticsearch is secured with standard AWS security a signed request is required. This utility uses JSON-P to handle the JSON response data. |
| 17 | + |
28 | 18 |
|
29 |
| -##Pre-Sign |
30 |
| -Pass in the method, requestURI, and expiration duration |
31 | 19 | ```
|
32 |
| -URI presigned = signer.presign("GET", new URI("https://some-s3-bucket.s3-us-west-1.amazonaws.com/intworkspace.json"), Duration.ofDays(1)); |
| 20 | +AWSSignerHttpClient client = AWSSignerHttpClient.builder().serviceName("es").awsCredentials(AwsCredentialsProviderChain.of(InstanceProfileCredentialsProvider.builder().build(), DefaultCredentialsProvider.create())).build(); |
| 21 | +SdkHttpFullRequest httpRequest = SdkHttpFullRequest.builder().method(SdkHttpMethod.GET).protocol("https").host("search-some-aws-elasticsearch-domain.us-west-1.es.amazonaws.com").build(); |
| 22 | +JsonObject obj = client.<JsonObject>execute(httpRequest); |
33 | 23 | ```
|
34 | 24 |
|
35 |
| -##AWS Java SDK 2.0 HTTP Client |
36 |
| -Configure the signing information and create a SdkHttpFullRequest request. Tested with version 2.0.0-preview-7 |
| 25 | +##DynamoDB to JSON |
| 26 | +A utility for converting DynamoDB AttributeValue structures into JSON-P objects and vice versa. Support for compressing JSON into AttributeValue byte storage is also available to avoid exceeding the 400k entry size limit. |
| 27 | + |
37 | 28 | ```
|
38 |
| -DefaultCredentialsProvider provider = DefaultCredentialsProvider.create(); |
39 |
| - AwsCredentials awsCredentials = provider.getCredentials(); |
40 |
| - SdkHttpClient sdkClient = ApacheSdkHttpClientFactory.builder().build().createHttpClient(); |
41 |
| - AWSSignerHttpClient client = AWSSignerHttpClient.builder().awsCredentials(awsCredentials).region(Region.US_WEST_1).serviceName("es").sdkClient(sdkClient).build(); |
| 29 | +Map<String, AttributeValue> map = new HashMap<>(); |
| 30 | +map.put("string", AttributeValue.builder().s("test").build()); |
| 31 | +AttributeValue test = AttributeValue.builder().m(map).build(); |
| 32 | +JsonObject json = (JsonObject) DynamoDBUtil.toJson(test); |
42 | 33 |
|
43 |
| - SdkHttpFullRequest httpRequest = SdkHttpFullRequest.builder().method(SdkHttpMethod.GET).protocol("https").host("search-some-aws-elasticsearch-domain.us-west-1.es.amazonaws.com").build(); |
44 |
| - JsonObject obj = client.<JsonObject> execute(httpRequest); |
| 34 | +JsonObjectBuilder builder = Json.createObjectBuilder(); |
| 35 | +builder.add("string", "test"); |
| 36 | +Map<String, AttributeValue> attrValue = DynamoDBUtil.toAttribute(builder.build()); |
45 | 37 | ```
|
| 38 | + |
0 commit comments