1
+ package com .myorg .urs .integration ;
2
+
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
5
+ import java .util .Map ;
6
+ import java .util .UUID ;
7
+
8
+ import org .junit .jupiter .api .AfterAll ;
9
+ import org .junit .jupiter .api .Assertions ;
10
+ import org .junit .jupiter .api .BeforeAll ;
11
+ import org .junit .jupiter .api .Test ;
12
+
13
+ import software .amazon .awssdk .core .sync .RequestBody ;
14
+ import software .amazon .awssdk .http .apache .ApacheHttpClient ;
15
+ import software .amazon .awssdk .services .cloudformation .CloudFormationClient ;
16
+ import software .amazon .awssdk .services .cloudformation .model .DescribeStacksRequest ;
17
+ import software .amazon .awssdk .services .cloudformation .model .DescribeStacksResponse ;
18
+ import software .amazon .awssdk .services .dynamodb .DynamoDbClient ;
19
+ import software .amazon .awssdk .services .dynamodb .model .AttributeValue ;
20
+ import software .amazon .awssdk .services .dynamodb .model .DeleteItemRequest ;
21
+ import software .amazon .awssdk .services .dynamodb .model .DeleteItemResponse ;
22
+ import software .amazon .awssdk .services .dynamodb .model .GetItemRequest ;
23
+ import software .amazon .awssdk .services .dynamodb .model .GetItemResponse ;
24
+ import software .amazon .awssdk .services .dynamodb .model .PutItemRequest ;
25
+ import software .amazon .awssdk .services .dynamodb .model .PutItemResponse ;
26
+ import software .amazon .awssdk .services .s3 .S3Client ;
27
+ import software .amazon .awssdk .services .s3 .model .PutObjectRequest ;
28
+ import software .amazon .awssdk .services .s3 .model .PutObjectResponse ;
29
+
30
+ public class TestFileProcessor {
31
+
32
+ private static S3Client s3Client ;
33
+
34
+ private static String dynamoDbTableName ;
35
+
36
+ private static String unicornInventoryBucket ;
37
+
38
+ private static String idPostfix ;
39
+
40
+ private static String testUnicorn ;
41
+
42
+ private static String testLocation ;
43
+
44
+ @ BeforeAll
45
+ public static void runBeforeAll () {
46
+ s3Client = S3Client .builder ()
47
+ .httpClient (ApacheHttpClient .create ())
48
+ .build ();
49
+
50
+ String awsSamStackName = System .getenv ("AWS_SAM_STACK_NAME" );
51
+
52
+ Assertions .assertNotNull (awsSamStackName );
53
+
54
+ DescribeStacksRequest describeStacksRequest = DescribeStacksRequest .builder ().stackName (awsSamStackName )
55
+ .build ();
56
+
57
+ CloudFormationClient cloudFormationClient = CloudFormationClient .builder ().build ();
58
+
59
+ DescribeStacksResponse describeStacksResponse = cloudFormationClient .describeStacks (describeStacksRequest );
60
+
61
+ Assertions .assertNotNull (describeStacksResponse );
62
+
63
+ describeStacksResponse .stacks ().forEach (stack -> stack .outputs ().forEach (output -> {
64
+ if (output .outputKey ().equals ("DynamoDBTableName" )) {
65
+ dynamoDbTableName = output .outputValue ();
66
+ } else if (output .outputKey ().equals ("UnicornInventoryBucket" )) {
67
+ unicornInventoryBucket = output .outputValue ();
68
+ }
69
+ }));
70
+
71
+ Assertions .assertNotNull (dynamoDbTableName );
72
+ Assertions .assertNotNull (unicornInventoryBucket );
73
+
74
+ idPostfix = "_%s" .formatted (UUID .randomUUID ().toString ());
75
+ testUnicorn = "TEST_UNI%s" .formatted (idPostfix );
76
+ testLocation = "TEST_LOC%s" .formatted (idPostfix );
77
+ }
78
+
79
+ @ AfterAll
80
+ public static void runAfterAll () {
81
+ // Delete testUnicorn
82
+ Map <String , AttributeValue > key = Map .of ("PK" , AttributeValue .builder ().s (testUnicorn ).build ());
83
+
84
+ GetItemRequest getItemRequest = GetItemRequest .builder ().tableName (dynamoDbTableName ).key (key ).build ();
85
+
86
+ DynamoDbClient dynamoDbClient = DynamoDbClient .builder ().build ();
87
+
88
+ GetItemResponse getItemResponse = dynamoDbClient .getItem (getItemRequest );
89
+
90
+ if (getItemResponse .hasItem ()) {
91
+ DeleteItemRequest deleteItemRequest = DeleteItemRequest .builder ().tableName (dynamoDbTableName ).key (key )
92
+ .build ();
93
+
94
+ DeleteItemResponse deleteItemResponse = dynamoDbClient .deleteItem (deleteItemRequest );
95
+
96
+ Assertions .assertNotNull (deleteItemResponse );
97
+ }
98
+
99
+ // Update LOCATION#LIST without testLocation
100
+ key = Map .of ("PK" , AttributeValue .builder ().s ("LOCATION#LIST" ).build ());
101
+
102
+ getItemRequest = GetItemRequest .builder ().tableName (dynamoDbTableName ).key (key ).build ();
103
+
104
+ dynamoDbClient = DynamoDbClient .builder ().build ();
105
+
106
+ getItemResponse = dynamoDbClient .getItem (getItemRequest );
107
+
108
+ Assertions .assertNotNull (getItemResponse );
109
+
110
+ List <AttributeValue > locations = getItemResponse .item ().get ("LOCATIONS" ).l ();
111
+
112
+ List <AttributeValue > updatedLocations = new ArrayList <>();
113
+
114
+ for (AttributeValue location : locations ) {
115
+ if (!location .s ().equals (testLocation )) {
116
+ updatedLocations .add (location );
117
+ }
118
+ }
119
+
120
+ Map <String , AttributeValue > item = Map .of ("PK" , AttributeValue .builder ().s ("LOCATION#LIST" ).build (),
121
+ "LOCATIONS" , AttributeValue .builder ().l (updatedLocations ).build ());
122
+
123
+ PutItemRequest putItemRequest = PutItemRequest .builder ().tableName (dynamoDbTableName ).item (item ).build ();
124
+
125
+ PutItemResponse putItemResponse = dynamoDbClient .putItem (putItemRequest );
126
+
127
+ Assertions .assertNotNull (putItemResponse );
128
+ }
129
+
130
+ @ Test
131
+ public void testFileProcessorHappyPath () {
132
+ Map <String , AttributeValue > key = Map .of ("PK" , AttributeValue .builder ().s (testUnicorn ).build ());
133
+
134
+ GetItemRequest getItemRequest = GetItemRequest .builder ().tableName (dynamoDbTableName ).key (key ).build ();
135
+
136
+ DynamoDbClient dynamoDbClient = DynamoDbClient .builder ().build ();
137
+
138
+ GetItemResponse getItemResponse = dynamoDbClient .getItem (getItemRequest );
139
+
140
+ Assertions .assertFalse (getItemResponse .hasItem ());
141
+
142
+ String testDataCsv = "\" Unicorn Name\" ,\" Unicorn Location\" \n " ;
143
+ testDataCsv += "\" %s\" ,\" %s\" \n " .formatted (testUnicorn , testLocation );
144
+
145
+ String testDataKey = "INTEGRATION_TEST/TEST%s.test_file_processor_happy_path.csv" .formatted (idPostfix );
146
+
147
+ PutObjectRequest putObjectRequest = PutObjectRequest .builder ().bucket (unicornInventoryBucket )
148
+ .key (testDataKey ).build ();
149
+
150
+ PutObjectResponse putObjectResponse = s3Client .putObject (putObjectRequest , RequestBody .fromString (testDataCsv ));
151
+ Assertions .assertNotNull (putObjectResponse );
152
+
153
+ int pollMaxSeconds = 30 ;
154
+ int pollCompleteSeconds = 0 ;
155
+
156
+ while (pollCompleteSeconds < pollMaxSeconds ) {
157
+ getItemResponse = dynamoDbClient .getItem (getItemRequest );
158
+
159
+ if (getItemResponse .hasItem ()) {
160
+ break ;
161
+ }
162
+
163
+ try {
164
+ Thread .sleep (1000 );
165
+ } catch (InterruptedException exception ) {
166
+ Assertions .fail (exception );
167
+ }
168
+
169
+ pollCompleteSeconds ++;
170
+ }
171
+
172
+ Assertions .assertTrue (getItemResponse .hasItem (), "Item not found after time allowed for processing." );
173
+ Assertions .assertTrue ((pollCompleteSeconds <= 2 ),
174
+ "Unicorns should be fast! Took too long: %d sec" .formatted (pollCompleteSeconds ));
175
+ Assertions .assertEquals (getItemResponse .item ().get ("PK" ).s (), testUnicorn ,
176
+ "Table PK is not set to the Unicorn Name: %s expected %s"
177
+ .formatted (getItemResponse .item ().get ("PK" ).s (), testUnicorn ));
178
+ Assertions .assertEquals (getItemResponse .item ().get ("LOCATION" ).s (), testLocation ,
179
+ "Table LOCATION is not set to the Unicorn Location: %s expected %s"
180
+ .formatted (getItemResponse .item ().get ("LOCATION" ).s (), testLocation ));
181
+ }
182
+
183
+ }
0 commit comments