Schedule a JOb on specific date in Akka Scheduler










2














I have a thread which need to run at particular day lets say it is 1st of the every month.
As we are using Akka Scheduler from starting so i just want to know whether we can do it by Akka or not.(Quartz scheduler can solve this problem easily.)



i can see in Akka scheduler schedule function, we need to pass restart time as well in the parameter. But restart time is not same for this particular date,because some months are 30 days,31 days etc.
So because of that my scheduler is running after each restart time passed.



Cron Expression: cron_expression=0 0 06 1 * ?
restart_time =86400 (here it is 24 hours)

Akka.system().scheduler().schedule(validCronExpressionTime, Duration.create(restart, TimeUnit.SECONDS), thread, Akka.system().dispatcher());


here validCronExpressionTime will find the valid date on the basis of cron_expression setting in file.



in akka scheduler the first arugument is just for starting the scheduler on a particular time after that it gets repeated on the basis of restart time.










share|improve this question





















  • did below answer helped you or not?
    – Amit Yadav
    Aug 4 '16 at 13:01











  • Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
    – Jitendra Yadav
    Aug 5 '16 at 11:09










  • No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
    – Amit Yadav
    Aug 5 '16 at 11:33











  • duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
    – Jitendra Yadav
    Aug 5 '16 at 12:03











  • We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
    – Amit Yadav
    Aug 5 '16 at 12:34
















2














I have a thread which need to run at particular day lets say it is 1st of the every month.
As we are using Akka Scheduler from starting so i just want to know whether we can do it by Akka or not.(Quartz scheduler can solve this problem easily.)



i can see in Akka scheduler schedule function, we need to pass restart time as well in the parameter. But restart time is not same for this particular date,because some months are 30 days,31 days etc.
So because of that my scheduler is running after each restart time passed.



Cron Expression: cron_expression=0 0 06 1 * ?
restart_time =86400 (here it is 24 hours)

Akka.system().scheduler().schedule(validCronExpressionTime, Duration.create(restart, TimeUnit.SECONDS), thread, Akka.system().dispatcher());


here validCronExpressionTime will find the valid date on the basis of cron_expression setting in file.



in akka scheduler the first arugument is just for starting the scheduler on a particular time after that it gets repeated on the basis of restart time.










share|improve this question





















  • did below answer helped you or not?
    – Amit Yadav
    Aug 4 '16 at 13:01











  • Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
    – Jitendra Yadav
    Aug 5 '16 at 11:09










  • No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
    – Amit Yadav
    Aug 5 '16 at 11:33











  • duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
    – Jitendra Yadav
    Aug 5 '16 at 12:03











  • We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
    – Amit Yadav
    Aug 5 '16 at 12:34














2












2








2







I have a thread which need to run at particular day lets say it is 1st of the every month.
As we are using Akka Scheduler from starting so i just want to know whether we can do it by Akka or not.(Quartz scheduler can solve this problem easily.)



i can see in Akka scheduler schedule function, we need to pass restart time as well in the parameter. But restart time is not same for this particular date,because some months are 30 days,31 days etc.
So because of that my scheduler is running after each restart time passed.



Cron Expression: cron_expression=0 0 06 1 * ?
restart_time =86400 (here it is 24 hours)

Akka.system().scheduler().schedule(validCronExpressionTime, Duration.create(restart, TimeUnit.SECONDS), thread, Akka.system().dispatcher());


here validCronExpressionTime will find the valid date on the basis of cron_expression setting in file.



in akka scheduler the first arugument is just for starting the scheduler on a particular time after that it gets repeated on the basis of restart time.










share|improve this question













I have a thread which need to run at particular day lets say it is 1st of the every month.
As we are using Akka Scheduler from starting so i just want to know whether we can do it by Akka or not.(Quartz scheduler can solve this problem easily.)



i can see in Akka scheduler schedule function, we need to pass restart time as well in the parameter. But restart time is not same for this particular date,because some months are 30 days,31 days etc.
So because of that my scheduler is running after each restart time passed.



Cron Expression: cron_expression=0 0 06 1 * ?
restart_time =86400 (here it is 24 hours)

Akka.system().scheduler().schedule(validCronExpressionTime, Duration.create(restart, TimeUnit.SECONDS), thread, Akka.system().dispatcher());


here validCronExpressionTime will find the valid date on the basis of cron_expression setting in file.



in akka scheduler the first arugument is just for starting the scheduler on a particular time after that it gets repeated on the basis of restart time.







java akka scheduled-tasks






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 4 '16 at 9:14









Jitendra Yadav

4811




