Browse Source

Resolves Islandora-CLAW/CLAW#468 (#31)

* Broadcaster rules action.

* Re-exporting rules

* Tests

* Updating travis environment for testing with activemq
pull/756/head
dannylamb 8 years ago committed by Jared Whiklo
parent
commit
8278fa36ba
  1. 1
      .gitignore
  2. 13
      .scripts/travis_setup.sh
  3. 10
      .travis.yml
  4. 3
      composer.json
  5. 7
      config/install/core.entity_form_display.fedora_resource.rdf_source.default.yml
  6. 10
      config/install/core.entity_view_mode.fedora_resource.teaser.yml
  7. 18
      config/install/field.field.fedora_resource.rdf_source.field_ldp_contains.yml
  8. 10
      config/install/field.storage.fedora_resource.field_ldp_contains.yml
  9. 10
      config/install/islandora.fedora_resource_type.non_rdf_source.yml
  10. 8
      config/install/islandora.fedora_resource_type.rdf_source.yml
  11. 8
      config/install/islandora.settings.yml
  12. 11
      config/install/rdf.mapping.fedora_resource_type.non_rdf_source.yml
  13. 11
      config/install/rdf.mapping.fedora_resource_type.rdf_source.yml
  14. 15
      config/install/rules.reaction.broadcast_create_event.yml
  15. 15
      config/install/rules.reaction.broadcast_delete_event.yml
  16. 15
      config/install/rules.reaction.broadcast_update_event.yml
  17. 7
      config/install/views.view.fedora_entities_reference.yml
  18. 14
      config/schema/islandora.schema.yml
  19. 4
      islandora.services.yml
  20. 2
      src/EventGenerator/EventGeneratorActionBase.php
  21. 51
      src/Form/IslandoraSettingsForm.php
  22. 125
      src/Plugin/RulesAction/Broadcaster.php
  23. 33
      src/StompFactory.php
  24. 127
      tests/src/Kernel/BroadcasterTest.php
  25. 8
      tests/src/Kernel/EventGeneratorTestBase.php
  26. 1
      tests/src/Kernel/IslandoraKernelTestBase.php
  27. 15
      tests/src/Kernel/VectorClockTest.php

1
.gitignore vendored

@ -0,0 +1 @@
vendor

13
.scripts/travis_setup.sh

@ -65,11 +65,16 @@ drush en -y jsonld
drush en -y islandora drush en -y islandora
drush -y dl bootstrap
drush -y en bootstrap
drush -y config-set system.theme default bootstrap
drush cr drush cr
# ACTIVEMQ
cd $HOME
wget "http://archive.apache.org/dist/activemq/5.14.3/apache-activemq-5.14.3-bin.tar.gz"
tar -xzf apache-activemq-5.14.3-bin.tar.gz
sudo sed -i 's|ACTIVEMQ_USER="activemq"|ACTIVEMQ_USER="travis"|' /etc/default/activemq
apache-activemq-5.14.3/bin/activemq start
# The shebang in this file is a bogeyman that is haunting the web test cases. # The shebang in this file is a bogeyman that is haunting the web test cases.
rm /home/travis/.phpenv/rbenv.d/exec/hhvm-switcher.bash rm /home/travis/.phpenv/rbenv.d/exec/hhvm-switcher.bash
sleep 20 sleep 20

10
.travis.yml

@ -15,27 +15,21 @@ branches:
only: only:
- /^8.x/ - /^8.x/
addons:
apt:
packages:
- activemq
before_install: before_install:
- export ISLANDORA_DIR=$TRAVIS_BUILD_DIR - export ISLANDORA_DIR=$TRAVIS_BUILD_DIR
install: install:
- printf "no" | pecl install stomp
- $TRAVIS_BUILD_DIR/.scripts/travis_setup.sh - $TRAVIS_BUILD_DIR/.scripts/travis_setup.sh
- composer install - composer install
- php vendor/bin/phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer - php vendor/bin/phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer
- cd $HOME/drupal; composer require stomp-php/stomp-php:4.*
script: script:
- $ISLANDORA_DIR/.scripts/line_endings.sh . - $ISLANDORA_DIR/.scripts/line_endings.sh .
- cd $HOME/drupal/modules/islandora - cd $HOME/drupal/modules/islandora
- php vendor/bin/phpcs --standard=Drupal --extensions=module/php,php/php src tests - php vendor/bin/phpcs --standard=Drupal --extensions=module/php,php/php src tests
- php vendor/bin/phpcpd --names *.module,*.inc,*.test,*.php --exclude=vendor . - php vendor/bin/phpcpd --names *.module,*.inc,*.test,*.php --exclude=vendor .
- cd $HOME/drupal; php core/scripts/run-tests.sh --php `which php` islandora - cd $HOME/drupal; php core/scripts/run-tests.sh --verbose --php `which php` islandora
notifications: notifications:
irc: irc:

