@SuppressWarnings("nls")
    protected synchronized void createIndex(RestHighLevelClient client, EsIndexProperties indexDef, String indexPrefix, String indexPostfix) throws Exception {
        String indexToCreate = EsIndexMapping.getFullIndexName(indexPrefix, indexPostfix);
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexToCreate);
        String mapping;
        try {
            mapping = objectMapper.writeValueAsString(indexDef);
            // Create index using a full definition.
            createIndexRequest = createIndexRequest.mapping(mapping, XContentType.JSON);
        } catch (JsonProcessingException jpe) {
            logger.warn("The EsIndex definition provided by {0} definition cannot be marshalled", this.getClass().getCanonicalName());
            throw jpe;
        }
        try {
            CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            // When running in e.g. Wildfly, the Gateway exists as two separate WARs - the API and the
            // runtime Gateway itself.  They both create a registry and thus they both try to initialize
            // the ES index if it doesn't exist.  A race condition could result in both WARs trying to
            // create the index.  So a result of "IndexAlreadyExistsException" should be ignored.
            if (!createIndexResponse.isAcknowledged()) {
                logger.error("Failed to create ES index: '" + indexToCreate + "' Reason: request was not acknowledged.", new Exception());
            } else if (!createIndexResponse.isShardsAcknowledged()) {
                logger.error("Failed to create ES index: '" + indexToCreate + "' Reason: request was not acknowledged by shards.", new Exception());
            } else {
                logger.info("ES index created: " + indexToCreate);
                logger.debug("Creating an index => " + mapping);
            }
        } catch (ElasticsearchStatusException esse) {
            // See: https://github.com/elastic/elasticsearch/issues/19862
            if (esse.status() == RestStatus.BAD_REQUEST && (esse.getMessage().contains("index_already_exists_exception") || esse.getMessage().contains("resource_already_exists_exception"))) {
                logger.warn("Exception occurred during attempt to create index. "
                                    + "Elasticsearch does not offer create-if-not-exists for indexes, so this exception could be a race condition "
                                    + "as another node already initialised the index: {0}", esse);
                // Fall through.
            } else {
                throw esse;
            }
        }
    }
Creates an index.
@param client the elasticsearch client
@param indexDef the index definition for the component being initialised
@param indexPrefix the index prefix
@param indexPostfix the index postfix
@throws IOException if problem connecting to or interacting with ES
common/es/src/main/java/io/apiman/common/es/util/AbstractClientFactory.java