Руководство прикладного разработчика#

О документе#

Настоящий документ предназначен для прикладного разработчика, использующего продукт Platform V Index Search (IXS) в своем приложении.

Основные понятия#

В таблице приведены основные аббревиатуры и сокращения:

Аббревиатура, сокращение

Определение

Продукт

Platform V Index Search (IXS)

API

Application programming interface. Набор готовых классов, процедур, функций, структур и констант, предоставляемых приложением (библиотекой, сервисом)

URL

Uniform Resource Locator. Унифицированный указатель ресурса

Системные требования#

Требования к окружению для использования Продукта приведены в документе «Руководство по установке» в разделе «Системные требования».

Подключение и конфигурирование#

Интеграция с Продуктом осуществляется способом Business hub - Business hub.

Для подключения и конфигурирования необходимо:

  1. Подключить библиотеку ufs-platform-httpclient.

Подключение HttpClient:

```
<httpclient:rest-client id="indexSearchRestClient" env="platformEnvironment" serviceCode="index_search.proxy" configService="configService" rootContext="/ufs-index-search-proxy">
    <httpclient:max-total-connections valueType="SUP" value="bfs.index_search.proxy.rest.client.max.total.connections"/>
    <httpclient:max-per-route valueType="SUP" value="bfs.index_search.proxy.rest.client.max.per.route"/>
    <httpclient:time-out valueType="SUP" value="bfs.index_search.proxy.rest.client.timeout"/>
    <httpclient:connect-time-out valueType="SUP" value="bfs.index_search.proxy.rest.client.connection.timeout"/>
    <httpclient:header-server-ip valueType="SUP" value="bfs.index_search.proxy.rest.client.header.server.ip"/>
</httpclient:rest-client>
```

Подключение HttpClient-starter:

```
@UfsPlatformHttpClient(rootContext = "/ufs-index-search-proxy", serviceCode = "index_search.proxy")
public interface IndexSearchProxyClientJsonRestClient extends JsonRestClient {
}
```
  1. Сконфигурировать параметры для компонента Управление параметрами (CFGE) продукта Platform V Frontend Std.

Параметры, начиная с версии 20.1:

```
{
  "name": "ufs.baseurl.index_search.proxy",
  "description": "URL Продукта, например, <protocol>://<host>:<port>",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        "${global.platform.index.search.rest.client.base.url}"
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.time-out.request.milliseconds.index_search.proxy",
  "description": "Таймаут соединения http-client Продукта (в мс.), по умолчанию 3000, где 0 - бесконечный таймаут",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        3000
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.time-out.connection.milliseconds.index_search.proxy",
  "description": "Таймаут на установку соединения в Продукте (в мс.), по умолчанию 500, где 0 - бесконечный таймаут",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        500
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.connections.max.total.index_search.proxy",
  "description": "Максимальное число соединений в пуле http-client Продукта, по умолчанию 10",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        10
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.connections.max.per-route.index_search.proxy",
  "description": "Максимальное число соединений на URL http-client Продукта, по умолчанию = max.total.connections (10)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        10
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.headers.name.server-ip.index_search.proxy",
  "description": "Имя http-заголовка для передачи ip-адреса клиента для http-client Продукта, по умолчанию ufs-client-ip",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        "ufs-client-ip"
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.enable.index_search.proxy",
  "description": "Признак работы механизма circuit breaker. Если указано false, то http вызов происходит без декорирования механизмом circuit breaker",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "BOOLEAN",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        false
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.failureRate.threshold.percent.index_search.proxy",
  "description": "Процент отказов в потоке запросов. После превышения данного процента поток будет прерван (переход в режим OPEN)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        50
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.closed.requestBuffer.size.requestCount.index_search.proxy",
  "description": "Размер буфера запросов в режиме CLOSED (обычный режим работы потока запросов). После заполнения буфера высчитывается процент отказов для принятия решения о прерывании потока запросов (переход в режим OPEN)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        120
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.halfOpen.requestBuffer.size.requestCount.index_search.proxy",
  "description": "Размер буфера запросов в режиме HALF_OPEN. После заполнения буфера высчитывается процент отказов для принятия решения о повторном прерывании потока (переход в режим OPEN) или о переходе в обычный режим работы потока запросов (переход в режим CLOSED). Настройка объединяется с ringBufferSizeInClosedState и не доступна потребителям для изменений. Значение по умолчанию: 0 - равно буферу запросов в режиме CLOSED",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        0
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.open.duration.milliseconds.index_search.proxy",
  "description": "Время ожидания перед переходом от режима работы OPEN к HALF_OPEN",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        60000
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.record.exceptions.index_search.proxy",
  "description": "Список исключений, которые считаются ошибкой и влияют на механизм circuit breaker. По умолчанию список пуст - все полученные исключения считаются ошибкой. Пример списка исключений: java.lang.IllegalStateException; java.lang.NullPointerException",
  "isList": true,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": []
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.record.httpException.codes.index_search.proxy",
  "description": "Список http кодов для исключений, которые считаются ошибкой для механизма circuit breaker.По умолчанию список пуст - все коды в исключениях считаются ошибкой. Пример списка кодов: 429; 502",
  "isList": true,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": []
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.upperLimit.requestsPerSecond.index_search.proxy",
  "description": "Предел ограничения скорости запросов, при достижении которого, задача плавного старта завершается",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        2
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.startLimit.percent.index_search.proxy",
  "description": "Ограничение скорости запросов в момент запуска задачи плавного старта. Указывается в процентах от предела ограничения скорости запросов",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        50
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.limitChange.step.percent.index_search.proxy",
  "description": "Шаг изменения ограничения скорости запросов, в процессе работы задачи плавного старта. Указывается в процентах от предела ограничения скорости запросов",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        5
      ]
    }
  ]
}
```