4811











  • did below answer helped you or not?
    – Amit Yadav
    Aug 4 '16 at 13:01











  • Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
    – Jitendra Yadav
    Aug 5 '16 at 11:09










  • No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
    – Amit Yadav
    Aug 5 '16 at 11:33











  • duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
    – Jitendra Yadav
    Aug 5 '16 at 12:03











  • We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
    – Amit Yadav
    Aug 5 '16 at 12:34

















  • did below answer helped you or not?
    – Amit Yadav
    Aug 4 '16 at 13:01











  • Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
    – Jitendra Yadav
    Aug 5 '16 at 11:09










  • No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
    – Amit Yadav
    Aug 5 '16 at 11:33











  • duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
    – Jitendra Yadav
    Aug 5 '16 at 12:03











  • We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
    – Amit Yadav
    Aug 5 '16 at 12:34
















did below answer helped you or not?
– Amit Yadav
Aug 4 '16 at 13:01





did below answer helped you or not?
– Amit Yadav
Aug 4 '16 at 13:01













Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
– Jitendra Yadav
Aug 5 '16 at 11:09




Hi,Amit it seems that your code will run the thread on the 1st of the month only once, but i want to run it on 1st of every month.
– Jitendra Yadav
Aug 5 '16 at 11:09












No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
– Amit Yadav
Aug 5 '16 at 11:33





No, this will run on every first date of month you need to put this same code inside your actor which you want to run on every 1st date. Continue asking if any other question arise.
– Amit Yadav
Aug 5 '16 at 11:33













duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
– Jitendra Yadav
Aug 5 '16 at 12:03





duration which you are setting is always checking the difference between 1st of the month to the current time, but this will not always be the case, Schedule once will execute the runnable after the particular duration every time. here duration will be set once and every time it will keep on scheduling after that duration interval always. ??
– Jitendra Yadav
Aug 5 '16 at 12:03













We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
– Amit Yadav
Aug 5 '16 at 12:34





We cannot schedule the cron like you want. We need to schedule the next event on start of every previous event. This is the only way we can do in akka schedule. If you have any problem in implementing this approach then let me know
– Amit Yadav
Aug 5 '16 at 12:34













2 Answers
2






active

oldest

votes


















0














I am using akka scheduler as shown in below code.



Each user can login to my Application and can create scheduler for background task.I am using Akka scheduler for this purpose.



public Cancellable buildScheduler(String actorName, SchedulerActorMessage message, long interval, TimeUnit timeUnit, long initialDelay, String actorMapKey) 
ActorRef daemonRef = actorSystem.actorOf(Props.create(SchedulerActor.class), actorName);
Cancellable cancellableActor = actorSystem.scheduler().schedule(FiniteDuration.apply(initialDelay, timeUnit),
FiniteDuration.apply(interval, timeUnit), daemonRef, message,
actorSystem.dispatcher(), ActorRef.noSender());
actorMap.put(actorMapKey, cancellableActor);
return cancellableActor;



Now, in SchedulerActor I have defined job as below ,



public class SchedulerActor extends AbstractActor {
@Override
public Receive createReceive()
return receiveBuilder().match(SchedulerActorMessage.class, message ->
CompletableFuture<String> jobResult =
message.getJob().scheduleJob(message.Id());
jobResult.thenAccept(state ->
if (state.equals(DONE))
//do post action
else
//handle exception

);
).build();



I am passing my Job instance in the SchedulerActorMessage.






share|improve this answer






























    -1














