0

I would Like to schedule a method using The annotation @Scheduled using cron, For example I want that the method should be executed everyday in the time specified by the client. So I would like to get the cron value from the DB, in order to give the client the possibility of executing the method whenever he wants. Here is my method, it sends emails automatically at 10:00 am to the given addresses, so my goal is to make the 10:00 dynamic. Thanks for your help.


    @Scheduled(cron = "0 00 10* * ?")
    public void periodicNotification()  {
        JavaMailSenderImpl jms = (JavaMailSenderImpl) sender;
        MimeMessage message = jms.createMimeMessage();
        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());
            
         
        List<EmailNotification> emailNotifs = enr.findAll();
        for (EmailNotification i : emailNotifs) 
        {
            helper.setFrom("smsender4@gmail.com");
            List<String> recipients = fileRepo.findWantedEmails(i.getDaysNum());
            //List<String> emails = recipientsRepository.getScheduledEmails();

            String[] to = recipients.stream().toArray(String[]::new);
            helper.setTo(to);
            helper.setText(i.getMessage());
            helper.setSubject(i.getSubject());
            sender.send(message);
            System.out.println("Email successfully sent to: " + Arrays.toString(to));
        }
        }
        catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

darwin
  • 27
  • 1
  • 8
  • I guess this is what you are looking for https://stackoverflow.com/questions/24306004/task-scheduling-using-cron-expression-from-properties-file – Sagar Mar 27 '21 at 10:03
  • Thanks for your reply, I see in that case that they're getting the cron value from the application.properties file, for my case I want to get it from the DB – darwin Mar 27 '21 at 14:41

2 Answers2

0

So I'm thinking at the next solution. ( + using the answer accepted here )

  1. Let's say you have a class that imlpements Runnable interface -> this will be your job that gets executed. Let's call it MyJob

  2. Also assume that we have a map that hold the id of the job and it's execution reference ( you'll see in a sec what i'm talking about). Call it something like currentExecutingJobs

  3. Assume you have an endpoint that gets the name of the job and a cron expression from the client

  4. When that endpoints gets called:

  5. You'll look in the map above to see if there is any entry with that job id. If it exists, you cancel the job.

  6. After that, you'll create an instance of that job ( You can do that by using reflection and having a custom annotation on your job classes in which you can provide an id. For example @MyJob("myCustomJobId" )

  7. And from the link provided, you'll schedule the job using

     // Schedule a task with the given cron expression
     ScheduledFuture myJobScheduledFutere = executor.schedule(myJob, new CronTrigger(cronExpression));
    
  8. And put the result in the above map currentExecutingJobs.put("myCustomJobId", myJobScheduledFutere)

ScheduledFuture docs

ALex
  • 673
  • 1
  • 6
  • 19
0

In case you want to read property from database you can implement the EnvironmentPostProcessor and read the necessary values from DB and add it to Environment object, more details available at https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-spring-boot-application

Sagar
  • 61
  • 9