Uploaded image for project: 'Jira Service Management Server and Data Center'
  1. Jira Service Management Server and Data Center
  2. JSDSERVER-5273

Notifications that contain only an image will break SD notification job when using Oracle database

    XMLWordPrintable

Details

    Description

      Summary

      When running on Oracle database, JIRA Service Desk will insert NULL value to TEXT_CONTENT column of AO_4E8AE6_NOTIF_BATCH_QUEUE table when the notification in question does not contain any plain text.

      Environment

      • JIRA is running on Oracle database

      Steps to Reproduce

      1. Create a service desk project with sample data.
      2. Navigate to Project settings > Customer notifications and modify the template for "Public comment added" rule as shown below:
      3. Add a public comment which contains only an image to one of the ticket.
      4. Observing the data in AO_4E8AE6_NOTIF_BATCH_QUEUE table.

      Expected Results

      A new row with a empty string for TEXT_CONTENT column is inserted.

      Actual Results

      A new row with NULL for TEXT_CONTENT column is inserted.
      The below exception is thrown in the log file when JIRA tried to send notification :

      2017-07-18 14:58:58,666 Caesium-1-1 ERROR anonymous     [c.a.scheduler.core.JobLauncher] Scheduled job with ID 'sd.custom.notification.batch.send' failed
      java.lang.RuntimeException: no text content set
      	at com.atlassian.servicedesk.plugins.notifications.internal.dao.NotificationBatchQueueEntryBuilder.validate(NotificationBatchQueueEntryBuilder.java:111)
      	at com.atlassian.servicedesk.plugins.notifications.internal.dao.NotificationBatchQueueEntryBuilder.build(NotificationBatchQueueEntryBuilder.java:91)
      	at com.atlassian.servicedesk.plugins.notifications.internal.dao.NotificationBatchQueueDao.convertToEntry(NotificationBatchQueueDao.java:54)
      	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
      	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
      	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
      	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
      	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
      	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
      	at com.atlassian.servicedesk.plugins.notifications.internal.dao.NotificationBatchQueueDao.convertToEntries(NotificationBatchQueueDao.java:38)
      	at com.atlassian.servicedesk.plugins.notifications.internal.dao.NotificationBatchQueueDao.fetchUnsentEntries(NotificationBatchQueueDao.java:26)
      	at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.lambda$execute$0(DatabaseAccessorImpl.java:68)
      	at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor.executeInternal(DefaultTransactionalExecutor.java:91)
      	at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor$1.execute(DefaultTransactionalExecutor.java:45)
      	at com.atlassian.sal.jira.rdbms.JiraHostConnectionAccessor.lambda$borrowConnectionAndExecute$0(JiraHostConnectionAccessor.java:62)
      	at com.atlassian.jira.database.DatabaseAccessorImpl.executeQuery(DatabaseAccessorImpl.java:67)
      	... 2 filtered
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
      	at com.sun.proxy.$Proxy496.executeQuery(Unknown Source)
      	... 2 filtered
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:136)
      	at com.sun.proxy.$Proxy496.executeQuery(Unknown Source)
      	at com.atlassian.sal.jira.rdbms.JiraHostConnectionAccessor.borrowConnectionAndExecute(JiraHostConnectionAccessor.java:50)
      	at com.atlassian.sal.jira.rdbms.JiraHostConnectionAccessor.execute(JiraHostConnectionAccessor.java:35)
      	at com.atlassian.sal.core.rdbms.DefaultTransactionalExecutor.execute(DefaultTransactionalExecutor.java:42)
      	at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.execute(DatabaseAccessorImpl.java:66)
      	at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.runInNewTransaction(DatabaseAccessorImpl.java:37)
      	at com.atlassian.pocketknife.internal.querydsl.DatabaseAccessorImpl.run(DatabaseAccessorImpl.java:32)
      	at com.atlassian.servicedesk.plugins.notifications.internal.scheduler.NotificationBatchJobRunner.sendBatchedMails(NotificationBatchJobRunner.java:49)
      	at com.atlassian.servicedesk.plugins.notifications.internal.scheduler.NotificationBatchJobRunner.runJob(NotificationBatchJobRunner.java:41)
      	at com.atlassian.scheduler.core.JobLauncher.runJob(JobLauncher.java:153)
      	at com.atlassian.scheduler.core.JobLauncher.launchAndBuildResponse(JobLauncher.java:118)
      	at com.atlassian.scheduler.core.JobLauncher.launch(JobLauncher.java:97)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.launchJob(CaesiumSchedulerService.java:443)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeClusteredJob(CaesiumSchedulerService.java:438)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeClusteredJobWithRecoveryGuard(CaesiumSchedulerService.java:462)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeQueuedJob(CaesiumSchedulerService.java:390)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:285)
      	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:282)
      	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeJob(SchedulerQueueWorker.java:65)
      	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeNextJob(SchedulerQueueWorker.java:59)
      	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.run(SchedulerQueueWorker.java:34)
      	at java.lang.Thread.run(Thread.java:745)
      

      Notes

      The issue cannot be reproduced on PostgreSQL database, in which two single quotes ('') are inserted to the database to represent an empty string instead of NULL.

      Workaround

      Modify the relevant notification template to include some plain text message or use the default template.

      Attachments

        1. 2017-07-25_comment-added.png
          89 kB
          Chen Mao
        2. nowy template zapobiegający błędom notyfikacji.png
          26 kB
          Dastin Kuwałek [SoftwarePlant]

        Issue Links

          Activity

            People

              agoldthorpe Aidan Goldthorpe
              cmao Chen Mao (Inactive)
              Votes:
              4 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Backbone Issue Sync