• 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.services.iotdataplane;
17 
18 import static org.hamcrest.Matchers.greaterThan;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertThat;
21 
22 import com.fasterxml.jackson.databind.JsonNode;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import java.io.IOException;
25 import java.net.URI;
26 import java.nio.ByteBuffer;
27 import org.junit.Before;
28 import org.junit.Test;
29 import software.amazon.awssdk.core.SdkBytes;
30 import software.amazon.awssdk.regions.Region;
31 import software.amazon.awssdk.services.iot.IotClient;
32 import software.amazon.awssdk.services.iotdataplane.model.DeleteThingShadowRequest;
33 import software.amazon.awssdk.services.iotdataplane.model.DeleteThingShadowResponse;
34 import software.amazon.awssdk.services.iotdataplane.model.GetThingShadowRequest;
35 import software.amazon.awssdk.services.iotdataplane.model.GetThingShadowResponse;
36 import software.amazon.awssdk.services.iotdataplane.model.InvalidRequestException;
37 import software.amazon.awssdk.services.iotdataplane.model.PublishRequest;
38 import software.amazon.awssdk.services.iotdataplane.model.ResourceNotFoundException;
39 import software.amazon.awssdk.services.iotdataplane.model.UpdateThingShadowRequest;
40 import software.amazon.awssdk.services.iotdataplane.model.UpdateThingShadowResponse;
41 import software.amazon.awssdk.testutils.service.AwsIntegrationTestBase;
42 import software.amazon.awssdk.utils.BinaryUtils;
43 
44 public class ServiceIntegrationTest extends AwsIntegrationTestBase {
45 
46     private static final String STATE_FIELD_NAME = "state";
47     private static final String THING_NAME = "foo";
48     private static final String INVALID_THING_NAME = "INVALID_THING_NAME";
49 
50     private IotDataPlaneClient iot;
51 
getPayloadAsJsonNode(ByteBuffer payload)52     private static JsonNode getPayloadAsJsonNode(ByteBuffer payload) throws IOException {
53         return new ObjectMapper().readTree(BinaryUtils.toStream(payload));
54     }
55 
assertPayloadNonEmpty(SdkBytes payload)56     private static void assertPayloadNonEmpty(SdkBytes payload) {
57         assertThat(payload.asByteBuffer().capacity(), greaterThan(0));
58     }
59 
60     /**
61      * Asserts that the returned payload has the correct state in the JSON document. It should be
62      * exactly what we sent it plus some additional metadata
63      *
64      * @param originalPayload
65      *            ByteBuffer we sent to the service containing just the state
66      * @param returnedPayload
67      *            ByteBuffer returned by the service containing the state (which should be the same
68      *            as what we sent) plus additional metadata in the JSON document
69      */
assertPayloadIsValid(SdkBytes originalPayload, SdkBytes returnedPayload)70     private static void assertPayloadIsValid(SdkBytes originalPayload, SdkBytes returnedPayload) throws Exception {
71         JsonNode originalJson = getPayloadAsJsonNode(originalPayload.asByteBuffer());
72         JsonNode returnedJson = getPayloadAsJsonNode(returnedPayload.asByteBuffer());
73         assertEquals(originalJson.get(STATE_FIELD_NAME), returnedJson.get(STATE_FIELD_NAME));
74     }
75 
76     @Before
setup()77     public void setup() throws Exception {
78         IotClient client = IotClient.builder().credentialsProvider(CREDENTIALS_PROVIDER_CHAIN).region(Region.US_EAST_1).build();
79         String endpoint = client.describeEndpoint(r -> r.endpointType("iot:Data-ATS")).endpointAddress();
80         iot = IotDataPlaneClient.builder()
81                                 .credentialsProvider(CREDENTIALS_PROVIDER_CHAIN)
82                                 .endpointOverride(URI.create("https://" + endpoint))
83                                 .region(Region.US_EAST_1)
84                                 .build();
85     }
86 
87     @Test
publish_ValidTopicAndNonEmptyPayload_DoesNotThrowException()88     public void publish_ValidTopicAndNonEmptyPayload_DoesNotThrowException() {
89         iot.publish(PublishRequest.builder().topic(THING_NAME).payload(SdkBytes.fromByteArray(new byte[] {1, 2, 3, 4})).build());
90     }
91 
92     @Test
publish_WithValidTopicAndEmptyPayload_DoesNotThrowException()93     public void publish_WithValidTopicAndEmptyPayload_DoesNotThrowException() {
94         iot.publish(PublishRequest.builder().topic(THING_NAME).payload(null).build());
95     }
96 
97     @Test(expected = InvalidRequestException.class)
updateThingShadow_NullPayload_ThrowsServiceException()98     public void updateThingShadow_NullPayload_ThrowsServiceException() throws Exception {
99         UpdateThingShadowRequest request = UpdateThingShadowRequest.builder().thingName(THING_NAME).payload(null).build();
100         iot.updateThingShadow(request);
101     }
102 
103     @Test(expected = InvalidRequestException.class)
updateThingShadow_MalformedPayload_ThrowsServiceException()104     public void updateThingShadow_MalformedPayload_ThrowsServiceException() throws Exception {
105         SdkBytes payload = SdkBytes.fromUtf8String("{ }");
106         UpdateThingShadowRequest request = UpdateThingShadowRequest.builder().thingName(THING_NAME).payload(payload).build();
107         iot.updateThingShadow(request);
108     }
109 
110     @Test(expected = ResourceNotFoundException.class)
getThingShadow_InvalidThingName_ThrowsException()111     public void getThingShadow_InvalidThingName_ThrowsException() {
112         iot.getThingShadow(GetThingShadowRequest.builder().thingName(INVALID_THING_NAME).build());
113     }
114 
115     @Test(expected = ResourceNotFoundException.class)
deleteThingShadow_InvalidThing_ThrowsException()116     public void deleteThingShadow_InvalidThing_ThrowsException() {
117         DeleteThingShadowResponse result = iot
118                 .deleteThingShadow(DeleteThingShadowRequest.builder().thingName(INVALID_THING_NAME).build());
119         assertPayloadNonEmpty(result.payload());
120     }
121 
122     @Test
UpdateReadDeleteThing()123     public void UpdateReadDeleteThing() throws Exception {
124         updateThingShadow_ValidRequest_ReturnsValidResponse(THING_NAME);
125         getThingShadow_ValidThing_ReturnsThingData(THING_NAME);
126         deleteThingShadow_ValidThing_DeletesSuccessfully(THING_NAME);
127     }
128 
updateThingShadow_ValidRequest_ReturnsValidResponse(String thingName)129     private void updateThingShadow_ValidRequest_ReturnsValidResponse(String thingName) throws Exception {
130         SdkBytes originalPayload = SdkBytes.fromUtf8String("{ \"state\": {\"reported\":{ \"r\": {}}}}");
131         UpdateThingShadowRequest request = UpdateThingShadowRequest.builder().thingName(thingName).payload(originalPayload).build();
132         UpdateThingShadowResponse result = iot.updateThingShadow(request);
133 
134         // Comes back with some extra metadata so we assert it's bigger than the original
135         assertThat(result.payload().asByteBuffer().capacity(), greaterThan(originalPayload.asByteBuffer().capacity()));
136         assertPayloadIsValid(originalPayload, result.payload());
137     }
138 
getThingShadow_ValidThing_ReturnsThingData(String thingName)139     private void getThingShadow_ValidThing_ReturnsThingData(String thingName) {
140         GetThingShadowRequest request = GetThingShadowRequest.builder().thingName(thingName).build();
141         GetThingShadowResponse result = iot.getThingShadow(request);
142         assertPayloadNonEmpty(result.payload());
143     }
144 
deleteThingShadow_ValidThing_DeletesSuccessfully(String thingName)145     private void deleteThingShadow_ValidThing_DeletesSuccessfully(String thingName) {
146         DeleteThingShadowResponse result = iot.deleteThingShadow(DeleteThingShadowRequest.builder().thingName(thingName).build());
147         assertPayloadNonEmpty(result.payload());
148     }
149 
150 }
151