3
composer.json

@ -18,7 +18,8 @@
"drupal/inline_entity_form": "^1.0@beta", "drupal/inline_entity_form": "^1.0@beta",
"drupal/rules": "^3.0@alpha", "drupal/rules": "^3.0@alpha",
"drupal/search_api": "^1.0@beta", "drupal/search_api": "^1.0@beta",
"islandora/claw-jsonld": "dev-8.x-1.x" "islandora/claw-jsonld": "dev-8.x-1.x",
"stomp-php/stomp-php": "4.*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8", "phpunit/phpunit": "^4.8",

7
config/install/core.entity_form_display.fedora_resource.rdf_source.default.yml

@ -1,9 +1,15 @@
uuid: ab918e50-21f9-42b3-b490-42fee6177162
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
enforced:
module:
- islandora
config: config:
- field.field.fedora_resource.rdf_source.field_ldp_contains - field.field.fedora_resource.rdf_source.field_ldp_contains
- islandora.fedora_resource_type.rdf_source - islandora.fedora_resource_type.rdf_source
_core:
default_config_hash: jDTpzFJD_PoXr0W008d5FvJV65oGCh89KANvALcy_O4
id: fedora_resource.rdf_source.default id: fedora_resource.rdf_source.default
targetEntityType: fedora_resource targetEntityType: fedora_resource
bundle: rdf_source bundle: rdf_source
@ -58,3 +64,4 @@ content:
placeholder: '' placeholder: ''
third_party_settings: { } third_party_settings: { }
hidden: { } hidden: { }

10
config/install/core.entity_view_mode.fedora_resource.teaser.yml

@ -2,9 +2,13 @@ uuid: 0efc20d3-0bd6-4606-842f-b87548de1924
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
module: enforced:
- islandora module:
- islandora
_core:
default_config_hash: PnOwgzHIcT0m2y9dN2B5D7og29JXDCm4dCqb1pKUWek
id: fedora_resource.teaser id: fedora_resource.teaser
label: Teaser label: Teaser
targetEntityType: fedora_resource targetEntityType: fedora_resource
cache: true cache: true

18
config/install/field.field.fedora_resource.rdf_source.field_ldp_contains.yml

@ -1,25 +1,31 @@
uuid: 29ea11d1-4267-4bc1-bdc0-550e58833c0b
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
enforced:
module:
- islandora
config: config:
- field.storage.fedora_resource.rdf_source.field_ldp_contains - field.storage.fedora_resource.field_ldp_contains
- islandora.fedora_resource_type.non_rdf_source
- islandora.fedora_resource_type.rdf_source - islandora.fedora_resource_type.rdf_source
_core:
default_config_hash: y-E4uXZywn0AAVWULpj46kKRevLvEFQup5pLJ2J9jsk
id: fedora_resource.rdf_source.field_ldp_contains id: fedora_resource.rdf_source.field_ldp_contains
field_name: field_ldp_contains field_name: field_ldp_contains
entity_type: fedora_resource entity_type: fedora_resource
bundle: rdf_source bundle: rdf_source
label: ldp:contains label: 'ldp:contains'
description: 'Contains Fedora Resource.' description: 'Contains Fedora Resource.'
required: false required: false
translatable: false translatable: false
default_value: { } default_value: { }
default_value_callback: '' default_value_callback: ''
settings: settings:
handler: 'default:fedora_resource' handler: views
handler_settings: handler_settings:
view: view:
view_name: bundles_of_fedora view_name: fedora_entities_reference
display_name: entity_reference_1 display_name: entity_reference_1
arguments: { } arguments: { }
field_type: entity_reference field_type: entity_reference

