Islandora / documentation

Contains islandora's documentation and main issue queue.
MIT License
104 stars 71 forks source link

[BUG] 'generate_image_derivative_file' and 'generate_extracted_text_file' actions not working #2135

Closed alxp closed 2 years ago

alxp commented 2 years ago

There are a couple of Actions that ship with Islandora Defaults built to show Islandora's Multi-file Media approach.

They seem to not be functional at the moment.

Test results on fresh Playbook run which has working thumbnail and extracted text generation using the actions that create new Media entities:

Hypercube log after "Generate Extracted Text for Media Attachment" action invokes Crayfish:


[2022-07-13 08:10:11] app.INFO: Matched route "{route}". {"route":"GET_","route_parameters":{"_controller":"hypercube.controller:get","_route":"GET_"},"request_uri":"http://127.0.0.1:8000/hypercube/","method":"GET"} []
[2022-07-13 08:10:11] app.DEBUG: Checking for guard authentication credentials. {"firewall_key":"default","authenticators":1} []
[2022-07-13 08:10:11] app.DEBUG: Checking support on guard authenticator. {"firewall_key":"default","authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] app.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"default","authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] crayfish.syn.jwt_authentication.DEBUG: Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NTc3MTc4MDEsImV4cCI6MTY1NzcyNTAwMSwid2ViaWQiOiIxIiwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo4MDAwIiwic3ViIjoiYWRtaW4iLCJyb2xlcyI6WyJhdXRoZW50aWNhdGVkIiwiYWRtaW5pc3RyYXRvciIsImZlZG9yYWFkbWluIl0sImF1ZCI6WyJpc2xhbmRvcmEiXX0.WFh5GFxe5HMsnaXdb1NH-_4-SWUTdmL6-YBkPCHCKp-T0s0OgdNajbu7kdwIefCD8qouanodN71iRkxaP_rfiaGkvjDOKdlDY3iCTmhYOmCxz2RcdV0-upPp3nE5QbaZLjP76BTDNLgfYJGJPZaLg8Ko88lQ45kWRkS3bIHapaegt4IRf6rm1anEOCUYHP5CHe3A9y8a0AruD1miqBkjU02NlHT5m5E-nEfUyvIDRSBUF-2qmdcfi7k0HbB_sZl42TUniEPtpsZwWM15VnwY2rAEGNsih3IBGc4fQKSFJT1eYEaIPq9fCXxexlCCZTq0t-WKFT46hbo8AZiLNT8QDw [] []
[2022-07-13 08:10:11] app.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"default","authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] app.INFO: Guard authentication successful! {"token":"[object] (Symfony\\Component\\Security\\Guard\\Token\\PostAuthenticationGuardToken: PostAuthenticationGuardToken(user=\"admin\", authenticated=true, roles=\"authenticated, administrator, fedoraadmin\"))","authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] app.DEBUG: Guard authenticator set no success response: request continues. {"authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] app.DEBUG: Remember me skipped: it is not configured for the firewall. {"authenticator":"Islandora\\Crayfish\\Commons\\Syn\\JwtAuthenticator"} []
[2022-07-13 08:10:11] app.DEBUG: > GET /hypercube/ [] []
[2022-07-13 08:10:11] crayfish.apix_middleware.DEBUG: Malformed request, no Apix-Ldp-Resource header present [] []
[2022-07-13 08:10:11] app.DEBUG: < 400 [] []

When adding an Generate "generate_image_derivative_file" action to an image context, saving the image produces a white screen. The error in the Apache log is:

[Thu Jul 14 17:47:42.953001 2022] [php7:notice] [pid 9190] [client 10.0.2.2:55046] TypeError: Argument 3 passed to Drupal\\islandora\\Event\\StompHeaderEvent::__construct() must be of the type array, null given, called in /var/www/html/drupal/web/modules/contrib/islandora/src/EventGenerator/EmitEvent.php on line 163 in /var/www/html/drupal/web/modules/contrib/islandora/src/Event/StompHeaderEvent.php on line 54 #0 /var/www/html/drupal/web/modules/contrib/islandora/src/EventGenerator/EmitEvent.php(163): Drupal\\islandora\\Event\\StompHeaderEvent->__construct(Object(Drupal\\node\\Entity\\Node), Object(Drupal\\user\\Entity\\User), NULL, Array)\n#1 /var/www/html/drupal/web/core/lib/Drupal/Core/Action/ActionBase.php(22): Drupal\\islandora\\EventGenerator\\EmitEvent->execute(Object(Drupal\\node\\Entity\\Node))\n#2 /var/www/html/drupal/web/core/modules/system/src/Entity/Action.php(129): Drupal\\Core\\Action\\ActionBase->executeMultiple(Array)\n#3 /var/www/html/drupal/web/modules/contrib/islandora/src/PresetReaction/PresetReaction.php(59): Drupal\\system\\Entity\\Action->execute(Array)\n#4 /var/www/html/drupal/web/modules/contrib/islandora/src/IslandoraUtils.php(407): Drupal\\islandora\\PresetReaction\\PresetReaction->execute(Object(Drupal\\node\\Entity\\Node))\n#5 /var/www/html/drupal/web/modules/contrib/islandora/islandora.module(198): Drupal\\islandora\\IslandoraUtils->executeDerivativeReactions('\\\\Drupal\\\\islando...', Object(Drupal\\node\\Entity\\Node), Object(Drupal\\media\\Entity\\Media))\n#6 [internal function]: islandora_file_update(Object(Drupal\\file\\Entity\\File))\n#7 /var/www/html/drupal/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(426): call_user_func_array(Object(Closure), Array)\n#8 /var/www/html/drupal/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(405): Drupal\\Core\\Extension\\ModuleHandler->Drupal\\Core\\Extension\\{closure}(Object(Closure), 'islandora')\n#9 /var/www/html/drupal/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(433): Drupal\\Core\\Extension\\ModuleHandler->invokeAllWith('file_update', Object(Closure))\n#10 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(249): Drupal\\Core\\Extension\\ModuleHandler->invokeAll('file_update', Array)\n#11 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(903): Drupal\\Core\\Entity\\EntityStorageBase->invokeHook('update', Object(Drupal\\file\\Entity\\File))\n#12 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(598): Drupal\\Core\\Entity\\ContentEntityStorageBase->invokeHook('update', Object(Drupal\\file\\Entity\\File))\n#13 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(784): Drupal\\Core\\Entity\\EntityStorageBase->doPostSave(Object(Drupal\\file\\Entity\\File), true)\n#14 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(523): Drupal\\Core\\Entity\\ContentEntityStorageBase->doPostSave(Object(Drupal\\file\\Entity\\File), true)\n#15 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\\Core\\Entity\\EntityStorageBase->save(Object(Drupal\\file\\Entity\\File))\n#16 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage->save(Object(Drupal\\file\\Entity\\File))\n#17 /var/www/html/drupal/web/core/modules/file/src/FileUsage/FileUsageBase.php(37): Drupal\\Core\\Entity\\EntityBase->save()\n#18 /var/www/html/drupal/web/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php(60): Drupal\\file\\FileUsage\\FileUsageBase->add(Object(Drupal\\file\\Entity\\File), 'file', 'media', '1506', 1)\n#19 /var/www/html/drupal/web/core/modules/file/src/Plugin/Field/FieldType/FileFieldItemList.php(27): Drupal\\file\\FileUsage\\DatabaseFileUsageBackend->add(Object(Drupal\\file\\Entity\\File), 'file', 'media', '1506')\n#20 [internal function]: Drupal\\file\\Plugin\\Field\\FieldType\\FileFieldItemList->postSave(false)\n#21 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(941): call_user_func_array(Array, Array)\n#22 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(973): Drupal\\Core\\Entity\\ContentEntityStorageBase->invokeFieldMethod('postSave', Object(Drupal\\media\\Entity\\Media), false)\n#23 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(895): Drupal\\Core\\Entity\\ContentEntityStorageBase->invokeFieldPostSave(Object(Drupal\\media\\Entity\\Media), false)\n#24 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(598): Drupal\\Core\\Entity\\ContentEntityStorageBase->invokeHook('insert', Object(Drupal\\media\\Entity\\Media))\n#25 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(784): Drupal\\Core\\Entity\\EntityStorageBase->doPostSave(Object(Drupal\\media\\Entity\\Media), false)\n#26 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(523): Drupal\\Core\\Entity\\ContentEntityStorageBase->doPostSave(Object(Drupal\\media\\Entity\\Media), false)\n#27 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\\Core\\Entity\\EntityStorageBase->save(Object(Drupal\\media\\Entity\\Media))\n#28 /var/www/html/drupal/web/core/modules/media/src/MediaStorage.php(29): Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage->save(Object(Drupal\\media\\Entity\\Media))\n#29 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\\media\\MediaStorage->save(Object(Drupal\\media\\Entity\\Media))\n#30 /var/www/html/drupal/web/core/lib/Drupal/Core/Entity/EntityForm.php(285): Drupal\\Core\\Entity\\EntityBase->save()\n#31 /var/www/html/drupal/web/core/modules/media/src/MediaForm.php(61): Drupal\\Core\\Entity\\EntityForm->save(Array, Object(Drupal\\Core\\Form\\FormState))\n#32 [internal function]: Drupal\\media\\MediaForm->save(Array, Object(Drupal\\Core\\Form\\FormState))\n#33 /var/www/html/drupal/web/core/lib/Drupal/Core/Form/FormSubmitter.php(114): call_user_func_array(Array, Array)\n#34 /var/www/html/drupal/web/core/lib/Drupal/Core/Form/FormSubmitter.php(52): Drupal\\Core\\Form\\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\\Core\\Form\\FormState))\n#35 /var/www/html/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(592): Drupal\\Core\\Form\\FormSubmitter->doSubmitForm(Array, Object(Drupal\\Core\\Form\\FormState))\n#36 /var/www/html/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(320): Drupal\\Core\\Form\\FormBuilder->processForm('media_image_add...', Array, Object(Drupal\\Core\\Form\\FormState))\n#37 /var/www/html/drupal/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\\Core\\Form\\FormBuilder->buildForm(Object(Drupal\\media\\MediaForm), Object(Drupal\\Core\\Form\\FormState))\n#38 [internal function]: Drupal\\Core\\Controller\\FormController->getContentResult(Object(Symfony\\Component\\HttpFoundation\\Request), Object(Drupal\\Core\\Routing\\RouteMatch))\n#39 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)\n#40 /var/www/html/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->Drupal\\Core\\EventSubscriber\\{closure}()\n#41 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\\Core\\Render\\Renderer->executeInRenderContext(Object(Drupal\\Core\\Render\\RenderContext), Object(Closure))\n#42 /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)\n#43 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\\Core\\EventSubscriber\\EarlyRenderingControllerWrapperSubscriber->Drupal\\Core\\EventSubscriber\\{closure}()\n#44 /var/www/html/drupal/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\\Component\\HttpKernel\\HttpKernel->handleR

I tried to run the same test on latest ISLE-DC, after running 'make local' and then upgrading to Drupal 9 and installing Islandora Defaults, but then the standard Text Extraction action did not seem to be able to invoke Hypercube so something else is going on there that I may report as a separate bug.

What steps does it take to reproduce the issue?

On Fresh Islandora Playbook instance:

To test Image inline thumbnail field generation:

  1. Go to /admin/structure/media and choose "Manage Fields" on Image.
  2. Add a new File field and name it something like "inline test thumbnail". Add "jpg, png,gif" to the allowed file extensions.
  3. Back on the Actions page, select "Generate an image derivative file for media attachment". from the drop down and click Add.
  4. Give it an appropriate label and select the field you created on the Image media entity in the drop down for "Destination file field name" and Save.
  5. Go to /node/add and choose Repository Item
  6. Choose Image in the Model drop down and Save.
  7. Click on the Media tab and click 'Add media'.
  8. Choose 'Image' and upload an image file and check 'Original File" and Save.

Wait a minute or two and click Edit again.

Expected: You should see a thumbnail in the field you added.

To test the inline Text Extraction functionality:

  1. Go to /admin/structure/media and click Manage Fields next to File
  2. Add a new field of type File and name it something like " extracted text" File. In the allowed file extensions field add .txt if it's not there.
  3. Add another field, this one you can add an Existing Field and choose "Text Long - Extracted Text". and Save.
  4. . Go to /admin/config/system/actions
  5. Click Configure next to "Generate Extracted Text for Media Attachment".
  6. Choose the two fields you just added for extracted text field and file field then save.
  7. Go to /node/add and pick Repository Item.
  8. Add a title and pick Page form the Model field and save.
  9. Click the Media tab and add media of type File.
  10. Upload a .tiff or .jp2 file and check Original File and save.

Expected

The two fields that hold extracted text should get populated. You may need to either configure the entity view display for the media or click Edit to see the fields.

See above

Adding Media

The derivatives do not get generated.

Editor, Administrator

Derivatives get generated and added to the specified fields.

Which version of Islandora are you using?

2.4

Any related open or closed issues to this bug report?

Screenshots:

alxp commented 2 years ago

Tackling the white screen first, this looks like a pretty simple thing,

In AbstractGenerateDerivativeMediaFile.php

 protected function generateData(EntityInterface $entity) {
    $data = parent::generateData($entity);
    if (get_class($entity) != 'Drupal\media\Entity\Media') {
      return;
    }

The event is emitted on the parent node called in islandora_file_update() hook. Since the Generate Thumbnail File event doesn't apply to nodes, it's bailing. But it's returning NULL, but the calling code keeps going and tries to construct a Stomp Header with "NULL" for data, which causes the type mismatch error.

How has this not come up before?

alxp commented 2 years ago

I think I need some help to understand what is supposed to be going on in the logic to generate derivatives:

Here is the call stack that leads up to the error:

image

The islandora_file_update() hook grabs a Media's parent and generates derivatives, passing the $node and the $media along:

oreach ($utils->getReferencingMedia($file->id()) as $media) {
    $node = $utils->getParentNode($media);
    if ($node) {
      $utils->executeDerivativeReactions(
        '\Drupal\islandora\Plugin\ContextReaction\DerivativeReaction',
        $node,
        $media
      );
    }

In IslandoraUtils::executeDerivativeReactions, it evaluates the contexts and then executes the active reactions, but only passes the $node entity along:


    // Fire off index reactions.
    foreach ($this->contextManager->getActiveReactions($reaction_type) as $reaction) {
      $reaction->execute($node);
    }

SO: How are the media derivatives supposed to be executed?

rosiel commented 2 years ago

In that mess of hook_insert()s and hook_updates (for nodes, media, and files) there are a few places where DerivativeFileReaction gets called:

It doesn't run on file update - but i am not sure if 'file update' is really a thing (in the UI), since the workflow appears to always include deleting a file and replacing it with a different file. Maybe it's possible for a file to be updated in place programmatically (like running a new derivative on top of an old derivative, if they have the same filename?? and drupal doesn't stop them? )

ajstanley commented 2 years ago

Video docs - https://www.youtube.com/watch?v=3U6tBvD8oJY