Параметры, начиная с версии 20.1 (OSE):

```
{
  "name": "ufs.baseurl.index_search.proxy",
  "description": "URL сервиса Продукта, например, <protocol>://<host>:<port>",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
        {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        "${global.ose.platform.index.search.rest.client.base.url}"
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.time-out.request.milliseconds.index_search.proxy",
  "description": "Таймаут соединения http-client Продукта (в мс.), по умолчанию 3000, где 0 - бесконечный таймаут",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        3000
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.time-out.connection.milliseconds.index_search.proxy",
  "description": "Таймаут на установку соединения в Продукте (в мс.), по умолчанию 500, где 0 - бесконечный таймаут",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        500
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.connections.max.total.index_search.proxy",
  "description": "Максимальное число соединений в пуле http-client Продукта, по умолчанию 10",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        10
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.connections.max.per-route.index_search.proxy",
  "description": "Максимальное число соединений на URL http-client Продукта, по умолчанию = max.total.connections (10)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        10
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.headers.name.server-ip.index_search.proxy",
  "description": "Имя http-заголовка для передачи ip-адреса клиента для http-client Продукта, по умолчанию ufs-client-ip",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        "ufs-client-ip"
      ]
    }
  ]
},


{
  "name": "ufs.httpclient.circuitBreaker.enable.index_search.proxy",
  "description": "Признак работы механизма circuit breaker. Если указано false, то http вызов происходит без декорирования механизмом circuit breaker",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "BOOLEAN",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        false
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.failureRate.threshold.percent.index_search.proxy",
  "description": "Процент отказов в потоке запросов. После превышения данного процента поток будет прерван (переход в режим OPEN)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        50
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.closed.requestBuffer.size.requestCount.index_search.proxy",
  "description": "Размер буфера запросов в режиме CLOSED (обычный режим работы потока запросов). После заполнения буфера высчитывается процент отказов для принятия решения о прерывании потока запросов (переход в режим OPEN)",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        120
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.halfOpen.requestBuffer.size.requestCount.index_search.proxy",
  "description": "Размер буфера запросов в режиме HALF_OPEN. После заполнения буфера высчитывается процент отказов для принятия решения о повторном прерывании потока (переход в режим OPEN) или о переходе в обычный режим работы потока запросов (переход в режим CLOSED). Настройка объединяется с ringBufferSizeInClosedState и не доступна потребителям для изменений. Значение по умолчанию: 0 - равно буферу запросов в режиме CLOSED",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        0
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.open.duration.milliseconds.index_search.proxy",
  "description": "Время ожидания перед переходом от режима работы OPEN к HALF_OPEN",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        60000
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.record.exceptions.index_search.proxy",
  "description": "Список исключений, которые считаются ошибкой и влияют на механизм circuit breaker. По умолчанию список пуст - все полученные исключения считаются ошибкой. Пример списка исключений: java.lang.IllegalStateException; java.lang.NullPointerException",
  "isList": true,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": []
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.record.httpException.codes.index_search.proxy",
  "description": "Список http кодов для исключений, которые считаются ошибкой для механизма circuit breaker.По умолчанию список пуст - все коды в исключениях считаются ошибкой. Пример списка кодов: 429; 502",
  "isList": true,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "STRING",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": []
    }
  ]
},

{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.upperLimit.requestsPerSecond.index_search.proxy",
  "description": "Предел ограничения скорости запросов, при достижении которого, задача плавного старта завершается",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        2
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.startLimit.percent.index_search.proxy",
  "description": "Ограничение скорости запросов в момент запуска задачи плавного старта. Указывается в процентах от предела ограничения скорости запросов",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        50
      ]
    }
  ]
},
{
  "name": "ufs.httpclient.circuitBreaker.smoothStart.rate.limitChange.step.percent.index_search.proxy",
  "description": "Шаг изменения ограничения скорости запросов, в процессе работы задачи плавного старта. Указывается в процентах от предела ограничения скорости запросов",
  "isList": false,
  "roles": [
    "ManageParameters.ParameterRole.System"
  ],
  "type": "LONG",
  "bundle": [
    {
      "path": [
          {
          "code": "PLATFORM_RUNTIME_ENVIRONMENT",
          "value": "SAMPLE_ENVIRONMENT"
        },
        {
          "code": "SUBSYSTEM",
          "value": Ваша подсистема
        }
      ],
      "values": [
        5
      ]
    }
  ]
}
```