10
config/install/field.storage.fedora_resource.rdf_source.field_ldp_contains.yml → config/install/field.storage.fedora_resource.field_ldp_contains.yml

@ -1,8 +1,12 @@
uuid: d40c0b76-1a6d-4dd2-8f0b-2945e30d2832
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
module: enforced:
- islandora module:
- islandora
_core:
default_config_hash: jkwDP8hekY3eWzIrEN4yinGftfXZlArUaz7PsiU6BcM
id: fedora_resource.field_ldp_contains id: fedora_resource.field_ldp_contains
field_name: field_ldp_contains field_name: field_ldp_contains
entity_type: fedora_resource entity_type: fedora_resource
@ -15,4 +19,4 @@ cardinality: -1
translatable: true translatable: true
indexes: { } indexes: { }
persist_with_no_fields: false persist_with_no_fields: false
custom_storage: false custom_storage: false

10
config/install/islandora.fedora_resource_type.non_rdf_source.yml

@ -1,3 +1,11 @@
uuid: 68d5a1cb-e493-4e9d-adad-21229a41ac68
langcode: en langcode: en
status: true
dependencies:
enforced:
module:
- islandora
_core:
default_config_hash: KgkkNCMXV1urHhxyo7wuwYPWaEAnyLAXvwrRnZWDmtw
id: non_rdf_source id: non_rdf_source
label: 'Non RDF Source' label: 'Non RDF Source'

8
config/install/islandora.fedora_resource_type.rdf_source.yml

@ -1,3 +1,11 @@
uuid: af1cb3d8-2c1f-4ca1-a1c2-b1173704807f
langcode: en langcode: en
status: true
dependencies:
enforced:
module:
- islandora
_core:
default_config_hash: 61Pa7qgwWd8HBTCgoxF3RxTsvCBcmHNhfg5k8FPqEpQ
id: rdf_source id: rdf_source
label: 'RDF Source' label: 'RDF Source'

8
config/install/islandora.settings.yml

@ -1,4 +1,6 @@
broker_url: 'http://localhost:61613' broker_url: 'tcp://localhost:61613'
triplestore_index_queue: '/islandora/triplestore/index'
fedora_rest_endpoint: 'http://localhost:8080/fcrepo/rest' fedora_rest_endpoint: 'http://localhost:8080/fcrepo/rest'
fedora_indexing_queue: 'islandora/indexing/fedora' _core:
default_config_hash: nDZDR2rrpXXQ-D_7BYrdDFAXYOsB5hgH6vCAMV5I3w8
broadcast_queue: islandora-connector-broadcast

11
config/install/rdf.mapping.fedora_resource_type.non_rdf_source.yml

@ -1,11 +1,15 @@
uuid: 58d7388f-c602-4a03-9c63-aed54b8d2b7e
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
enforced:
module:
- islandora
config: config:
- islandora.fedora_resource_type.non_rdf_source - islandora.fedora_resource_type.non_rdf_source
module: _core:
- islandora default_config_hash: HoZxZHzZDjK45CfvxQaCJCn6eqr9Ve2FxcqtLlYf-RI
id: fedora_resource_type.non_rdf_source id: fedora_resource.non_rdf_source
targetEntityType: fedora_resource targetEntityType: fedora_resource
bundle: non_rdf_source bundle: non_rdf_source
types: types:
@ -41,3 +45,4 @@ fieldMappings:
properties: properties:
- 'ldp:contains' - 'ldp:contains'
mapping_type: rel mapping_type: rel

11
config/install/rdf.mapping.fedora_resource_type.rdf_source.yml

