2. Конфигурация Агента проверок (application.yml)

Файл application.yml – основной конфигурационный файл Агента проверок, в котором задана логика и порядок работы модуля:

2.1. Пример файла application.yml

В конфигурационном файле следует задавать только те настройки, которые необходимы для решения текущих бизнес-задач.

spring:
  main:
    banner-mode: off
    web-application-type: none
  task:
    scheduling:
      pool:
        size: 5
  profiles:
    # В профилях указывается какой функционал необходим (dqf- проверки качества, std - стандартизация)
    active: ${PROFILES_ACTIVE:dqf}
  liquibase:
    enabled: true
    analytics-enabled: false
    contexts: ${spring.profiles.active}
    change-log: classpath:/liquibase-changes/changelog.xml
    driver-class-name: ru.datamart.prostore.jdbc.Driver
    url: ${adapter.prostore.jdbc.prostoreUrl}
    liquibase-schema: ${dqf.schema}
    default-schema: ${dqf.schema}
    database-change-log-table: check_adapter_changelog
    database-change-log-lock-table: check_adapter_changeloglock

http-server:
  port: ${HTTP_PORT:3010}

adapter:
  # Отправку в мониторинг можно выключить
  useMonitoring: ${USE_MONITORING:false}
  adapterNg:
    http:
      url: http://10.81.7.90:28358/
      useAdapter: ${USE_NG_ADAPTER:true}
  podd:
    http:
      url: http://158.160.13.119:8172/
  prostore:
    jdbc:
      prostoreUrl: ${PROSTORE_JDBC_URL:jdbc:prostore://localhost:9191/}
      driverClassName: ${PROSTORE_JDBC_DRIVER_CLASS:ru.datamart.prostore.jdbc.Driver}
    http:
      prostoreUrl: ${PROSTORE_HTTP_URL:http://localhost:9191/}
      maxConnections: ${PROSTORE_MAX_CONNECTIONS:1000}
      maxConnectionsPerHost: ${PROSTORE_MAX_CONNECTIONS_PER_HOST:1000}
      #      Количество записей получаемых для отправки в топик input
      fetchSize: ${PROSTORE_FETCH_SIZE:10000}
      #     Буферизация данных в памяти для кодеков webclient
      maxInMemorySize: ${PROSTORE_MAX_IN_MEMORY_SIZE:64MB}
      #     Количество потоков трансфорирующих данные до покладки в input топик
      concurrency: ${PROSTORE_THREAD_COUNT:16}
  webclient:
    input:
      connProvider:
        # Максимальное число одновременно открытых соединений в пуле.
        maxConnections: ${ADAPTER_QUALITY_RECORD_INPUT_MAX_CONNECTIONS:1000}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_INPUT_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_INPUT_MAX_DELAY_MS:5000}
    output:
      connProvider:
        # Максимальное число одновременно открытых соединений в пуле.
        maxConnections: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_CONNECTIONS:1000}
        # Максимальное время ожидания без активности для одного соединения
        maxIdleTime: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_IDLE_TIME:60}
        # Общее время жизни соединения от момента его создания
        maxLifeTime: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_LIFE_TIME:120}
        # Интервал, с каким фоновой задачей будет выполняться проверка и удаления "протухших" (idle/expired) соединений
        evictInBackground: ${ADAPTER_QUALITY_RECORD_OUTPUT_EVICT_IN_BACKGROUND:30}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_OUTPUT_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_DELAY_MS:5000}
    execAlg:
      connProvider:
        # Максимальное число одновременно открытых соединений в пуле.
        maxConnections: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_CONNECTIONS:1000}
        # Максимальное время ожидания без активности для одного соединения
        maxIdleTime: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_IDLE_TIME:60}
        # Общее время жизни соединения от момента его создания
        maxLifeTime: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_LIFE_TIME:120}
        # Интервал, с каким фоновой задачей будет выполняться проверка и удаления "протухших" (idle/expired) соединений
        evictInBackground: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_EVICT_IN_BACKGROUND:30}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_DELAY_MS:5000}

