Руководство прикладного разработчика#
О документе#
Настоящий документ предназначен для прикладного разработчика, использующего продукт Platform V Index Search (IXS) в своем приложении.
Основные понятия#
В таблице приведены основные аббревиатуры и сокращения:
Аббревиатура, сокращение |
Определение |
|---|---|
Продукт |
Platform V Index Search (IXS) |
API |
Application programming interface. Набор готовых классов, процедур, функций, структур и констант, предоставляемых приложением (библиотекой, сервисом) |
URL |
Uniform Resource Locator. Унифицированный указатель ресурса |
Системные требования#
Требования к окружению для использования Продукта приведены в документе «Руководство по установке» в разделе «Системные требования».
Подключение и конфигурирование#
Интеграция с Продуктом осуществляется способом Business hub - Business hub.
Для подключения и конфигурирования необходимо:
Подключить библиотеку 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 {
}
```
Сконфигурировать параметры для компонента Управление параметрами (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) не имеет клиентского модуля. Инструкции по подключению продукта приведены в разделе "Подключение и конфигурирование" настоящего документа |