Рекомендуется создавать DTO самостоятельно, а не использовать библиотеку для построения запросов ElasticSearch. Если, несмотря на рекомендацию, используется данная библиотека, то должно быть выполнено условие — версия 7.8.0.

Миграция на текущую версию#

Миграция с предыдущей версии Продукта не требуется.

Разработка первого приложения с использованием программного продукта#

Необходимо подключить Продукт в соответствии с инструкцией, описанной в разделе "Подключение и конфигурирование" настоящего документа. После этого можно приступать к разработке прикладной функциональности, связанной с поисковыми задачами.

Пример использования API Продукта приведен в разделе "Использование программного продукта" настоящего документа.

Использование программного продукта#

Пример обращения к Продукту из кода приложения:

public class IndexSearchService {

    //Не забывайте указывать Qualifire так как требуется именно indexSearchRestClient httpclient
    @Qualifire("indexSearchRestClient")
    @Autowire
    private JsonRestClient client;

    //Если вы используете http client starter
    //@Autowire
    //private IndexSearchProxyClientJsonRestClient client

    private ObjectMapper mapper;


    private <T> List<T> extractEntity(JsonNode hits, Class<T> clazz) {
        final List<T> result = new ArrayList<>(hits.size());
        for (JsonNode elem : hits) {
            result.add(mapper.convertValue(elem.path("_source"), clazz));
        }
        return result;
    }


    public List<MyDomainModel> search(MyQueryRequest request) {

        JsonBodyResponse response = client.query()
                .path("rest/v1/{{Код домена данных}}/_search")
                .request(request)
                .responseClass(JsonBodyResponse.class)
                .post();


        if (response.getSuccess()) {
            return extractEntity(response.getBody().at("/hits/hits"), MyDomainModel.class);
        }

        throw new MyServiceException();
    }

    public class JsonBodyResponse extends BaseResponse<JsonNode> {

    }

}

Важно! Информация о модели данных: возможно самостоятельное создание java-классов в зависимости от потребностей.

Часто встречающиеся проблемы и пути их устранения#

Описание возможных проблем:

Проблема

Решение

Нет информации о подключении клиентского модуля продукта

Platform V Index Search (IXS) не имеет клиентского модуля. Инструкции по подключению продукта приведены в разделе "Подключение и конфигурирование" настоящего документа