prostore-rest-client:
  host: localhost
  port: 9191

dtm-config:
  eduejd01:
    sql-request-priority:

dqf:
  quality:
    bufferSize: 10000
    capacity:
      incomeQueue: ${DQF_QUALITY_CAPACITY_INCOME_QUEUE:10000}
      outcomeQueue: ${DQF_QUALITY_CAPACITY_OUTCOME_QUEUE:10000}
    threads:
      consumerAsyncThreads: ${DQF_QUALITY_CONSUMER_ASYNC_THREADS:1}
  # Явное указание схемы для dqf
  schema: ${DQF_SCHEMA:reg_datamart_dqf}
  # Список datasource Prostore, в которых необходимо создавать snapshot таблицы
  data-sources: ${DQF_DATA_SOURCES:}
  deleteOldErrorsCron: '0 0 1 * * *'
  retry:
    times: 0
    initialDelay: 1s
    maxDelay: 5s

nsud:
  #  Задача получения от НСУД списка проверок
  nsudCron: '0 */5 * * * *'
  nsudUrlList: ${NSUD_URL_LIST:https://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_versions}
  nsudUrlAck: ${NSUD_URL_ACK:https://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_versions/activations}
  ddl:
    # Режим получения DDL: HTTP - http-запросом в ЕИП НСУД / FILE - из файла в локальной ФС
    mode: FILE
    # Адрес ЕИП НСУД для получения DDL
    url: ${NSUD_URL_DDL:http://<хост>:<порт>/<basePath>/ddl}
    # Параметры повторного выполнения запроса при получении ошибки
    retry:
      times: 3
      delay: 3s
  requestTimeout: 1m
  useHash: ${NSUD_USE_HASH:true}
  ackNew: ${NSUD_ACK_NEW:true}
  pebble:
    interval: ${NSUD_PEBBLE_INTERVAL:PT30s}
    idleDelay: ${NSUD_PEBBLE_IDLE_DELAY:PT1m}
    pebbleRefresh: ${NSUD_PEBBLE_REFRESH:PT5m}
  # Необходимо указать список датамартов по которым требуется получать список проверок
  datamarts:
    - eduejd01

agg:
  #  Задача по агрегации данных, сохранение в таблицу aggregation и последующая отправка по REST
  aggCron: '0 0 0 31 2 *'
  aggArmDsCron: '0 0 0 31 2 *'
  aggUrl: ${AGGREGATION_URL:http://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_reports}
  aggArmDsStatUrl: http://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/data_mart_check_adapter_stats/
  entriesLimit: 100

execution-log:
  view:
    # Имя view, создаваемой в прикладных схемах
    view-name: dqf_check_log
    # Запускать миграцию по созданию view при каждом старте приложения
    recreate-on-startup: false

metrics:
  port: ${METRICS_PORT:9837}

3. Параметры конфигурации

Настройка конфигурации Агента проверок осуществляется путем редактирования параметров настроек в файле application.yml, где настраиваются секции:

  • spring – настройка Spring Boot и профиля работы приложения;

  • http-server – настройка использования альтернативного значения серверного порта;

  • adapter – настройка параметров вызова внешних сервисов;

  • prostore-rest-client - настройки подключения к REST-клиенту Prostore;

  • dtm-config - конфигурация витрин;

  • dqf – настройка параметров проверок качества;

  • nsud – настройка взаимодействия с ЕИП НСУД;

  • agg – настройка плана выполнения агрегаций;

  • execution-log – настройки представлений журнала выполнения проверок для DQF;

  • metrics - настройки параметров метрик.

3.1. Секция spring

В секции spring хранятся настройки Spring Boot и профиля работы приложения.

Например:

spring:
  main:
    banner-mode: off
    web-application-type: none
  task:
    scheduling:
      pool:
        size: 5
  profiles:
    # В профилях указывается какой функционал необходим (dqf- проверки качества, std - стандартизация)
    active: ${PROFILES_ACTIVE:dqf}
  liquibase:
    enabled: true
    analytics-enabled: false
    contexts: ${spring.profiles.active}
    change-log: classpath:/liquibase-changes/changelog.xml
    driver-class-name: ru.datamart.prostore.jdbc.Driver
    url: ${adapter.prostore.jdbc.prostoreUrl}
    liquibase-schema: ${dqf.schema}
    default-schema: ${dqf.schema}
    database-change-log-table: check_adapter_changelog
    database-change-log-lock-table: check_adapter_changeloglock

Параметры настроек

  • task.scheduling.pool.size - размер пула планировщика задач Spring;

  • profiles.active - активные профили приложения. Для задачи проверки качества данных используется профиль dqf, для задач по стандартизации - std;

  • enabled - признак включения/отключения миграций;

  • analytics-enabled - флаг подключения статистики;

  • contexts - наименование профилей запуска чек адаптера. Допустимые значения: std, dqf. При использовании нескольких профилей, перечисление осуществляется через запятую;

  • change-log - путь к файлам миграций, которые находятся внутри jar;

  • driver-class-name - имя JDBC-драйвера Prostore. Константа, без переопределения.

  • url - адрес подключения к Prostore в формате JDBC. Переопределять не потребуется, конструируется из параметров подключения к Prostore;

  • liquibase-schema - имя датамарта, в котором будут созданы служебные таблицы liquibase;

  • database-change-log-table - имя таблицы хранения истории выполненных миграций;

  • database-change-log-lock-table - имя таблицы для блокировок, константа.

3.2. Секция http-server

В секции http-server хранятся настройки использования альтернативного значения серверного порта.

Существует два варианта изменения дефолтного значения номера порта:

  1. Значение может быть передано через переменную окружения HTTP_PORT. В случае запуска приложения с помощью systemd переменную необходимо передать через указание Environment="HTTP_PORT=3010" в .service-файле.

В случае прямого запуска, переменная должна быть задана на уровне ОС на момент запуска приложения.

  1. Возможно указать в конфигурационном файле следующую настройку:

http-server:
  port: ${HTTP_PORT:3010}

Параметры настроек

  • port - порт сервера, значение может быть изменено на нужное.

3.3. Секция adapter

В секции adapter хранятся настройки параметров вызова внешних сервисов.

Например:

adapter:
  # Отправку в мониторинг можно выключить
  useMonitoring: ${USE_MONITORING:false}
  adapterNg:
    http:
      url: http://10.81.7.90:28358/
      useAdapter: ${USE_NG_ADAPTER:true}
  podd:
    http:
      url: http://158.160.13.119:8172/
  prostore:
    jdbc:
      prostoreUrl: ${PROSTORE_JDBC_URL:jdbc:prostore://localhost:9191/}
      driverClassName: ${PROSTORE_JDBC_DRIVER_CLASS:ru.datamart.prostore.jdbc.Driver}
    http:
      prostoreUrl: ${PROSTORE_HTTP_URL:http://localhost:9191/}
      maxConnections: ${PROSTORE_MAX_CONNECTIONS:1000}
      maxConnectionsPerHost: ${PROSTORE_MAX_CONNECTIONS_PER_HOST:1000}
      fetchSize: ${PROSTORE_FETCH_SIZE:10000}
      maxInMemorySize: ${PROSTORE_MAX_IN_MEMORY_SIZE:64MB}
      concurrency: ${PROSTORE_THREAD_COUNT:16}
  webclient:
    input:
      connProvider:
        maxConnections: ${ADAPTER_QUALITY_RECORD_INPUT_MAX_CONNECTIONS:1000}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_INPUT_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_INPUT_MAX_DELAY_MS:5000}
    output:
      connProvider:
        maxConnections: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_CONNECTIONS:1000}
        maxIdleTime: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_IDLE_TIME:60}
        maxLifeTime: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_LIFE_TIME:120}
        evictInBackground: ${ADAPTER_QUALITY_RECORD_OUTPUT_EVICT_IN_BACKGROUND:30}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_OUTPUT_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_OUTPUT_MAX_DELAY_MS:5000}
    execAlg:
      connProvider:
        maxConnections: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_CONNECTIONS:1000}
        maxIdleTime: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_IDLE_TIME:60}
        maxLifeTime: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_LIFE_TIME:120}
        evictInBackground: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_EVICT_IN_BACKGROUND:30}
      retry:
        initialDelayMs: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_INITIAL_DELAY_MS:1000}
        maxDelayMs: ${ADAPTER_QUALITY_RECORD_EXEC_ALG_MAX_DELAY_MS:5000}

