code: def run(self) -> None:
      self.validate()
  
      engine = self._properties["engine"]
      driver = self._properties.get("driver")
  
      if engine in BYPASS_VALIDATION_ENGINES:
          # Skip engines that are only validated onCreate
          return
  
      engine_spec = get_engine_spec(engine, driver)
      if not hasattr(engine_spec, "parameters_schema"):
          raise InvalidEngineError(
              SupersetError(
                  message=__(
                      'Engine "%(engine)s" cannot be configured through parameters.',
                      engine=engine,
                  ),
                  error_type=SupersetErrorType.GENERIC_DB_ENGINE_ERROR,
                  level=ErrorLevel.ERROR,
              ),
          )
  
      # perform initial validation
      errors = engine_spec.validate_parameters(self._properties)  # type: ignore
      if errors:
          event_logger.log_with_context(
              action="validation_error", engine=engine
          )
          raise InvalidParametersError(errors)
  
      serialized_encrypted_extra = self._properties.get(
          "masked_encrypted_extra",
          "{}",
      )
      if self._model:
          serialized_encrypted_extra = (
              engine_spec.unmask_encrypted_extra(
                  self._model.encrypted_extra,
                  serialized_encrypted_extra,
              )
          )
      try:
          encrypted_extra = json.loads(serialized_encrypted_extra)
      except json.decoder.JSONDecodeError:
          encrypted_extra = {}
  
      # try to connect
      sqlalchemy_uri = engine_spec.build_sqlalchemy_uri(  # type: ignore
          self._properties.get("parameters"),
          encrypted_extra,
      )
      if (
          self._model
          and sqlalchemy_uri == self._model.safe_sqlalchemy_uri()
      ):
          sqlalchemy_uri = self._model.sqlalchemy_uri_decrypted
      database = DatabaseDAO.build_db_for_connection_test(
          server_cert=self._properties.get("server_cert", ""),
          extra=self._properties.get("extra", "{}"),
          impersonate_user=self._properties.get(
              "impersonate_user", False
          ),
          encrypted_extra=serialized_encrypted_extra,
      )
      database.set_sqlalchemy_uri(sqlalchemy_uri)
      database.db_engine_spec.mutate_db_for_connection_test(database)
  
      alive = False
      with database.get_sqla_engine_with_context() as engine:
          try:
              with closing(engine.raw_connection()) as conn:
                  alive = engine.dialect.do_ping(conn)
          except Exception as ex:
              url = make_url_safe(sqlalchemy_uri)
              context = {
                  "hostname": url.host,
                  "password": url.password,
                  "port": url.port,
                  "username": url.username,
                  "database": url.database,
              }
              errors = database.db_engine_spec.extract_errors(
                  ex, context
              )
              raise DatabaseTestConnectionFailedError(errors) from ex
  
      if not alive:
          raise DatabaseOfflineError(
              SupersetError(
                  message=__("Database is offline."),
                  error_type=SupersetErrorType.GENERIC_DB_ENGINE_ERROR,
                  level=ErrorLevel.ERROR,
              ),
          )
  
file_path: superset/superset/commands/database/validate.py
imports: import json
  from contextlib import closing
  from typing import Any, Optional
  from flask_babel import gettext
  from superset.commands.base import BaseCommand
  from superset.commands.database.exceptions import DatabaseOfflineError, DatabaseTestConnectionFailedError, InvalidEngineError, InvalidParametersError
  from superset.daos.database import DatabaseDAO
  from superset.databases.utils import make_url_safe
  from superset.db_engine_specs import get_engine_spec
  from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
  from superset.extensions import event_logger
  from superset.models.core import Database
label_desc: Use image node_id 2 for calling the ValidateDatabaseParametersCommand obj's underlying member method code with example usage: obj.run() without return types