class_docstr: Base class for all app integrations to be implemented for various services
docstr: Method for performing any final steps, like saving applicable state
  
  This function is also used to invoke a new copy of this lambda in the case
  that there are more logs available to collect.
docstr_tok: ["Method","for","performing","any","final","steps",",","like","saving","applicable","state","This","function","is","also","used","to","invoke","a","new","copy","of","this","lambda","in","the","case","that","there","are","more","logs","available","to","collect","."]
code: def _finalize(self):
      """Method for performing any final steps, like saving applicable state
  
      This function is also used to invoke a new copy of this lambda in the case
      that there are more logs available to collect.
      """
      if not self._last_timestamp:
          LOGGER.error(
              "Ending last timestamp is 0. This should not happen and is likely "
              "due to the subclass not setting this value."
          )
  
      if self._last_timestamp == self._config.start_last_timestamp:
          LOGGER.info(
              "Ending last timestamp is the same as the beginning last timestamp. "
              "This could occur if there were no logs collected for this execution."
          )
  
      LOGGER.info(
          "[%s] App complete; gathered %d logs in %d polls.",
          self,
          self._gathered_log_count,
          self._poll_count,
      )
  
      self._config.last_timestamp = self._last_timestamp
      self._config.context = self._context
  
      # If there are more logs to poll, invoke this app function again and mark
      # the config as 'partial'. Marking the state as 'partial' prevents
      # scheduled function invocations from running alongside chained invocations.
      if self._more_to_poll:
          self._config.mark_partial()
          self._invoke_successive_app()
          return
  
      self._config.mark_success()
  
imports: from abc import ABCMeta, abstractmethod, abstractproperty
  from json import JSONDecodeError
  import time
  import boto3
  from botocore.exceptions import ClientError
  import requests
  from streamalert.apps.config import AppConfig
  from streamalert.apps.batcher import Batcher
  from streamalert.shared.logger import get_logger
label_desc: Use image node_id 13 for calling the AppIntegration obj's underlying member method code with example usage: obj._finalize() without return types