@ -1,11 +1,15 @@
uuid: 77e9e71f-f67f-438f-80eb-bb5fa931a5ec
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
enforced:
module:
- islandora
config: config:
- islandora.fedora_resource_type.rdf_source - islandora.fedora_resource_type.rdf_source
module: _core:
- islandora default_config_hash: SXB_6Qvx5WtM-zrkkgEOjok1YGMeyjn9Zsa7ymV2MbM
id: fedora_resource_type.rdf_source id: fedora_resource.rdf_source
targetEntityType: fedora_resource targetEntityType: fedora_resource
bundle: rdf_source bundle: rdf_source
types: types:
@ -45,3 +49,4 @@ fieldMappings:
properties: properties:
- 'ldp:contains' - 'ldp:contains'
mapping_type: rel mapping_type: rel

15
config/install/rules.reaction.broadcast_create_event.yml

@ -8,6 +8,8 @@ dependencies:
enforced: enforced:
module: module:
- islandora - islandora
_core:
default_config_hash: EKVRKXObBdrm-lGcG3RPpF8sg0tZSZbZx00lkzm42_E
id: broadcast_create_event id: broadcast_create_event
label: 'Broadcast Create Event' label: 'Broadcast Create Event'
events: events:
@ -40,17 +42,16 @@ expression:
action_id: islandora_create_event_generator action_id: islandora_create_event_generator
- -
id: rules_action id: rules_action
uuid: bbcd7317-2879-4961-a79d-5827fab4e194 uuid: 2afa7216-91bb-49a3-a567-e504ba8f95e1
context_values: context_values:
type: info recipients:
repeat: false - "activemq:queue:islandora-indexing-fcrepo\r"
- 'activemq:queue:islandora-indexing-triplestore'
context_mapping: context_mapping:
message: event_message message: event_message
context_processors: context_processors:
type: recipients:
rules_tokens: { }
repeat:
rules_tokens: { } rules_tokens: { }
provides_mapping: { } provides_mapping: { }
action_id: rules_system_message action_id: islandora_broadcast

15
config/install/rules.reaction.broadcast_delete_event.yml

@ -8,6 +8,8 @@ dependencies:
enforced: enforced:
module: module:
- islandora - islandora
_core:
default_config_hash: 79mBUbR_0wDo3oT4vWjuFgGPic_hghVkQ0yiYMuxLns
id: broadcast_delete_event id: broadcast_delete_event
label: 'Broadcast Delete Event' label: 'Broadcast Delete Event'
events: events:
@ -40,17 +42,16 @@ expression:
action_id: islandora_delete_event_generator action_id: islandora_delete_event_generator
- -
id: rules_action id: rules_action
uuid: bacf7f09-1d54-46f2-a4b9-e345992a604d uuid: 53942d65-7567-4b6b-9b43-4d67079651f6
context_values: context_values:
type: info recipients:
repeat: false - "activemq:queue:islandora-indexing-fcrepo\r"
- 'activemq:queue:islandora-indexing-triplestore'
context_mapping: context_mapping:
message: event_message message: event_message
context_processors: context_processors:
type: recipients:
rules_tokens: { }
repeat:
rules_tokens: { } rules_tokens: { }
provides_mapping: { } provides_mapping: { }
action_id: rules_system_message action_id: islandora_broadcast

15
config/install/rules.reaction.broadcast_update_event.yml

@ -8,6 +8,8 @@ dependencies:
enforced: enforced:
module: module:
- islandora - islandora
_core:
default_config_hash: XX87LaQzcIVbzZTzUR4HBgeZKCzKOMJzVCTJYgmg47k
id: broadcast_update_event id: broadcast_update_event
label: 'Broadcast Update Event' label: 'Broadcast Update Event'
events: events:
@ -40,17 +42,16 @@ expression:
action_id: islandora_update_event_generator action_id: islandora_update_event_generator
- -
id: rules_action id: rules_action
uuid: f77c64ef-c737-4143-89b4-e1b6599232b5 uuid: 40aa4a03-ad36-45bf-9584-ede3b9b3e5c9
context_values: context_values:
type: info recipients:
repeat: false - "activemq:queue:islandora-indexing-fcrepo\r"
- 'activemq:queue:islandora-indexing-triplestore'
context_mapping: context_mapping:
message: event_message message: event_message
context_processors: context_processors:
type: recipients:
rules_tokens: { }
repeat:
rules_tokens: { } rules_tokens: { }
provides_mapping: { } provides_mapping: { }
action_id: rules_system_message action_id: islandora_broadcast

