def perform
        begin
          required_options :service_id, :snapshot_id
          @name = options["service_id"]
          @snapshot_id = options["snapshot_id"]
          @logger.info("Launch job: #{self.class} for #{name}")

          lock = create_lock

          @snapshot_files = []
          lock.lock do
            # extract origin files from package
            dump_path = get_dump_path(name, snapshot_id)
            package_file = "#{snapshot_id}.zip"
            package = Package.load(File.join(dump_path, package_file))
            @manifest = package.manifest
            @snapshot_files = package.unpack(dump_path)
            @logger.debug("Unpack files from #{package_file}: #{@snapshot_files}")
            raise "Package file doesn't contain snapshot file." if @snapshot_files.empty?

            result = execute
            @logger.info("Results of rollback snapshot: #{result}")

            completed(Yajl::Encoder.encode({:result => :ok}))
            @logger.info("Complete job: #{self.class} for #{name}")
          end
        rescue => e
          handle_error(e)
        ensure
          set_status({:complete_time => Time.now.to_s})
          @snapshot_files.each{|f| File.delete(f) if File.exists? f} if @snapshot_files
        end
      end
def perform
        begin
          required_options :service_id, :snapshot_id
          @name = options["service_id"]
          @snapshot_id = options["snapshot_id"]
          @logger.info("Launch job: #{self.class} for #{name}")

          lock = create_lock

          @snapshot_files = []
          lock.lock do
            # extract origin files from package
            dump_path = get_dump_path(name, snapshot_id)
            package_file = "#{snapshot_id}.zip"
            package = Package.load(File.join(dump_path, package_file))
            @manifest = package.manifest
            @snapshot_files = package.unpack(dump_path)
            @logger.debug("Unpack files from #{package_file}: #{@snapshot_files}")
            raise "Package file doesn't contain snapshot file." if @snapshot_files.empty?

            result = execute
            @logger.info("Results of rollback snapshot: #{result}")

            completed(Yajl::Encoder.encode({:result => :ok}))
            @logger.info("Complete job: #{self.class} for #{name}")
          end
        rescue => e
          handle_error(e)
        ensure
          set_status({:complete_time => Time.now.to_s})
          @snapshot_files.each{|f| File.delete(f) if File.exists? f} if @snapshot_files
        end
      end
workflow template
 Subclass implement execute method which returns true for a successful rollback