    Create an actor, say Test actor and tell it from your main class and inside that actor, in on receive use below code.



    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DATE, <choose date of your choice>);
    cal.set(Calendar.MONTH, <choose month of your choice>);

    Calendar cal2 = Calendar.getInstance();

    long duration =(cal2.getTimeInMillis()-cal.getTimeInMillis())/1000;

    ActorRef testActorRef = getContext().actorOf(Props.create(Test.class));
    getContext().system().scheduler().scheduleOnce(Duration.create(duration, TimeUnit.SECONDS), testActorRef, messege, getContext().system().dispatcher(), null);





    share|improve this answer






















    • let me know if any question arise.
      – Amit Yadav
      Aug 4 '16 at 11:47











    • you set Date 1 first then added 1 month.
      – Govind Singh
      Nov 6 at 11:42










    • @GovindSingh I resolved that
      – Amit Yadav
      Nov 13 at 13:15










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38763206%2fschedule-a-job-on-specific-date-in-akka-scheduler%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I am using akka scheduler as shown in below code.



    Each user can login to my Application and can create scheduler for background task.I am using Akka scheduler for this purpose.



    public Cancellable buildScheduler(String actorName, SchedulerActorMessage message, long interval, TimeUnit timeUnit, long initialDelay, String actorMapKey) 
    ActorRef daemonRef = actorSystem.actorOf(Props.create(SchedulerActor.class), actorName);
    Cancellable cancellableActor = actorSystem.scheduler().schedule(FiniteDuration.apply(initialDelay, timeUnit),
    FiniteDuration.apply(interval, timeUnit), daemonRef, message,
    actorSystem.dispatcher(), ActorRef.noSender());
    actorMap.put(actorMapKey, cancellableActor);
    return cancellableActor;



    Now, in SchedulerActor I have defined job as below ,



    public class SchedulerActor extends AbstractActor {
    @Override
    public Receive createReceive()
    return receiveBuilder().match(SchedulerActorMessage.class, message ->
    CompletableFuture<String> jobResult =
    message.getJob().scheduleJob(message.Id());
    jobResult.thenAccept(state ->
    if (state.equals(DONE))
    //do post action
    else
    //handle exception

    );
    ).build();



    I am passing my Job instance in the SchedulerActorMessage.






    share|improve this answer



























      0














      I am using akka scheduler as shown in below code.



      Each user can login to my Application and can create scheduler for background task.I am using Akka scheduler for this purpose.



      public Cancellable buildScheduler(String actorName, SchedulerActorMessage message, long interval, TimeUnit timeUnit, long initialDelay, String actorMapKey) 
      ActorRef daemonRef = actorSystem.actorOf(Props.create(SchedulerActor.class), actorName);
      Cancellable cancellableActor = actorSystem.scheduler().schedule(FiniteDuration.apply(initialDelay, timeUnit),
      FiniteDuration.apply(interval, timeUnit), daemonRef, message,
      actorSystem.dispatcher(), ActorRef.noSender());
      actorMap.put(actorMapKey, cancellableActor);
      return cancellableActor;



      Now, in SchedulerActor I have defined job as below ,



      public class SchedulerActor extends AbstractActor {
      @Override
      public Receive createReceive()
      return receiveBuilder().match(SchedulerActorMessage.class, message ->
      CompletableFuture<String> jobResult =
      message.getJob().scheduleJob(message.Id());
      jobResult.thenAccept(state ->
      if (state.equals(DONE))
      //do post action
      else
      //handle exception

      );
      ).build();



      I am passing my Job instance in the SchedulerActorMessage.






      share|improve this answer

























        0












        0








        0






        I am using akka scheduler as shown in below code.



        Each user can login to my Application and can create scheduler for background task.I am using Akka scheduler for this purpose.



        public Cancellable buildScheduler(String actorName, SchedulerActorMessage message, long interval, TimeUnit timeUnit, long initialDelay, String actorMapKey) 
        ActorRef daemonRef = actorSystem.actorOf(Props.create(SchedulerActor.class), actorName);
        Cancellable cancellableActor = actorSystem.scheduler().schedule(FiniteDuration.apply(initialDelay, timeUnit),
        FiniteDuration.apply(interval, timeUnit), daemonRef, message,
        actorSystem.dispatcher(), ActorRef.noSender());
        actorMap.put(actorMapKey, cancellableActor);
        return cancellableActor;



        Now, in SchedulerActor I have defined job as below ,



        public class SchedulerActor extends AbstractActor {
        @Override
        public Receive createReceive()
        return receiveBuilder().match(SchedulerActorMessage.class, message ->
        CompletableFuture<String> jobResult =
        message.getJob().scheduleJob(message.Id());
        jobResult.thenAccept(state ->
        if (state.equals(DONE))
        //do post action
        else
        //handle exception

        );
        ).build();



        I am passing my Job instance in the SchedulerActorMessage.






        share|improve this answer














        I am using akka scheduler as shown in below code.



        Each user can login to my Application and can create scheduler for background task.I am using Akka scheduler for this purpose.



        public Cancellable buildScheduler(String actorName, SchedulerActorMessage message, long interval, TimeUnit timeUnit, long initialDelay, String actorMapKey) 
        ActorRef daemonRef = actorSystem.actorOf(Props.create(SchedulerActor.class), actorName);
        Cancellable cancellableActor = actorSystem.scheduler().schedule(FiniteDuration.apply(initialDelay, timeUnit),
        FiniteDuration.apply(interval, timeUnit), daemonRef, message,
        actorSystem.dispatcher(), ActorRef.noSender());
        actorMap.put(actorMapKey, cancellableActor);
        return cancellableActor;



        Now, in SchedulerActor I have defined job as below ,



        public class SchedulerActor extends AbstractActor {
        @Override
        public Receive createReceive()
        return receiveBuilder().match(SchedulerActorMessage.class, message ->
        CompletableFuture<String> jobResult =
        message.getJob().scheduleJob(message.Id());
        jobResult.thenAccept(state ->
        if (state.equals(DONE))
        //do post action
        else
        //handle exception

        );
        ).build();



        I am passing my Job instance in the SchedulerActorMessage.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 9 at 14:58









        Suraj Rao

        22.6k75469




        22.6k75469










        answered Oct 9 at 14:53









        omee parikh

        31




        31























            -1














            Create an actor, say Test actor and tell it from your main class and inside that actor, in on receive use below code.



            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DATE, <choose date of your choice>);
            cal.set(Calendar.MONTH, <choose month of your choice>);

            Calendar cal2 = Calendar.getInstance();

            long duration =(cal2.getTimeInMillis()-cal.getTimeInMillis())/1000;

            ActorRef testActorRef = getContext().actorOf(Props.create(Test.class));
            getContext().system().scheduler().scheduleOnce(Duration.create(duration, TimeUnit.SECONDS), testActorRef, messege, getContext().system().dispatcher(), null);





            share|improve this answer






















            • let me know if any question arise.
              – Amit Yadav
              Aug 4 '16 at 11:47











            • you set Date 1 first then added 1 month.
              – Govind Singh
              Nov 6 at 11:42










            • @GovindSingh I resolved that
              – Amit Yadav
              Nov 13 at 13:15















            -1














            Create an actor, say Test actor and tell it from your main class and inside that actor, in on receive use below code.



            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DATE, <choose date of your choice>);
            cal.set(Calendar.MONTH, <choose month of your choice>);

            Calendar cal2 = Calendar.getInstance();

            long duration =(cal2.getTimeInMillis()-cal.getTimeInMillis())/1000;

            ActorRef testActorRef = getContext().actorOf(Props.create(Test.class));
            getContext().system().scheduler().scheduleOnce(Duration.create(duration, TimeUnit.SECONDS), testActorRef, messege, getContext().system().dispatcher(), null);





            share|improve this answer






















            • let me know if any question arise.
              – Amit Yadav
              Aug 4 '16 at 11:47











            • you set Date 1 first then added 1 month.
              – Govind Singh
              Nov 6 at 11:42










            • @GovindSingh I resolved that
              – Amit Yadav
              Nov 13 at 13:15













            -1












            -1








            -1






            Create an actor, say Test actor and tell it from your main class and inside that actor, in on receive use below code.



            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DATE, <choose date of your choice>);
            cal.set(Calendar.MONTH, <choose month of your choice>);

            Calendar cal2 = Calendar.getInstance();

            long duration =(cal2.getTimeInMillis()-cal.getTimeInMillis())/1000;

            ActorRef testActorRef = getContext().actorOf(Props.create(Test.class));
            getContext().system().scheduler().scheduleOnce(Duration.create(duration, TimeUnit.SECONDS), testActorRef, messege, getContext().system().dispatcher(), null);





            share|improve this answer














            Create an actor, say Test actor and tell it from your main class and inside that actor, in on receive use below code.



            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DATE, <choose date of your choice>);
            cal.set(Calendar.MONTH, <choose month of your choice>);

            Calendar cal2 = Calendar.getInstance();

            long duration =(cal2.getTimeInMillis()-cal.getTimeInMillis())/1000;

            ActorRef testActorRef = getContext().actorOf(Props.create(Test.class));
            getContext().system().scheduler().scheduleOnce(Duration.create(duration, TimeUnit.SECONDS), testActorRef, messege, getContext().system().dispatcher(), null);






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 12 at 15:12

























            answered Aug 4 '16 at 11:46









            Amit Yadav

            371110




            371110











            • let me know if any question arise.
              – Amit Yadav
              Aug 4 '16 at 11:47











            • you set Date 1 first then added 1 month.
              – Govind Singh
              Nov 6 at 11:42










            • @GovindSingh I resolved that
              – Amit Yadav
              Nov 13 at 13:15
















            • let me know if any question arise.
              – Amit Yadav
              Aug 4 '16 at 11:47











            • you set Date 1 first then added 1 month.
              – Govind Singh
              Nov 6 at 11:42










            • @GovindSingh I resolved that
              – Amit Yadav
              Nov 13 at 13:15















            let me know if any question arise.
            – Amit Yadav
            Aug 4 '16 at 11:47





            let me know if any question arise.
            – Amit Yadav
            Aug 4 '16 at 11:47













            you set Date 1 first then added 1 month.
            – Govind Singh
            Nov 6 at 11:42




            you set Date 1 first then added 1 month.
            – Govind Singh
            Nov 6 at 11:42












            @GovindSingh I resolved that
            – Amit Yadav
            Nov 13 at 13:15




            @GovindSingh I resolved that
            – Amit Yadav
            Nov 13 at 13:15

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38763206%2fschedule-a-job-on-specific-date-in-akka-scheduler%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

            Museum of Modern and Contemporary Art of Trento and Rovereto