7
config/install/views.view.fedora_entities_reference.yml

@ -1,9 +1,15 @@
uuid: ec053572-be63-4209-a49a-16c09c9a3e73
langcode: en langcode: en
status: true status: true
dependencies: dependencies:
module: module:
- islandora - islandora
- user - user
enforced:
module:
- islandora
_core:
default_config_hash: UU-ZHb4xUJIu4JMAIGXvy0c93Y_xq4CPibq1qrgp098
id: fedora_entities_reference id: fedora_entities_reference
label: 'Fedora Entities Reference' label: 'Fedora Entities Reference'
module: views module: views
@ -161,3 +167,4 @@ display:
- 'languages:language_interface' - 'languages:language_interface'
- user.permissions - user.permissions
tags: { } tags: { }

14
config/schema/islandora.schema.yml

@ -0,0 +1,14 @@
islandora.settings:
type: config_object
label: 'Islandora Core Settings'
mapping:
broker_url:
type: string
label: 'Url to connect to message broker'
fedora_rest_endpoint:
type: string
label: 'Url to Fedora instance'
broadcast_queue:
type: string
label: 'Queue that handles distributing messages amongst multiple recipients'

4
islandora.services.yml

@ -8,3 +8,7 @@ services:
arguments: ['@entity.manager'] arguments: ['@entity.manager']
islandora.eventgenerator: islandora.eventgenerator:
class: Drupal\islandora\EventGenerator\EventGenerator class: Drupal\islandora\EventGenerator\EventGenerator
islandora.stomp:
class: Stomp\StatefulStomp
factory: ['Drupal\islandora\StompFactory', create]
arguments: ['@config.factory']

2
src/EventGenerator/EventGeneratorActionBase.php

