Announcement Announcement Module
Collapse
No announcement yet.
Changing the file name after the step completes Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Changing the file name after the step completes

    Hi,

    we configured one step inside a job to read from a file and upload the items to a database. After the step is complete we want to change the file name.

    If for some reason the name change fails the steps must not to be marked as completed so the change will be tried later.

    The idea was to extend the class StepExecutionResourceProxy implementing the afterStep method and changing the file name there:

    public ExitStatus afterStep(StepExecution stepExecution) {

    final String oldFilename = getFilename();

    ExitStatus exitStatus = stepExecution.getExitStatus();

    if (!ExitStatus.FAILED.equals(exitStatus)) {

    try {

    boolean success =
    getFile().renameTo(
    new File(oldFilename.concat(".parsed")));
    if (!success) {
    if (logger.isErrorEnabled()) {
    logger.error("It was not possible to rename the file:"
    + oldFilename + ". The reason is unknown.");
    }

    stepExecution.setStatus(BatchStatus.FAILED);
    return ExitStatus.FAILED;
    }
    } catch (IOException e) {
    if (logger.isErrorEnabled()) {
    logger.error("It was not possible to rename the file:"
    + oldFilename + " for an input/output exception: "
    + e.getMessage());
    }
    stepExecution.setStatus(BatchStatus.FAILED);
    return ExitStatus.FAILED;
    }
    }

    // If the renaming goes well then we can return the exit status of the
    // current context.
    return stepExecution.getExitStatus();
    }

    and the listener is correctly added to the job. But what happen is that the status is set to COMPLETE then preventing the job to run again without an exception.

    Have you any suggestion?

    Is better to add another tasklet to the job for changing the file name? Someone has any example for that?


    Thanks in advance,
    Vicio.
    Last edited by vincenzo.vitale; Apr 15th, 2008, 09:56 PM.

  • #2
    Update: the main problem should be related to this http://jira.springframework.org/browse/BATCH-532

    BTW, do you think it's better to configure a tasklet?

    When 1.0.1 will be officially release? There are delays?

    Comment


    • #3
      I think I would use another TaskletStep for the rename. It would certainly make restart a lot more understandable, since the step that generated the file would be skipped if it had completed successfully. You also wouldn't have to worry about BATCH-532.

      There isn't really any delay in releasing 1.0.1. The final 1.0 release was only made a little more than two weeks ago. We wanted to give the community ample time to help to identify bugs, etc. In Jira its official release date is April 25th. I think we'll stick to that date, barring any unforeseen issues.

      Comment


      • #4
        Hi Lucas,

        thanks for your answer.

        I think I will follow your suggestion using a tasklet for changing the filename. Thanks also for confirming the date.


        Bye,
        Vicio.


        P.s.: Spring Batch rocks!!! :-)

        Comment


        • #5
          It worked really fine writing a tasklet.

          So now if just the file renaming fails it will be done again when the job is called again with the same parameter (the file name).

          Why not implementing a DefaultFileRenameTaskLet (or something like that). This is my code:

          /**
          * A {@link Tasklet} object to change the name of a file adding a suffix.
          *
          * @author Vincenzo Vitale (vita)
          *
          */
          public class ChangeSearchLogFileName implements Tasklet {

          private static Log logger =
          LogFactory.getLog(ChangeSearchLogFileName.class);

          private Resource resource;

          private String parsedSuffix;

          /*
          * (non-Javadoc)
          *
          * @see org.springframework.batch.core.step.tasklet.Taskle t#execute()
          */
          public ExitStatus execute() throws Exception {

          final File file = resource.getFile();
          final String oldFilePath = file.getAbsolutePath();
          final String newFilePath = oldFilePath.concat(parsedSuffix);

          if (logger.isInfoEnabled()) {
          logger.info("Moving the file: " + oldFilePath + " to "
          + newFilePath);
          }

          boolean success = file.renameTo(new File(newFilePath));
          if (!success) {
          if (logger.isErrorEnabled()) {
          logger.error("It was not possible to rename the file:"
          + oldFilePath + ". The reason is unknown.");
          }

          throw new JobInterruptedException(
          "It was not possible to rename the file:" + oldFilePath
          + ". The reason is unknown.");
          }

          // If the renaming goes well then we can return the exit status of the
          // current context.
          return ExitStatus.FINISHED;

          }

          /**
          * @param parsedSuffix the parsedSuffix to set
          */
          public void setParsedSuffix(String parsedSuffix) {
          this.parsedSuffix = parsedSuffix;
          }

          /**
          * @param resource the resource to set
          */
          public void setResource(Resource resource) {
          this.resource = resource;
          }

          }

          and in Spring:

          <!-- Tasklet step to change the filename -->
          <bean id="changeLocalSearchLogFileNameStep"
          class="org.springframework.batch.core.step.tasklet .TaskletStep">
          <property name="tasklet" ref="changeLocalSearchLogFileName" />
          <property name="jobRepository" ref="jobRepository" />
          <property name="stepListeners">
          <list>
          <ref bean="localSearchLogInputFile" />
          </list>
          </property>
          </bean>

          <bean id="detailsSearchLogInputFile"
          class="org.springframework.batch.core.resource.Ste pExecutionResourceProxy">
          <property name="filePattern"
          value="%detailsSearchLog.file.name%" />
          </bean>


          If useful I can provide a patch for the Spring Batch trunk providing this implementation.


          Really thanks for your help,
          Vicio.

          Comment


          • #6
            It is currently a bit cumbersome to accept contributions, as the framework distribution should contain just essential things.

            There is an idea to have a separate 'Spring Batch Components' (or whatever) project to house useful Tasklets, ItemTransfromers, more exotic ItemReaders and ItemWriters etc. however there is no concrete schedule when that should happen. The FileRenamingTasklet would fit nicely there - hopefully there will be more similar contributions and the project will be born.

            Meanwhile feel free to open a "new feature" jira issue and attach the code there - if so don't forget to include tests as well
            Last edited by robert.kasanicky; Apr 16th, 2008, 10:01 AM.

            Comment


            • #7
              Cool.


              Ciao,
              V.

              Comment


              • #8
                I also saw that you threw a JobInterruptedException if the renaming fails, you might think about using another exception type, as this exception generally means that someone interrupted an otherwise normal execution, rather than it simply failing. Not a big deal, since either way it gets the job to fail, but something to think about it.

                Comment


                • #9
                  Thanks for the suggestion.

                  I created for a FileRenameException extending RuntimeException.

                  And I also attached the new listener:

                  /**
                  * Base listener for step error handling.
                  *
                  * @author Vincenzo Vitale (vita)
                  *
                  */
                  public class DefaultStepErrorListener extends StepExecutionListenerSupport {

                  /*
                  * (non-Javadoc)
                  *
                  * @see org.springframework.batch.core.listener.StepExecut ionListenerSupport#onErrorInStep(org.springframewo rk.batch.core.StepExecution,
                  * java.lang.Throwable)
                  */
                  @Override
                  public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
                  ExitStatus exitStatus =
                  new ExitStatus(false, ExitStatus.FAILED.getExitCode(), e
                  .getMessage());

                  return exitStatus;
                  }

                  }

                  in order to add the problem occurred in the database description column. BTW I think the description should be added automatically when throwing a Runtime exception, but it isn't.

                  Comment

                  Working...
                  X