/** * 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.core.model.impl.es.accessor; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.fujitsu.dc.common.ads.AdsWriteFailureLogInfo; import com.fujitsu.dc.common.es.EsIndex; import com.fujitsu.dc.common.es.query.DcQueryBuilder; import com.fujitsu.dc.common.es.query.DcQueryBuilders; import com.fujitsu.dc.common.es.response.DcSearchHit; import com.fujitsu.dc.common.es.response.DcSearchResponse; import com.fujitsu.dc.common.es.response.EsClientException; import com.fujitsu.dc.core.DcCoreLog; import com.fujitsu.dc.core.model.DavCmp; import com.fujitsu.dc.core.model.impl.es.EsModel; import com.fujitsu.dc.core.model.impl.es.QueryMapFactory; import com.fujitsu.dc.core.model.impl.es.ads.AdsException; import com.fujitsu.dc.core.model.impl.es.doc.EntitySetDocHandler; import com.fujitsu.dc.core.model.lock.Lock; import com.fujitsu.dc.core.model.lock.LockKeyComposer; /** * Cellのアクセス処理を実装したクラス. */ public class CellAccessor extends AbstractEntitySetAccessor { /** * コンストラクタ. * @param index インデックス * @param name タイプ名 * @param routingId routingId */ public CellAccessor(EsIndex index, String name, String routingId) { super(index, name, routingId); } /** * セル配下のDavFile数を返却する. * @param cellId 削除対象のセルID * @param unitUserName ユニットユーザ名 * @return セル配下のDavFile数 */ public long getDavFileTotalCount(String cellId, String unitUserName) { // CellAccessorはadインデックスに対するアクセスのため、ユニットユーザ側のアクセッサを取得 DataSourceAccessor accessor = EsModel.dsa(unitUserName); // Countのみを取得するためサイズを0で指定 Map<String, Object> countQuery = getDavFileFilterQuery(cellId); countQuery.put("size", 0); DcSearchResponse response = accessor.searchForIndex(cellId, countQuery); return response.getHits().getAllPages(); } /** * セル配下のDavFileID一覧を返却する. * @param cellId 削除対象のセルID * @param unitUserName ユニットユーザ名 * @param size 取得件数 * @param from 取得開始位置 * @return セル配下のDavFile数 */ public List<String> getDavFileIdList(String cellId, String unitUserName, int size, int from) { // CellAccessorはadインデックスに対するアクセスのため、ユニットユーザ側のアクセッサを取得 DataSourceAccessor accessor = EsModel.dsa(unitUserName); Map<String, Object> searchQuery = getDavFileFilterQuery(cellId); searchQuery.put("size", size); searchQuery.put("from", from); DcSearchResponse response = accessor.searchForIndex(cellId, searchQuery); List<String> davFileIdList = new ArrayList<String>(); for (DcSearchHit hit : response.getHits().getHits()) { davFileIdList.add(hit.getId()); } return davFileIdList; } private Map<String, Object> getDavFileFilterQuery(String cellId) { Map<String, Object> cellQuery = new HashMap<String, Object>(); cellQuery.put("c", cellId); Map<String, Object> cellTermQuery = new HashMap<String, Object>(); cellTermQuery.put("term", cellQuery); Map<String, Object> davTypeQuery = new HashMap<String, Object>(); davTypeQuery.put("t", DavCmp.TYPE_DAV_FILE); Map<String, Object> davTypeTermQuery = new HashMap<String, Object>(); davTypeTermQuery.put("term", davTypeQuery); List<Map<String, Object>> andQueryList = new ArrayList<Map<String, Object>>(); andQueryList.add(cellTermQuery); andQueryList.add(davTypeTermQuery); Map<String, Object> query = QueryMapFactory.filteredQuery(null, QueryMapFactory.mustQuery(andQueryList)); Map<String, Object> countQuery = new HashMap<String, Object>(); countQuery.put("query", query); return countQuery; } /** * セル配下のエンティティを一括削除する. * @param cellId 削除対象のセルID * @param unitUserName ユニットユーザ名 */ public void cellBulkDeletion(String cellId, String unitUserName) { // AdsのCell配下のエンティティはバッチにて削除するので // Cell削除管理テーブルに削除対象のDB名とセルIDを追加する insertCellDeleteRecord(unitUserName, cellId); DataSourceAccessor accessor = EsModel.dsa(unitUserName); // セルIDを指定してelasticsearchからセル関連エンティティを一括削除する DcQueryBuilder matchQuery = DcQueryBuilders.matchQuery("c", cellId); try { accessor.deleteByQuery(cellId, matchQuery); log.info("KVS Deletion Success."); } catch (EsClientException e) { // 削除に失敗した場合はログを出力して処理を続行する log.warn(String.format("Delete CellResource From KVS Failed. CellId:[%s], CellUnitUserName:[%s]", cellId, unitUserName), e); } } private void insertCellDeleteRecord(String unitUserName, String cellId) { CellDeleteAccessor accessor = new CellDeleteAccessor(); if (!accessor.isValid()) { log.warn(String.format("Insert CELL_DELETE Record To Ads Failed. db_name:[%s], cell_id:[%s]", unitUserName, cellId)); return; } accessor.createManagementDatabase(); accessor.insertCellDeleteRecord(unitUserName, cellId); } /** * マスターデータを登録する. * @param docHandler 登録データ */ @Override protected void createAds(EntitySetDocHandler docHandler) { // 登録に成功した場合、マスタデータを書き込む if (getAds() != null) { String unitUserName = docHandler.getUnitUserName(); try { getAds().createCell(unitUserName, docHandler); } catch (AdsException e) { // Indexが存在しない場合はインデックスを作成する。 if (e.getCause() instanceof SQLException && MYSQL_BAD_TABLE_ERROR.equals(((SQLException) e.getCause()).getSQLState())) { DcCoreLog.Server.ES_INDEX_NOT_EXIST.params(unitUserName).writeLog(); createAdsIndex(unitUserName); try { getAds().createCell(unitUserName, docHandler); } catch (AdsException e1) { DcCoreLog.Server.DATA_STORE_ENTITY_CREATE_FAIL.params(e1.getMessage()).reason(e1).writeLog(); // Adsの登録に失敗した場合は、専用のログに書込む String lockKey = LockKeyComposer.fullKeyFromCategoryAndKey(Lock.CATEGORY_ODATA, docHandler.getCellId(), null, null); AdsWriteFailureLogInfo loginfo = new AdsWriteFailureLogInfo( docHandler.getUnitUserName(), docHandler.getType(), lockKey, docHandler.getCellId(), docHandler.getId(), AdsWriteFailureLogInfo.OperationKind.CREATE, 1, docHandler.getUpdated()); recordAdsWriteFailureLog(loginfo); } } else { DcCoreLog.Server.DATA_STORE_ENTITY_CREATE_FAIL.params(e.getMessage()).reason(e).writeLog(); // Adsの登録に失敗した場合は、専用のログに書込む String lockKey = LockKeyComposer.fullKeyFromCategoryAndKey(Lock.CATEGORY_ODATA, docHandler.getCellId(), null, null); AdsWriteFailureLogInfo loginfo = new AdsWriteFailureLogInfo( docHandler.getUnitUserName(), docHandler.getType(), lockKey, docHandler.getCellId(), docHandler.getId(), AdsWriteFailureLogInfo.OperationKind.CREATE, 1, docHandler.getUpdated()); recordAdsWriteFailureLog(loginfo); } } } } /** * マスターデータを更新する. * @param docHandler 登録データ * @param version Elasticsearchに登録されたドキュメントのバージョン */ @Override protected void updateAds(EntitySetDocHandler docHandler, long version) { // 更新に成功した場合、マスタデータを更新する if (getAds() != null) { try { getAds().updateCell(docHandler.getUnitUserName(), docHandler); } catch (AdsException e) { DcCoreLog.Server.DATA_STORE_ENTITY_UPDATE_FAIL.params(e.getMessage()).reason(e).writeLog(); // Adsの登録に失敗した場合は、専用のログに書込む String lockKey = LockKeyComposer.fullKeyFromCategoryAndKey(Lock.CATEGORY_ODATA, docHandler.getCellId(), null, null); AdsWriteFailureLogInfo loginfo = new AdsWriteFailureLogInfo( docHandler.getUnitUserName(), docHandler.getType(), lockKey, docHandler.getCellId(), docHandler.getId(), AdsWriteFailureLogInfo.OperationKind.UPDATE, version, docHandler.getUpdated()); recordAdsWriteFailureLog(loginfo); } } } /** * マスタデータを削除する. * @param docHandler 削除データ * @param version 削除したデータのバージョン */ @Override protected void deleteAds(EntitySetDocHandler docHandler, long version) { String id = docHandler.getId(); String unitUserName = docHandler.getUnitUserName(); // 削除に成功した場合、マスタデータを削除する if (getAds() != null) { try { getAds().deleteCell(unitUserName, id); } catch (AdsException e) { DcCoreLog.Server.DATA_STORE_ENTITY_DELETE_FAIL.params(e.getMessage()).reason(e).writeLog(); // Adsの登録に失敗した場合は、専用のログに書込む String lockKey = LockKeyComposer.fullKeyFromCategoryAndKey(Lock.CATEGORY_ODATA, docHandler.getCellId(), null, null); AdsWriteFailureLogInfo loginfo = new AdsWriteFailureLogInfo( docHandler.getUnitUserName(), docHandler.getType(), lockKey, docHandler.getCellId(), docHandler.getId(), AdsWriteFailureLogInfo.OperationKind.DELETE, version, docHandler.getUpdated()); recordAdsWriteFailureLog(loginfo); } } } }