Параметры настроек

  • adapter.useMonitoring - подключение мониторинга;

  • adapterNg.http.url - URL сервиса ИУА;

  • adapterNg.http.useAdapter - используется ли ИУА для взаимодействия со СМЭВ 3;

  • podd.http.url - URL сервиса Агент СМЭВ 4, необходимо указывать порт для взаимодействия именно через Rest-api (по умолчанию в Агенте СМЭВ 4 8172);

  • prostore.jdbc.* - JDBC-параметры подключения к Prostore;

  • prostore.http.* - HTTP-параметры подключения к Prostore;

  • fetchSize - количество записей, получаемых при поточной выборке из компонента Prostore;

  • pormaxInMemorySize - буферизация данных в памяти для кодеков webclient;

  • concurrency - количество потоков трансформирующих данные, после извлечения;

  • webclient.input.connProvider.maxConnections - максимальное число одновременно открытых соединений в пуле;

  • webclient.input.retry.initialDelayMs - начальное время паузы перед выполнением новой попытки вызова при получении ошибки;

  • webclient.input.retry.maxDelayMs - конечное время паузы перед выполнением новой попытки вызова при получении ошибки;

  • webclient.output.connProvider.maxIdleTime - максимальное время ожидания без активности для одного соединения;

  • webclient.output.connProvider.maxLifeTime - общее время жизни соединения от момента его создания;

  • webclient.output.connProvider.evictInBackground - интервал, с которым фоновой задачей будет выполняться проверка и удаления истекших (idle/expired) соединений;

  • webclient.output.retry.initialDelayMs - начальное время паузы перед выполнением новой попытки вызова при получении ошибки;

  • webclient.output.retry.maxDelayMs - конечное время паузы перед выполнением новой попытки вызова при получении ошибки;

  • webclient.execAlg.connProvider.maxConnections - максимальное число одновременно открытых соединений в пуле;

  • webclient.execAlg.connProvider.maxIdleTime - максимальное время ожидания без активности для одного соединения;

  • webclient.execAlg.connProvider.maxLifeTime - общее время жизни соединения от момента его создания;

  • webclient.execAlg.connProvider.evictInBackground - интервал, с которым фоновой задачей будет выполняться проверка и удаления истекших (idle/expired) соединений;

  • webclient. execAlg.retry.initialDelayMs - начальное время паузы перед выполнением новой попытки вызова при получении ошибки;

  • webclient.execAlg.retry.maxDelayMs - конечное время паузы перед выполнением новой попытки вызова при получении ошибки.

