• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.benchmark.marshaller.dynamodb;
17 
18 import java.io.ByteArrayInputStream;
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.UncheckedIOException;
23 import java.util.Map;
24 import org.openjdk.jmh.annotations.Benchmark;
25 import org.openjdk.jmh.annotations.Param;
26 import org.openjdk.jmh.annotations.Scope;
27 import org.openjdk.jmh.annotations.Setup;
28 import org.openjdk.jmh.annotations.State;
29 import software.amazon.awssdk.core.http.HttpResponseHandler;
30 import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
31 import software.amazon.awssdk.http.AbortableInputStream;
32 import software.amazon.awssdk.http.SdkHttpFullRequest;
33 import software.amazon.awssdk.http.SdkHttpFullResponse;
34 import software.amazon.awssdk.protocols.core.ExceptionMetadata;
35 import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
36 import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
37 import software.amazon.awssdk.protocols.json.JsonOperationMetadata;
38 import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
39 import software.amazon.awssdk.services.dynamodb.model.BackupInUseException;
40 import software.amazon.awssdk.services.dynamodb.model.BackupNotFoundException;
41 import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
42 import software.amazon.awssdk.services.dynamodb.model.ContinuousBackupsUnavailableException;
43 import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
44 import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
45 import software.amazon.awssdk.services.dynamodb.model.GlobalTableAlreadyExistsException;
46 import software.amazon.awssdk.services.dynamodb.model.GlobalTableNotFoundException;
47 import software.amazon.awssdk.services.dynamodb.model.IndexNotFoundException;
48 import software.amazon.awssdk.services.dynamodb.model.InternalServerErrorException;
49 import software.amazon.awssdk.services.dynamodb.model.InvalidRestoreTimeException;
50 import software.amazon.awssdk.services.dynamodb.model.ItemCollectionSizeLimitExceededException;
51 import software.amazon.awssdk.services.dynamodb.model.LimitExceededException;
52 import software.amazon.awssdk.services.dynamodb.model.PointInTimeRecoveryUnavailableException;
53 import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputExceededException;
54 import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
55 import software.amazon.awssdk.services.dynamodb.model.ReplicaAlreadyExistsException;
56 import software.amazon.awssdk.services.dynamodb.model.ReplicaNotFoundException;
57 import software.amazon.awssdk.services.dynamodb.model.ResourceInUseException;
58 import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
59 import software.amazon.awssdk.services.dynamodb.model.TableAlreadyExistsException;
60 import software.amazon.awssdk.services.dynamodb.model.TableInUseException;
61 import software.amazon.awssdk.services.dynamodb.model.TableNotFoundException;
62 import software.amazon.awssdk.services.dynamodb.transform.PutItemRequestMarshaller;
63 
64 
65 public class V2DynamoDbAttributeValue {
66 
67     private static final AwsJsonProtocolFactory JSON_PROTOCOL_FACTORY = AwsJsonProtocolFactory
68         .builder()
69         .defaultServiceExceptionSupplier(DynamoDbException::builder)
70         .protocol(AwsJsonProtocol.AWS_JSON)
71         .protocolVersion("1.0")
72         .registerModeledException(
73             ExceptionMetadata.builder().errorCode("ResourceInUseException")
74                              .exceptionBuilderSupplier(ResourceInUseException::builder).build())
75         .registerModeledException(
76             ExceptionMetadata.builder().errorCode("TableAlreadyExistsException")
77                              .exceptionBuilderSupplier(TableAlreadyExistsException::builder).build())
78         .registerModeledException(
79             ExceptionMetadata.builder().errorCode("GlobalTableAlreadyExistsException")
80                              .exceptionBuilderSupplier(GlobalTableAlreadyExistsException::builder).build())
81         .registerModeledException(
82             ExceptionMetadata.builder().errorCode("InvalidRestoreTimeException")
83                              .exceptionBuilderSupplier(InvalidRestoreTimeException::builder).build())
84         .registerModeledException(
85             ExceptionMetadata.builder().errorCode("ReplicaAlreadyExistsException")
86                              .exceptionBuilderSupplier(ReplicaAlreadyExistsException::builder).build())
87         .registerModeledException(
88             ExceptionMetadata.builder().errorCode("ConditionalCheckFailedException")
89                              .exceptionBuilderSupplier(ConditionalCheckFailedException::builder).build())
90         .registerModeledException(
91             ExceptionMetadata.builder().errorCode("BackupNotFoundException")
92                              .exceptionBuilderSupplier(BackupNotFoundException::builder).build())
93         .registerModeledException(
94             ExceptionMetadata.builder().errorCode("IndexNotFoundException")
95                              .exceptionBuilderSupplier(IndexNotFoundException::builder).build())
96         .registerModeledException(
97             ExceptionMetadata.builder().errorCode("LimitExceededException")
98                              .exceptionBuilderSupplier(LimitExceededException::builder).build())
99         .registerModeledException(
100             ExceptionMetadata.builder().errorCode("GlobalTableNotFoundException")
101                              .exceptionBuilderSupplier(GlobalTableNotFoundException::builder).build())
102         .registerModeledException(
103             ExceptionMetadata.builder().errorCode("ItemCollectionSizeLimitExceededException")
104                              .exceptionBuilderSupplier(ItemCollectionSizeLimitExceededException::builder).build())
105         .registerModeledException(
106             ExceptionMetadata.builder().errorCode("ReplicaNotFoundException")
107                              .exceptionBuilderSupplier(ReplicaNotFoundException::builder).build())
108         .registerModeledException(
109             ExceptionMetadata.builder().errorCode("TableNotFoundException")
110                              .exceptionBuilderSupplier(TableNotFoundException::builder).build())
111         .registerModeledException(
112             ExceptionMetadata.builder().errorCode("BackupInUseException")
113                              .exceptionBuilderSupplier(BackupInUseException::builder).build())
114         .registerModeledException(
115             ExceptionMetadata.builder().errorCode("ResourceNotFoundException")
116                              .exceptionBuilderSupplier(ResourceNotFoundException::builder).build())
117         .registerModeledException(
118             ExceptionMetadata.builder().errorCode("ContinuousBackupsUnavailableException")
119                              .exceptionBuilderSupplier(ContinuousBackupsUnavailableException::builder).build())
120         .registerModeledException(
121             ExceptionMetadata.builder().errorCode("TableInUseException")
122                              .exceptionBuilderSupplier(TableInUseException::builder).build())
123         .registerModeledException(
124             ExceptionMetadata.builder().errorCode("ProvisionedThroughputExceededException")
125                              .exceptionBuilderSupplier(ProvisionedThroughputExceededException::builder).build())
126         .registerModeledException(
127             ExceptionMetadata.builder().errorCode("PointInTimeRecoveryUnavailableException")
128                              .exceptionBuilderSupplier(PointInTimeRecoveryUnavailableException::builder).build())
129         .registerModeledException(
130             ExceptionMetadata.builder().errorCode("InternalServerError")
131                              .exceptionBuilderSupplier(InternalServerErrorException::builder).build())
132         .build();
133 
134     private static final PutItemRequestMarshaller PUT_ITEM_REQUEST_MARSHALLER
135         = new PutItemRequestMarshaller(getJsonProtocolFactory());
136 
getItemResponseJsonResponseHandler()137     private static HttpResponseHandler<GetItemResponse> getItemResponseJsonResponseHandler() {
138         return JSON_PROTOCOL_FACTORY.createResponseHandler(JsonOperationMetadata.builder()
139                                                                                 .isPayloadJson(true)
140                                                                                 .hasStreamingSuccessResponse(false)
141                                                                                 .build(),
142                                                            GetItemResponse::builder);
143     }
144 
145     @Benchmark
putItem(PutItemState s)146     public Object putItem(PutItemState s) {
147         return putItemRequestMarshaller().marshall(s.getReq());
148     }
149 
150     @Benchmark
getItem(GetItemState s)151     public Object getItem(GetItemState s) throws Exception {
152         SdkHttpFullResponse resp = fullResponse(s.testItem);
153         return getItemResponseJsonResponseHandler().handle(resp, new ExecutionAttributes());
154     }
155 
156     @State(Scope.Benchmark)
157     public static class PutItemState {
158         @Param({"TINY", "SMALL", "HUGE"})
159         private TestItem testItem;
160 
161         private PutItemRequest req;
162 
163         @Setup
setup()164         public void setup() {
165             req = PutItemRequest.builder().item(testItem.getValue()).build();
166         }
167 
getReq()168         public PutItemRequest getReq() {
169             return req;
170         }
171     }
172 
173     @State(Scope.Benchmark)
174     public static class GetItemState {
175         @Param({"TINY", "SMALL", "HUGE"})
176         private TestItemUnmarshalling testItem;
177     }
178 
179     public enum TestItem {
180         TINY,
181         SMALL,
182         HUGE;
183 
184         private static final AbstractItemFactory<AttributeValue> FACTORY = new V2ItemFactory();
185 
186         private Map<String, AttributeValue> av;
187 
188         static {
189             TINY.av = FACTORY.tiny();
190             SMALL.av = FACTORY.small();
191             HUGE.av = FACTORY.huge();
192         }
193 
getValue()194         public Map<String, AttributeValue> getValue() {
195             return av;
196         }
197     }
198 
199     public enum TestItemUnmarshalling {
200         TINY,
201         SMALL,
202         HUGE;
203 
204         private byte[] utf8;
205 
206         static {
207             TINY.utf8 = toUtf8ByteArray(TestItem.TINY.av);
208             SMALL.utf8 = toUtf8ByteArray(TestItem.SMALL.av);
209             HUGE.utf8 = toUtf8ByteArray(TestItem.HUGE.av);
210         }
211 
utf8()212         public byte[] utf8() {
213             return utf8;
214         }
215     }
216 
fullResponse(TestItemUnmarshalling item)217     private SdkHttpFullResponse fullResponse(TestItemUnmarshalling item) {
218         AbortableInputStream abortableInputStream = AbortableInputStream.create(new ByteArrayInputStream(item.utf8()));
219         return SdkHttpFullResponse.builder()
220                                   .statusCode(200)
221                                   .content(abortableInputStream)
222                                   .build();
223     }
224 
toUtf8ByteArray(Map<String, AttributeValue> item)225     private static byte[] toUtf8ByteArray(Map<String, AttributeValue> item) {
226         SdkHttpFullRequest marshalled = putItemRequestMarshaller().marshall(PutItemRequest.builder().item(item).build());
227         InputStream content = marshalled.contentStreamProvider().get().newStream();
228         ByteArrayOutputStream baos = new ByteArrayOutputStream();
229         byte[] buff = new byte[8192];
230         int read;
231         try {
232             while ((read = content.read(buff)) != -1) {
233                 baos.write(buff, 0, read);
234             }
235         } catch (IOException ioe) {
236             throw new UncheckedIOException(ioe);
237         }
238         return baos.toByteArray();
239     }
240 
putItemRequestMarshaller()241     private static PutItemRequestMarshaller putItemRequestMarshaller() {
242         return PUT_ITEM_REQUEST_MARSHALLER;
243     }
244 
getJsonProtocolFactory()245     private static AwsJsonProtocolFactory getJsonProtocolFactory() {
246         return JSON_PROTOCOL_FACTORY;
247     }
248 }
249