Java tutorial
/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fujitsu.dc.common.es.impl; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.CharEncoding; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.indices.IndexAlreadyExistsException; import org.elasticsearch.indices.IndexMissingException; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fujitsu.dc.common.es.EsBulkRequest; import com.fujitsu.dc.common.es.EsIndex; import com.fujitsu.dc.common.es.query.DcQueryBuilder; import com.fujitsu.dc.common.es.response.DcBulkResponse; import com.fujitsu.dc.common.es.response.DcMultiSearchResponse; import com.fujitsu.dc.common.es.response.DcSearchResponse; import com.fujitsu.dc.common.es.response.EsClientException; import com.fujitsu.dc.common.es.response.impl.DcBulkResponseImpl; import com.fujitsu.dc.common.es.response.impl.DcMultiSearchResponseImpl; import com.fujitsu.dc.common.es.response.impl.DcSearchResponseImpl; /** * Index ? Class. */ public class EsIndexImpl extends EsTranslogHandler implements EsIndex { private InternalEsClient esClient; /** * . */ static Logger log = LoggerFactory.getLogger(EsIndexImpl.class); // ? private int retryCount; // ? private int retryInterval; String name; String category; private EsTranslogHandler requestOwner; /** * ???????. * @param name ?? * @param category * @param times ES?????? * @param interval ES??????() * @param client EsClient */ public EsIndexImpl(final String name, final String category, int times, int interval, InternalEsClient client) { super(times, interval, client, name); // ?????????public??????????? // EsClient?????? this.name = name; this.category = category; this.retryCount = times; this.retryInterval = interval; this.esClient = client; this.requestOwner = this; } @Override public String getName() { return this.name; } @Override public String getCategory() { return this.category; } @Override public void create() { if (mappingConfigs == null) { loadMappingConfigs(); } Map<String, JSONObject> mappings = mappingConfigs.get(this.category); if (mappings == null) { throw new EsClientException("NO MAPPINGS DEFINED for " + this.category + this.name); } CreateRetryableRequest request = new CreateRetryableRequest(retryCount, retryInterval, name, mappings); // ???????. request.doRequest(); } @Override public void delete() { DeleteRetryableRequest request = new DeleteRetryableRequest(retryCount, retryInterval, this.name); // ???????. request.doRequest(); } @Override public DcSearchResponse search(String routingId, final Map<String, Object> query) { SearchWithMapRetryableRequest request = new SearchWithMapRetryableRequest(retryCount, retryInterval, routingId, query); // ???????. return DcSearchResponseImpl.getInstance(request.doRequest()); } @Override public DcSearchResponse search(String routingId, final DcQueryBuilder query) { SearchRetryableRequest request = new SearchRetryableRequest(retryCount, retryInterval, routingId, getQueryBuilder(query)); // ???????. return DcSearchResponseImpl.getInstance(request.doRequest()); } @Override public DcMultiSearchResponse multiSearch(String routingId, final List<Map<String, Object>> queryList) { MultiSearchRetryableRequest request = new MultiSearchRetryableRequest(retryCount, retryInterval, routingId, queryList); // ???????. return DcMultiSearchResponseImpl.getInstance(request.doRequest()); } @Override public void deleteByQuery(String routingId, DcQueryBuilder queryBuilder) { QueryBuilder deleteQuery = getQueryBuilder(queryBuilder); DeleteByQueryRetryableRequest request = new DeleteByQueryRetryableRequest(retryCount, retryInterval, this.name, deleteQuery); request.doRequest(); // ????????????? DcSearchResponse response = this.search(routingId, queryBuilder); long failedCount = response.getHits().getAllPages(); if (failedCount != 0) { throw new EsClientException.EsDeleteByQueryException(failedCount); } } private QueryBuilder getQueryBuilder(DcQueryBuilder dcQueryBuilder) { QueryBuilder queryBuilder = null; if (dcQueryBuilder != null) { queryBuilder = dcQueryBuilder.getQueryBuilder(); } if (queryBuilder == null) { log.info("Query is not specified."); } return queryBuilder; } @Override public DcBulkResponse bulkCreate(final String routingId, final List<EsBulkRequest> datas) { BulkCreateRetryableRequest request = new BulkCreateRetryableRequest(retryCount, retryInterval, this.name, routingId, datas); // ???????. return DcBulkResponseImpl.getInstance(request.doRequest()); } /** * ??. * @param index ?? * @param settings ? * @return Void */ public Void updateSettings(String index, Map<String, String> settings) { UpdateSettingsRetryableRequest request = new UpdateSettingsRetryableRequest(retryCount, retryInterval, index, settings); // ???????. return request.doRequest(); } /** * Elasticsearch?? index create?. */ class CreateRetryableRequest extends AbstractRetryableEsRequest<CreateIndexResponse> { String name; Map<String, JSONObject> mappings; public CreateRetryableRequest(int retryCount, long retryInterval, String argName, Map<String, JSONObject> argMappings) { super(retryCount, retryInterval, "EsIndex create"); name = argName; mappings = argMappings; } @Override CreateIndexResponse doProcess() { return esClient.createIndex(name, mappings).actionGet(); } /** * ????????true???????. * ???#onParticularError???. * ??, ? false?. * @param e ? * @return true: ?????, false: ?? */ @Override boolean isParticularError(ElasticsearchException e) { return e instanceof IndexAlreadyExistsException || e.getCause() instanceof IndexAlreadyExistsException; } @Override CreateIndexResponse onParticularError(ElasticsearchException e) { if (e instanceof IndexAlreadyExistsException || e.getCause() instanceof IndexAlreadyExistsException) { throw new EsClientException.EsIndexAlreadyExistsException(e); } throw e; } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * Elasticsearch?? index delete?. */ class DeleteRetryableRequest extends AbstractRetryableEsRequest<DeleteIndexResponse> { String name; public DeleteRetryableRequest(int retryCount, long retryInterval, String argName) { super(retryCount, retryInterval, "EsIndex delete"); name = argName; } @Override DeleteIndexResponse doProcess() { return esClient.deleteIndex(this.name).actionGet(); } @Override boolean isParticularError(ElasticsearchException e) { return e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException; } @Override DeleteIndexResponse onParticularError(ElasticsearchException e) { if (e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException) { throw new EsClientException.EsIndexMissingException(e); } throw e; } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } static Map<String, Map<String, JSONObject>> mappingConfigs = null; static synchronized void loadMappingConfigs() { if (mappingConfigs != null) { return; } mappingConfigs = new HashMap<String, Map<String, JSONObject>>(); loadMappingConfig(EsIndex.CATEGORY_AD, "Domain", "es/mapping/domain.json"); loadMappingConfig(EsIndex.CATEGORY_AD, "Cell", "es/mapping/cell.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "link", "es/mapping/link.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "Account", "es/mapping/account.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "Box", "es/mapping/box.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "Role", "es/mapping/role.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "Relation", "es/mapping/relation.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "SentMessage", "es/mapping/sentMessage.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "ReceivedMessage", "es/mapping/receivedMessage.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "EntityType", "es/mapping/entityType.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "AssociationEnd", "es/mapping/associationEnd.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "Property", "es/mapping/property.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "ComplexType", "es/mapping/complexType.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "ComplexTypeProperty", "es/mapping/complexTypeProperty.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "ExtCell", "es/mapping/extCell.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "ExtRole", "es/mapping/extRole.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "dav", "es/mapping/dav.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "UserData", "es/mapping/userdata.json"); loadMappingConfig(EsIndex.CATEGORY_USR, "_default_", "es/mapping/default.json"); } static void loadMappingConfig(String indexCat, String typeCat, String resPath) { JSONObject json = readJsonResource(resPath); Map<String, JSONObject> idxMappings = mappingConfigs.get(indexCat); if (idxMappings == null) { idxMappings = new HashMap<String, JSONObject>(); mappingConfigs.put(indexCat, idxMappings); } idxMappings.put(typeCat, json); } /** * ?JSON???????. * @param resPath * @return ???JSON */ private static JSONObject readJsonResource(final String resPath) { JSONParser jp = new JSONParser(); JSONObject json = null; InputStream is = null; try { is = EsIndexImpl.class.getClassLoader().getResourceAsStream(resPath); json = (JSONObject) jp.parse(new InputStreamReader(is, CharEncoding.UTF_8)); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (ParseException e) { throw new RuntimeException(e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { throw new RuntimeException(e); } } } return json; } /** * ????????. */ public static class TooLongIndexNameException extends RuntimeException { /** * ?ID. */ private static final long serialVersionUID = 1L; /** * . * @param msg */ public TooLongIndexNameException(final String msg) { super(msg); } } /** * Elasticsearch?? search?. <br /> * Query?Map????QueryBuilder????????. */ @Deprecated class SearchWithMapRetryableRequest extends AbstractRetryableEsRequest<SearchResponse> { String routingId; Map<String, Object> query; public SearchWithMapRetryableRequest(int retryCount, long retryInterval, String argRoutingId, Map<String, Object> argQuery) { super(retryCount, retryInterval, "EsIndex search"); query = argQuery; routingId = argRoutingId; } @Override SearchResponse doProcess() { return asyncIndexSearch(routingId, query).actionGet(); } @Override boolean isParticularError(ElasticsearchException e) { return e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException || e instanceof SearchPhaseExecutionException; } @Override SearchResponse onParticularError(ElasticsearchException e) { if (e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException) { return null; } if (e instanceof SearchPhaseExecutionException) { throw new EsClientException("unknown property was appointed.", e); } throw e; } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * Elasticsearch?? search?. */ class SearchRetryableRequest extends AbstractRetryableEsRequest<SearchResponse> { String routingId; QueryBuilder query; public SearchRetryableRequest(int retryCount, long retryInterval, String argRoutingId, QueryBuilder argQuery) { super(retryCount, retryInterval, "EsIndex search"); routingId = argRoutingId; query = argQuery; } @Override boolean isParticularError(ElasticsearchException e) { return e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException || e instanceof SearchPhaseExecutionException; } @Override SearchResponse doProcess() { return asyncIndexSearch(routingId, query).actionGet(); } @Override SearchResponse onParticularError(ElasticsearchException e) { if (e instanceof IndexMissingException || e.getCause() instanceof IndexMissingException) { return null; } if (e instanceof SearchPhaseExecutionException) { throw new EsClientException("unknown property was appointed.", e); } throw e; } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * Elasticsearch?? multisearch?. */ class MultiSearchRetryableRequest extends AbstractRetryableEsRequest<MultiSearchResponse> { String routingId; List<Map<String, Object>> queryList; public MultiSearchRetryableRequest(int retryCount, long retryInterval, String argRoutingId, List<Map<String, Object>> argQueryList) { super(retryCount, retryInterval, "EsIndex search"); routingId = argRoutingId; queryList = argQueryList; } @Override MultiSearchResponse doProcess() { return asyncMultiIndexSearch(routingId, queryList).actionGet(); } @Override boolean isParticularError(ElasticsearchException e) { return e instanceof SearchPhaseExecutionException; } @Override MultiSearchResponse onParticularError(ElasticsearchException e) { if (e instanceof SearchPhaseExecutionException) { throw new EsClientException("unknown property was appointed.", e); } throw e; } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * Elasticsearch?? delete by query?. */ class DeleteByQueryRetryableRequest extends AbstractRetryableEsRequest<DeleteByQueryResponse> { String name; QueryBuilder deleteQuery; public DeleteByQueryRetryableRequest(int retryCount, long retryInterval, String argName, QueryBuilder argDeleteQuery) { super(retryCount, retryInterval, "EsIndex deleteByQuery"); name = argName; deleteQuery = argDeleteQuery; } @Override DeleteByQueryResponse doProcess() { return esClient.deleteByQuery(name, deleteQuery); } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * Elasticsearch?? update index settings?. */ class UpdateSettingsRetryableRequest extends AbstractRetryableEsRequest<Void> { String index; Map<String, String> settings; public UpdateSettingsRetryableRequest(int retryCount, long retryInterval, String index, Map<String, String> settings) { super(retryCount, retryInterval, "EsIndex updateSettings"); this.index = index; this.settings = settings; } @Override Void doProcess() { return esClient.updateIndexSettings(index, settings); } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } /** * ???. <br /> * Query?Map????QueryBuilder????????. * @param routingId routingId * @param query * @return ES */ public ActionFuture<SearchResponse> asyncIndexSearch(String routingId, final Map<String, Object> query) { return esClient.asyncSearch(this.name, routingId, query); } /** * ???. * @param routingId routingId * @param query * @return ES */ public ActionFuture<SearchResponse> asyncIndexSearch(String routingId, final QueryBuilder query) { return esClient.asyncSearch(this.name, routingId, query); } /** * ????. * @param routingId routingId * @param queryList * @return ES */ public ActionFuture<MultiSearchResponse> asyncMultiIndexSearch(String routingId, final List<Map<String, Object>> queryList) { return esClient.asyncMultiSearch(this.name, routingId, queryList); } /** * Elasticsearch?? bulk create?. */ class BulkCreateRetryableRequest extends AbstractRetryableEsRequest<BulkResponse> { String name; String routingId; List<EsBulkRequest> datas; public BulkCreateRetryableRequest(int retryCount, long retryInterval, String argName, String argRoutingId, List<EsBulkRequest> argDatas) { super(retryCount, retryInterval, "EsIndex bulkCreate"); name = argName; routingId = argRoutingId; datas = argDatas; } @Override BulkResponse doProcess() { return esClient.bulkCreate(name, routingId, datas); } @Override EsTranslogHandler getEsTranslogHandler() { return requestOwner; } } }