3.4. Секция prostore-rest-client

В секции prostore-rest-client хранятся настройки подключения к REST-клиенту Prostore.

Например:

prostore-rest-client:
  host: localhost
  port: 9191

Параметры настроек

  • host - адрес хоста подключения;

  • port - порт подключения.

3.5. Секция dtm-config

В секции dtm-config указывается тег балансировки в конфигурации витрин.

Например:

dtm-config:
  eduejd01:
    sql-request-priority:

Параметры настроек

  • sql-request-priority - тег балансировки.

3.6. Секция dqf

В секции dqf хранятся настройки параметров проверок качества.

Например:

dqf:
  quality:
    bufferSize: 10000
    capacity:
      incomeQueue: ${DQF_QUALITY_CAPACITY_INCOME_QUEUE:10000}
      outcomeQueue: ${DQF_QUALITY_CAPACITY_OUTCOME_QUEUE:10000}
    threads:
      consumerAsyncThreads: ${DQF_QUALITY_CONSUMER_ASYNC_THREADS:1}
  schema: ${DQF_SCHEMA:reg_datamart_dqf}
  data-sources: ${DQF_DATA_SOURCES:}
  deleteOldErrorsCron: '0 0 1 * * *'
  retry:
    times: 0
    initialDelay: 1s
    maxDelay: 5s