@ -19,7 +19,7 @@ abstract class EventGeneratorActionBase extends RulesActionBase implements Conta
protected $eventGenerator; protected $eventGenerator;
/** /**
* Constructs a MessageBroadcaster action. * Constructs a EventGeneratorActionBase.
* *
* @param array $configuration * @param array $configuration
* A configuration array containing information about the plugin instance. * A configuration array containing information about the plugin instance.

51
src/Form/IslandoraSettingsForm.php

@ -4,6 +4,9 @@ namespace Drupal\islandora\Form;
use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Stomp\Client;
use Stomp\Exception\StompException;
use Stomp\StatefulStomp;
/** /**
* Config form for Islandora settings. * Config form for Islandora settings.
@ -12,9 +15,8 @@ class IslandoraSettingsForm extends ConfigFormBase {
const CONFIG_NAME = 'islandora.settings'; const CONFIG_NAME = 'islandora.settings';
const BROKER_URL = 'broker_url'; const BROKER_URL = 'broker_url';
const TRIPLESTORE_INDEX_QUEUE = 'triplestore_index_queue';
const FEDORA_REST_ENDPOINT = 'fedora_rest_endpoint'; const FEDORA_REST_ENDPOINT = 'fedora_rest_endpoint';
const FEDORA_INDEXING_QUEUE = 'fedora_indexing_queue'; const BROADCAST_QUEUE = 'broadcast_queue';
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -44,10 +46,10 @@ class IslandoraSettingsForm extends ConfigFormBase {
'#default_value' => $config->get(self::BROKER_URL), '#default_value' => $config->get(self::BROKER_URL),
); );
$form[self::TRIPLESTORE_INDEX_QUEUE] = array( $form[self::BROADCAST_QUEUE] = array(
'#type' => 'textfield', '#type' => 'textfield',
'#title' => $this->t('Triplestore Index Queue'), '#title' => $this->t('Broadcast Queue'),
'#default_value' => $config->get(self::TRIPLESTORE_INDEX_QUEUE), '#default_value' => $config->get(self::BROADCAST_QUEUE),
); );
$form[self::FEDORA_REST_ENDPOINT] = array( $form[self::FEDORA_REST_ENDPOINT] = array(
@ -57,16 +59,38 @@ class IslandoraSettingsForm extends ConfigFormBase {
'#default_value' => $config->get(self::FEDORA_REST_ENDPOINT), '#default_value' => $config->get(self::FEDORA_REST_ENDPOINT),
); );
$form[self::FEDORA_INDEXING_QUEUE] = array(
'#type' => 'textfield',
'#title' => $this->t('Fedora Indexing Queue Name'),
'#description' => $this->t('Name of the queue where Drupal will publish updates to have "indexed" to Fedora'),
'#default_value' => $config->get(self::FEDORA_INDEXING_QUEUE),
);
return parent::buildForm($form, $form_state); return parent::buildForm($form, $form_state);
} }
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
// Validate broker url by actually connecting with a stomp client.
$brokerUrl = $form_state->getValue(self::BROKER_URL);
// Attempt to subscribe to a dummy queue.
try {
$stomp = new StatefulStomp(
new Client(
$brokerUrl
)
);
$stomp->subscribe('dummy-queue-for-validation');
$stomp->unsubscribe();
}
// Invalidate the form if there's an issue.
catch (StompException $e) {
$form_state->setErrorByName(
self::BROKER_URL,
$this->t(
'Cannot connect to message broker at @broker_url',
['@broker_url' => $brokerUrl]
)
);
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -75,9 +99,8 @@ class IslandoraSettingsForm extends ConfigFormBase {
$config $config
->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL)) ->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL))
->set(self::TRIPLESTORE_INDEX_QUEUE, $form_state->getValue(self::TRIPLESTORE_INDEX_QUEUE)) ->set(self::BROADCAST_QUEUE, $form_state->getValue(self::BROADCAST_QUEUE))
->set(self::FEDORA_REST_ENDPOINT, $form_state->getValue(self::FEDORA_REST_ENDPOINT)) ->set(self::FEDORA_REST_ENDPOINT, $form_state->getValue(self::FEDORA_REST_ENDPOINT))
->set(self::FEDORA_INDEXING_QUEUE, $form_state->getValue(self::FEDORA_INDEXING_QUEUE))
->save(); ->save();
parent::submitForm($form, $form_state); parent::submitForm($form, $form_state);

125
src/Plugin/RulesAction/Broadcaster.php

@ -0,0 +1,125 @@
<?php
namespace Drupal\islandora\Plugin\RulesAction;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\islandora\Form\IslandoraSettingsForm;
use Drupal\rules\Core\RulesActionBase;
use Stomp\Exception\StompException;
use Stomp\StatefulStomp;
use Stomp\Transport\Message;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an action to broadcast an event to multiple queues/topics.
*
* @RulesAction(
* id = "islandora_broadcast",
* label = @Translation("Broadcast Message"),
* category = @Translation("Islandora"),
* context = {
* "message" = @ContextDefinition("string",
* label = @Translation("Message")
* ),
* "recipients" = @ContextDefinition("string",
* label = @Translation("Recipients"),
* description = @Translation("Queues/Topics to receive the message"),
* multiple = TRUE
* ),
* }
* )
*/
class Broadcaster extends RulesActionBase implements ContainerFactoryPluginInterface {
/**
* Stomp client.
*
* @var \Stomp\StatefulStomp
*/
protected $stomp;
/**
* Name of broadcast queue.
*
* @var string
*/
protected $broadcastQueue;
/**
* Constructs a BroadcastAction.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param string $broadcast_queue
* Name of queue that will handle distributing the broadcast.
* @param \Stomp\StatefulStomp $stomp
* Stomp client.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, $broadcast_queue, StatefulStomp $stomp) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->broadcastQueue = $broadcast_queue;
$this->stomp = $stomp;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$config = $container->get('config.factory');
$settings = $config->get(IslandoraSettingsForm::CONFIG_NAME);
$broadcastQueue = $settings->get(IslandoraSettingsForm::BROADCAST_QUEUE);
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$broadcastQueue,
$container->get('islandora.stomp')
);
}
/**
* Sends a message to a broadcaster to get distributed.
*
* @param string $message
* Message body to send.
* @param array $recipients
* List of queues/topics to broadcast message to.
*/
protected function doExecute($message, array $recipients) {
// Transform recipients array into comma searated list.
$recipients = array_map('trim', $recipients);
$recipients = implode(',', $recipients);
// Transform message from string into a proper message object.
$message = new Message($message, ['IslandoraBroadcastRecipients' => $recipients]);
// Send the message.
try {
$this->stomp->begin();
$this->stomp->send($this->broadcastQueue, $message);
$this->stomp->commit();
}
catch (StompException $e) {
// Log it.
\Drupal::logger('islandora')->error(
'Error publishing message: @msg',
['@msg' => $e->getMessage()]
);
// Notify user.
drupal_set_message(
t('Error publishing message: @msg',
['@msg' => $e->getMessage()]
),
'error'
);
}
}
}

