2121import software .amazon .awssdk .crt .mqtt5 .OnConnectionSuccessReturn ;
2222import software .amazon .awssdk .crt .mqtt5 .packets .ConnectPacket ;
2323import software .amazon .awssdk .crt .mqtt5 .packets .PublishPacket ;
24+ import software .amazon .awssdk .crt .mqtt5 .packets .UserProperty ;
2425
2526import java .nio .charset .StandardCharsets ;
27+ import java .util .ArrayList ;
2628import java .util .UUID ;
2729import java .util .concurrent .CompletableFuture ;
2830import java .util .concurrent .ExecutionException ;
@@ -699,14 +701,21 @@ public void ShadowUpdatedStreamingOperationOpenCloseMqtt311() {
699701 doStreamingOperationOpenClosedTest (MqttVersion .Mqtt311 );
700702 }
701703
702- void doStreamingOperationIncomingPublishTest (MqttVersion version ) {
704+ public interface StreamOperationPublishHelper {
705+ String getTopic ();
706+ PublishPacket createMqtt5PublishPacket ();
707+ MqttMessage createMqtt3Message ();
708+ void assertPublishEvent (IncomingPublishEvent event );
709+ }
710+
711+ void doStreamingOperationIncomingPublishTest (MqttVersion version , StreamOperationPublishHelper helper ) {
703712 this .context = new TestContext (version , null );
704713 CompletableFuture <Boolean > subscribed = new CompletableFuture <>();
705714 CompletableFuture <IncomingPublishEvent > publishEvent = new CompletableFuture <>();
706715
707- String fakeShadowTopic = "not/a/shadow/topic/" + ( UUID . randomUUID ()). toString ();
716+ String topic = helper . getTopic ();
708717 StreamingOperationOptions streamingOptions = StreamingOperationOptions .builder ()
709- .withTopic (fakeShadowTopic )
718+ .withTopic (topic )
710719 .withSubscriptionStatusEventCallback ((event ) -> {
711720 if (event .getType () == SubscriptionStatusEventType .SUBSCRIPTION_ESTABLISHED ) {
712721 subscribed .complete (true );
@@ -723,48 +732,135 @@ void doStreamingOperationIncomingPublishTest(MqttVersion version) {
723732 try {
724733 subscribed .get ();
725734 } catch (Exception ex ) {
726- Assert .assertTrue ( false );
735+ Assert .fail ( ex . getMessage () );
727736 }
728737
729- String originalPayloadAsString = "IncomingPublishTest" ;
730- byte [] originalPayload = originalPayloadAsString .getBytes (StandardCharsets .UTF_8 );
731-
732738 if (version == MqttVersion .Mqtt5 ) {
733- PublishPacket publishPacket = new PublishPacket .PublishPacketBuilder ()
734- .withPayload (originalPayload )
735- .withTopic (fakeShadowTopic )
736- .withQOS (QOS .AT_LEAST_ONCE )
737- .build ();
739+ PublishPacket publishPacket = helper .createMqtt5PublishPacket ();
738740 this .context .mqtt5Client .publish (publishPacket );
739741 } else {
740- this .context .mqtt311Client .publish (new MqttMessage ( fakeShadowTopic , originalPayload , QualityOfService . AT_LEAST_ONCE ));
742+ this .context .mqtt311Client .publish (helper . createMqtt3Message ( ));
741743 }
742744
743745 try {
744746 IncomingPublishEvent event = publishEvent .get ();
747+ helper .assertPublishEvent (event );
748+ } catch (Exception | Error ex ) {
749+ Assert .fail (ex .getMessage ());
750+ } finally {
751+ stream .close ();
752+ }
753+ }
754+
755+ class StreamOperationPublishHelper_RequiredFieldsOnly implements StreamOperationPublishHelper {
756+ private final String payload = "IncomingPublishTest" ;
757+ private final String topic = "not/a/shadow/topic/" + (UUID .randomUUID ()).toString ();
758+
759+ @ Override
760+ public String getTopic () {
761+ return topic ;
762+ }
763+
764+ @ Override
765+ public PublishPacket createMqtt5PublishPacket () {
766+ byte [] payloadBytes = payload .getBytes (StandardCharsets .UTF_8 );
767+ return new PublishPacket .PublishPacketBuilder ()
768+ .withPayload (payloadBytes )
769+ .withTopic (topic )
770+ .withQOS (QOS .AT_LEAST_ONCE )
771+ .build ();
772+ }
773+
774+ @ Override
775+ public MqttMessage createMqtt3Message () {
776+ byte [] payloadBytes = payload .getBytes (StandardCharsets .UTF_8 );
777+ return new MqttMessage (topic , payloadBytes , QualityOfService .AT_LEAST_ONCE );
778+ }
779+
780+ @ Override
781+ public void assertPublishEvent (IncomingPublishEvent event ) {
745782 Assert .assertNotNull (event );
746- String payloadAsString = new String (event .getPayload (), StandardCharsets .UTF_8 );
747- Assert .assertEquals (originalPayloadAsString , payloadAsString );
748- Assert .assertEquals (fakeShadowTopic , event .getTopic ());
749- } catch (Exception ex ) {
750- Assert .assertTrue (false );
783+ String eventPayload = new String (event .getPayload (), StandardCharsets .UTF_8 );
784+ Assert .assertEquals ("payload" , payload , eventPayload );
785+ Assert .assertEquals ("topic" , topic , event .getTopic ());
786+
787+ Assert .assertNull ("content-type" , event .getContentType ());
788+ Assert .assertNull ("user-properties" , event .getUserProperties ());
789+ Assert .assertNull ("message-expiry-interval-seconds" , event .getMessageExpiryIntervalSeconds ());
751790 }
791+ }
752792
753- stream .close ();
793+ class StreamOperationPublishHelper_AllFields implements StreamOperationPublishHelper {
794+ private final String payload = "IncomingPublishTest" ;
795+ private final String topic = "not/a/shadow/topic/" + (UUID .randomUUID ()).toString ();
796+ private final String contentType = "application/json" ;
797+ private ArrayList <UserProperty > userProperties ;
798+
799+ @ Override
800+ public String getTopic () {
801+ return topic ;
802+ }
803+
804+ @ Override
805+ public PublishPacket createMqtt5PublishPacket () {
806+ byte [] payloadBytes = payload .getBytes (StandardCharsets .UTF_8 );
807+
808+ userProperties = new ArrayList <UserProperty >();
809+ userProperties .add (new UserProperty ("Hello" , "World" ));
810+
811+ return new PublishPacket .PublishPacketBuilder ()
812+ .withPayload (payloadBytes )
813+ .withTopic (topic )
814+ .withQOS (QOS .AT_LEAST_ONCE )
815+ .withContentType (contentType )
816+ .withUserProperties (userProperties )
817+ .withMessageExpiryIntervalSeconds (100L )
818+ .build ();
819+ }
820+
821+ @ Override
822+ public MqttMessage createMqtt3Message () {
823+ byte [] payloadBytes = payload .getBytes (StandardCharsets .UTF_8 );
824+ return new MqttMessage (topic , payloadBytes , QualityOfService .AT_LEAST_ONCE );
825+ }
826+
827+ @ Override
828+ public void assertPublishEvent (IncomingPublishEvent event ) {
829+ Assert .assertNotNull (event );
830+ String eventPayload = new String (event .getPayload (), StandardCharsets .UTF_8 );
831+ Assert .assertEquals ("payload" , payload , eventPayload );
832+ Assert .assertEquals ("topic" , topic , event .getTopic ());
833+ Assert .assertEquals ("content-type" , contentType , event .getContentType ());
834+ Assert .assertEquals ("user-properties size" , userProperties .size (), event .getUserProperties ().size ());
835+ for (int i = 0 ; i < userProperties .size (); i ++) {
836+ Assert .assertEquals ("user-property " + i + " key" , userProperties .get (i ).key , event .getUserProperties ().get (i ).key );
837+ Assert .assertEquals ("user-property " + i + " value" , userProperties .get (i ).value , event .getUserProperties ().get (i ).value );
838+ }
839+ Assert .assertNotNull ("message-expiry-interval-seconds should not be null" , event .getMessageExpiryIntervalSeconds ());
840+ // We can't check for the exact value here as it'll be decremented by the server part.
841+ Assert .assertTrue ("message-expiry-interval-seconds should be a positive number" , event .getMessageExpiryIntervalSeconds () > 0 );
842+ }
843+ }
844+
845+ @ Test
846+ public void StreamingOperationIncomingPublishMqtt5_RequiredFieldsOnly () {
847+ skipIfNetworkUnavailable ();
848+
849+ doStreamingOperationIncomingPublishTest (MqttVersion .Mqtt5 , new StreamOperationPublishHelper_RequiredFieldsOnly ());
754850 }
755851
756852 @ Test
757- public void StreamingOperationIncomingPublishMqtt5 () {
853+ public void StreamingOperationIncomingPublishMqtt5_AllFields () {
758854 skipIfNetworkUnavailable ();
759855
760- doStreamingOperationIncomingPublishTest (MqttVersion .Mqtt5 );
856+ doStreamingOperationIncomingPublishTest (MqttVersion .Mqtt5 , new StreamOperationPublishHelper_AllFields () );
761857 }
762858
763859 @ Test
764860 public void StreamingOperationIncomingPublishMqtt311 () {
765861 skipIfNetworkUnavailable ();
766862
767- doStreamingOperationIncomingPublishTest (MqttVersion .Mqtt311 );
863+ doStreamingOperationIncomingPublishTest (MqttVersion .Mqtt311 , new StreamOperationPublishHelper_RequiredFieldsOnly () );
768864 }
769865
770866 void doStreamingOperationReopenFailureTest (MqttVersion version ) {
0 commit comments