Параметры настроек

  • bufferSize - размер внутреннего пакета обработки;

  • incomeQueue - размер внутренней очереди извлечения данных;

  • outcomeQueue - размер очереди на отправку в ПО Prostore;

  • recordThreads - количество тредов на получение списка идентификаторов;

  • checkThreads - количество тредов на проверку полученных данных;

  • consumerAsyncThreads - количество тредов на извлечение данных из внутренней очереди;

  • schema - наименование служебной схемы (формируется по шаблону: {имя_основной_схемы}_dqf);

  • data-sources - список датасорсов Prostore, в которых необходимо создавать snapshot таблицы;

  • deleteOldErrorsCron - периодичность удаления старых ошибок;

  • retry - настройки повторных попыток.

3.7. Секция nsud

В секции nsud хранятся настройки взаимодействия с ЕИП НСУД.

Например:

nsud:
  #  Задача получения от НСУД списка проверок
  nsudCron: '0 */5 * * * *'
  nsudUrlList: ${NSUD_URL_LIST:https://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_versions}
  nsudUrlAck: ${NSUD_URL_ACK:https://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_versions/activations}
  ddl:
    mode: FILE
    url: ${NSUD_URL_DDL:http://<хост>:<порт>/<basePath>/ddl}
    retry:
      times: 3
      delay: 3s
  requestTimeout: 1m
  useHash: ${NSUD_USE_HASH:true}
  ackNew: ${NSUD_ACK_NEW:true}
  pebble:
    interval: ${NSUD_PEBBLE_INTERVAL:PT30s}
    idleDelay: ${NSUD_PEBBLE_IDLE_DELAY:PT1m}
    pebbleRefresh: ${NSUD_PEBBLE_REFRESH:PT5m}
  datamarts:
    - eduejd01

Параметры настроек

  • nsudCron - периодичность получения списка проверок;

  • nsudUrlList - адрес для получения списка проверок качества данных, где <хост> - хост агента-потребителя «своей» ИС, подключённой к СМЭВ4, <порт> - ApiGw порт агента-потребителя (необходимо указывать порт для взаимодействия именно через REST API (по умолчанию в Агенте СМЭВ 4 8172));

  • nsudUrlAck - адрес подтверждения применения проверок качества данных, где <хост> - хост агента-потребителя «своей» ИС, подключённой к СМЭВ4, <порт> - ApiGw порт агента-потребителя (необходимо указывать порт для взаимодействия именно через REST API (по умолчанию в Агенте СМЭВ 4 8172));

  • ddl - настройки получения DDL:

    • mode - режим получения DDL: HTTP - HTTP-запросом в ЕИП НСУД или FILE - из файла в локальной ФС;

    • url - адрес ЕИП НСУД для получения DDL, при выборе режима HTTP;

    • retry - параметры повторного выполнения запроса при получении ошибки;

  • useHash - включение/отключение обработки проверок от ЕИП в случае изменений по сравнению с предыдущим запросом;

  • ackNew - включение/отключение отправки подтверждения новых или изменившихся проверок в ЕИП;

  • datamarts - список датамартов по которым требуется получать список проверок.

3.8. Секция agg

В секции agg хранятся настройки плана выполнения агрегаций.

Например:

agg:
  #  Задача по агрегации данных, сохранение в таблицу aggregation и последующая отправка по REST
  aggCron: '0 0 0 31 2 *'
  aggArmDsCron: '0 0 0 31 2 *'
  aggUrl: ${AGGREGATION_URL:http://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/dqf_check_reports}
  aggArmDsStatUrl: http://<хост>:<порт>/<мнемоника ЕИП>/<basePath>/data_mart_check_adapter_stats/
  entriesLimit: 100

Параметры настроек

  • aggCron - периодичность запуска подсчета агрегированной статистики для передачи в ЕИП НСУД (рекомендуется устанавливать 1 раз в день);

  • aggArmDsCron - периодичность запуска подсчета агрегированной статистики для отображений виджета ТПО УД (рекомендуется устанавливать 1 раз в день);

  • aggUrl - адрес отправки агрегированной статистики в ЕИП НСУД, где <хост> - хост агента-потребителя «своей» ИС, подключённой к СМЭВ4, <порт> - ApiGw порт агента-потребителя (необходимо указывать порт для взаимодействия именно через REST API (по умолчанию в Агенте СМЭВ 4 8172));

  • aggArmDsStatUrl - адрес отправки агрегированной статистики в разрезе таблиц в ЕИП НСУД, где <хост> - хост агента-потребителя «своей» ИС, подключённой к СМЭВ4, <порт> - ApiGw порт агента-потребителя (необходимо указывать порт для взаимодействия именно через Rest-api (по умолчанию в Агенте СМЭВ 4 8172)).

3.9. Секция execution-log

В секции execution-log хранятся настройки представлений журнала выполнения проверок для DQF.

Например:

execution-log:
  view:
    # Имя view, создаваемой в прикладных схемах
    view-name: dqf_check_log
    # Запускать миграцию по созданию view при каждом старте приложения
    recreate-on-startup: false

Параметры настроек

  • view-name - имя представления (view), создаваемого в каждой прикладной витрине;

  • recreate-on-startup - флаг пересоздания view при каждом старте приложения. Включается, если view была удалена или в список витрин добавлена новая.

3.10. Секция metrics

Секция metrics предназначена для настройки параметров метрик.

Например:

metrics:
  port: ${METRICS_PORT:9837}

Параметры конфигурации

  • port - порт для метрик, например METRICS_PORT:9837.

4. Конфигурационный файл с описанием проверяемой схемы

Агенту проверок, для построения внутренней модели со связями таблиц, необходим файл с описанием проверяемой схемы и связей таблиц внутри этой схемы в формате, приведенном ниже:

CREATE TABLE vehicle.owners (
  id            UUID        NOT NULL,
  name          VARCHAR(255) NOT NULL,
  birthdate     DATE         NULL,
  PRIMARY KEY (id)
);

CREATE TABLE vehicle.cars (
  id            UUID        NOT NULL,
  owner_id      UUID        NOT NULL,
  model         VARCHAR(255) NOT NULL,
  manufacture_year INTEGER    NULL,
  PRIMARY KEY (id)
);

CREATE TABLE vehicle.repairs (
  id            UUID        NOT NULL,
  car_id        UUID        NOT NULL,
  owner_id      UUID        NOT NULL,
  repair_date   DATE        NOT NULL,
  description   TEXT        NULL,
  PRIMARY KEY (id)
);

-- Foreign key constraints
ALTER TABLE vehicle.cars
  ADD CONSTRAINT fk_cars_owner
    FOREIGN KEY (owner_id)
    REFERENCES vehicle.owners(id);

ALTER TABLE vehicle.repairs
  ADD CONSTRAINT fk_repairs_car
    FOREIGN KEY (car_id)
    REFERENCES vehicle.cars(id);

ALTER TABLE vehicle.repairs
  ADD CONSTRAINT fk_repairs_owner
    FOREIGN KEY (owner_id)
    REFERENCES vehicle.owners(id);

Имя файла необходимо формировать по формату {имя проверяемой схемы}.sql в данном случае vehicle.sql.