33
src/StompFactory.php

@ -0,0 +1,33 @@
<?php
namespace Drupal\islandora;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\islandora\Form\IslandoraSettingsForm;
use Stomp\Client;
use Stomp\StatefulStomp;
/**
* StatefulStomp static factory.
*/
class StompFactory {
/**
* Factory function.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config
* Config.
*
* @return \Stomp\StatefulStomp
* Stomp client.
*/
static public function create(ConfigFactoryInterface $config) {
// Get broker url from config.
$settings = $config->get(IslandoraSettingsForm::CONFIG_NAME);
$brokerUrl = $settings->get(IslandoraSettingsForm::BROKER_URL);
$client = new Client($brokerUrl);
return new StatefulStomp($client);
}
}

127
tests/src/Kernel/BroadcasterTest.php

@ -0,0 +1,127 @@
<?php
namespace Drupal\Tests\islandora\Kernel;
use Stomp\Exception\StompException;
use Stomp\StatefulStomp;
use Drupal\islandora\Plugin\RulesAction\Broadcaster;
/**
* Broadcaster tests.
*
* @group islandora
* @coversDefaultClass \Drupal\islandora\Plugin\RulesAction\Broadcaster
*/
class BroadcasterTest extends IslandoraKernelTestBase {
protected $testQueue = 'islandora-broadcaster-test-queue';
/**
* Tests that the action does not WSOD Drupal when there's a StompException.
*
* @covers \Drupal\islandora\Plugin\RulesAction\Broadcaster::execute
*/
public function testExecuteSquashesStompExceptions() {
// Set up a fake Stomp client to throw a StompException when used.
$prophecy = $this->prophesize(StatefulStomp::CLASS);
$prophecy->begin()->willThrow(new StompException('STOMP EXCEPTION'));
$stomp = $prophecy->reveal();
$action = $this->createBroadcaster($stomp);
try {
// Execute the action.
$action->execute();
$this->assertTrue(TRUE, "The execute() method must squash StompExceptions.");
}
catch (\Exception $e) {
$this->assertTrue(FALSE, "The execute() method must squash StompExceptions.");
}
}
/**
* Tests that the action DOES NOT squash any other Exception.
*
* @covers \Drupal\islandora\Plugin\RulesAction\Broadcaster::execute
* @expectedException \Exception
*/
public function testExecuteDoesNotSquashOtherExceptions() {
// Set up a fake Stomp client to throw a non-StompException when used.
$prophecy = $this->prophesize(StatefulStomp::CLASS);
$prophecy->begin()->willThrow(new \Exception('NOT A STOMP EXCEPTION'));
$stomp = $prophecy->reveal();
$action = $this->createBroadcaster($stomp);
// This should throw an exception.
$action->execute();
}
/**
* Tests that the action publishes the message to be broadcast to a broker.
*
* @covers \Drupal\islandora\Plugin\RulesAction\Broadcaster::execute
*/
public function testBrokerIntegration() {
// Grab a legit stomp client, using values from config.
$this->installConfig('islandora');
$stomp = $this->container->get('islandora.stomp');
// Create and execute the action.
$action = $this->createBroadcaster($stomp);
$action->execute();
// Verify the message actually got sent.
try {
$stomp->subscribe($this->testQueue);
$msg = $stomp->read();
$this->assertTrue(
strcmp($msg->getBody(), 'test') == 0,
"Message body is not 'test'"
);
$headers = $msg->getHeaders();
$this->assertTrue(
strcmp($headers['IslandoraBroadcastRecipients'], 'activemq:queue:foo,activemq:queue:bar') == 0,
"IslandoraBroadcastRecipients header must be a comma separated list of endpoints"
);
$stomp->unsubscribe();
}
catch (StompException $e) {
$this->assertTrue(FALSE, "There was an error connecting to the stomp broker");
}
}
/**
* Utility function to create a broadcaster action from a Stomp prophecy.
*
* @param StatefulStomp $stomp
* Stomp instance or prophecy.
*
* @return \Drupal\islandora\Plugin\RulesAction\Broadcaster
* Broadcaster, ready to test.
*/
protected function createBroadcaster(StatefulStomp $stomp) {
// Pull the plugin definition out of the plugin system.
$actionManager = $this->container->get('plugin.manager.rules_action');
$definitions = $actionManager->getDefinitions();
$pluginDefinition = $definitions['islandora_broadcast'];
$action = new Broadcaster(
[],
'islandora_broadcast',
$pluginDefinition,
$this->testQueue,
$stomp
);
// Set the required contexts for the action to run.
$action->setContextValue('message', "test");
$action->setContextValue('recipients', ['activemq:queue:foo', 'activemq:queue:bar']);
return $action;
}
}

