dusterio / laravel-plain-sqs

Custom SQS connector for Laravel (or Lumen) that supports third-party, plain JSON messages
MIT License
131 stars 92 forks source link

Handling XML data #6

Open TwassistantKeith opened 8 years ago

TwassistantKeith commented 8 years ago

Hey there, I am trying to handle XML data in the body of a payload from the queue:

array (
  'MessageId' => 'XXX',
  'ReceiptHandle' => 'XXX',
  'MD5OfBody' => 'XXX',
  'Body' => '<Notification><NotificationMetaData><NotificationType>Test</NotificationType><PayloadVersion>1.0</PayloadVersion><UniqueId>XXX</UniqueId><PublishTime>2016-08-17T13:42:02Z</PublishTime></NotificationMetaData><NotificationPayload><TestNotification /></NotificationPayload></Notification>',
  'Attributes' => 
  array (
    'ApproximateReceiveCount' => '10',
  ),
)  

I believe this could be handled by adding XML detection to your modifyPayload function, something along these lines:

private function modifyPayload($payload, $class)
    {
        if (!is_array($payload)) $payload = json_decode($payload, true);

        function is_valid_xml ( $xml ) {
            libxml_use_internal_errors( true );

            $doc = new \DOMDocument('1.0', 'utf-8');

            $doc->loadXML( $xml );

            $errors = libxml_get_errors();

            return empty( $errors );
        }

        if(is_valid_xml($payload['Body'])) {
            $data = json_decode(json_encode(simplexml_load_string($payload['Body'], "SimpleXMLElement", LIBXML_NOCDATA)),true);
        } else {
            $data = json_decode($payload['Body']);
        }

        $body = [
          'job' => $class . '@handle',
          'data' => $data,
        ];

        $payload['Body'] = json_encode($body);

        return $payload;
    }

I just hacked this together so I'm sure there's a better way, but it appears to work properly. What do you think?

TwassistantKeith commented 8 years ago

Actually, I get this error now:

[2016-08-17 10:39:36] production.ERROR: exception 'ErrorException' with message 'Argument 1 passed to Dusterio\PlainSqs\Integrations\LaravelServiceProvider::Dusterio\PlainSqs\Integrations\{closure}() must be an instance of Illuminate\Queue\Events\JobProcessed, string given' in /home/x/vendor/dusterio/laravel-plain-sqs/src/Integrations/LaravelServiceProvider.php:27

I believe this is a problem due to the different between Laravel 5.1 and 5.2. I am using 5.1 and so the Queue::after function looks different:

Queue::after(function ($connection, $job, $data) {

vs 5.2:

Queue::after(function (JobProcessed $event) {

I've changed my function to:

Queue::after(function ($connection, $job, $data) {
      $job->delete();
});

And everything is now processing correctly.

dusterio commented 8 years ago

Thanks for finding and pointing this out! Since 5.3 is coming out soon as well, I will need to add some version checks in the Laravel/Lumen service provider it seems – to support different versions. I will include this 5.1 fix as well