8
tests/src/Kernel/EventGeneratorTestBase.php

@ -10,9 +10,7 @@ use Drupal\simpletest\UserCreationTrait;
*/ */
abstract class EventGeneratorTestBase extends IslandoraKernelTestBase { abstract class EventGeneratorTestBase extends IslandoraKernelTestBase {
use UserCreationTrait { use UserCreationTrait;
createUser as drupalCreateUser;
}
/** /**
* User entity. * User entity.
@ -35,12 +33,12 @@ abstract class EventGeneratorTestBase extends IslandoraKernelTestBase {
parent::setUp(); parent::setUp();
// Create a test user. // Create a test user.
$this->user = $this->drupalCreateUser(); $this->user = $this->createUser(['add fedora resource entities']);
// Create a test entity. // Create a test entity.
$this->entity = FedoraResource::create([ $this->entity = FedoraResource::create([
"type" => "rdf_source", "type" => "rdf_source",
"uid" => 1, "uid" => $this->user->get('uid'),
"name" => "Test Fixture", "name" => "Test Fixture",
"langcode" => "und", "langcode" => "und",
"status" => 1, "status" => 1,

1
tests/src/Kernel/IslandoraKernelTestBase.php

@ -29,6 +29,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase {
'typed_data', 'typed_data',
'rules', 'rules',
'jsonld', 'jsonld',
'views',
'islandora', 'islandora',
]; ];

15
tests/src/Kernel/VectorClockTest.php

@ -3,6 +3,7 @@
namespace Drupal\Tests\islandora\Kernel; namespace Drupal\Tests\islandora\Kernel;
use Drupal\islandora\Entity\FedoraResource; use Drupal\islandora\Entity\FedoraResource;
use Drupal\simpletest\UserCreationTrait;
/** /**
* Tests the basic behavior of a vector clock. * Tests the basic behavior of a vector clock.
@ -12,6 +13,8 @@ use Drupal\islandora\Entity\FedoraResource;
*/ */
class VectorClockTest extends IslandoraKernelTestBase { class VectorClockTest extends IslandoraKernelTestBase {
use UserCreationTrait;
/** /**
* Fedora resource entity. * Fedora resource entity.
* *
@ -19,16 +22,26 @@ class VectorClockTest extends IslandoraKernelTestBase {
*/ */
protected $entity; protected $entity;
/**
* User entity.
*
* @var \Drupal\user\UserInterface
*/
protected $user;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
// Create a test user.
$this->user = $this->createUser(['add fedora resource entities', 'edit fedora resource entities']);
// Create a test entity. // Create a test entity.
$this->entity = FedoraResource::create([ $this->entity = FedoraResource::create([
"type" => "rdf_source", "type" => "rdf_source",
"uid" => 1, "uid" => $this->user->get('uid'),
"name" => "Test Fixture", "name" => "Test Fixture",
"langcode" => "und", "langcode" => "und",
"status" => 1, "status" => 1,

Loading…
Cancel
Save