/** * 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 static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; import org.json.simple.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import com.fujitsu.dc.common.es.EsClient; import com.fujitsu.dc.common.es.EsIndex; import com.fujitsu.dc.common.es.response.DcActionResponse; import com.fujitsu.dc.common.es.response.DcGetResponse; import com.fujitsu.dc.common.es.response.DcIndexResponse; import com.fujitsu.dc.common.es.response.EsClientException; import com.fujitsu.dc.common.es.util.DcUUID; import com.fujitsu.dc.core.DcCoreConfig; import com.fujitsu.dc.core.model.file.BinaryDataAccessException; import com.fujitsu.dc.core.model.file.BinaryDataAccessor; import com.fujitsu.dc.core.model.impl.es.DavNode; import com.fujitsu.dc.core.model.impl.es.ads.AdsException; import com.fujitsu.dc.core.model.impl.es.ads.JdbcAds; import com.fujitsu.dc.test.categories.Unit; import com.fujitsu.dc.test.jersey.DcRunner; /** * DavNodeAccessorTestの単体テストケース. */ @RunWith(DcRunner.class) @Category({Unit.class }) public class DavNodeAccessorTest { private static final String UNIT_USER_NAME = "index_for_test"; private static final String UNIT_PREFIX = DcCoreConfig.getEsUnitPrefix(); private static final String INDEX_NAME = UNIT_PREFIX + "_" + UNIT_USER_NAME; private static final String TYPE_NAME = "TypeForTest"; private static final String ROUTING_ID = "RoutingIdTest"; private BinaryDataAccessor binaryDataAccessor = new BinaryDataAccessor(DcCoreConfig.getBlobStoreRoot(), "index_for_test", DcCoreConfig.getFsyncEnabled()); private static EsClient esClient; /** * 各テスト実行前の初期化処理. * @throws Exception 異常が発生した場合の例外 */ @Before public void setUp() throws Exception { esClient = new EsClient(DcCoreConfig.getEsClusterName(), DcCoreConfig.getEsHosts()); } /** * 各テスト実行後のクリーンアップ処理. * @throws Exception 異常が発生した場合の例外 */ @After public void tearDown() throws Exception { EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); try { index.delete(); JdbcAds ads = new JdbcAds(); ads.deleteIndex(INDEX_NAME); } catch (Exception ex) { System.out.println(""); } } /** * 例外用Mock. * @author Administrator */ class JdbcAdsMock extends JdbcAds { JdbcAdsMock() throws Exception { super(); } @Override public void createDavNode(String index, DavNode davNode) throws AdsException { throw new AdsException("MockErrorCreare"); } @Override public void updateDavNode(String index, DavNode davNode) throws AdsException { throw new AdsException("MockErrorUpdate"); } @Override public void deleteDavNode(String index, String id) throws AdsException { throw new AdsException("MockErrorDelete"); } } /** * 例外用Mock. * @author Administrator */ class JdbcAdsMockDavNodeAccessor extends DavNodeAccessor { JdbcAdsMockDavNodeAccessor(EsIndex index, String name, String routingId) throws Exception { super(index, name, routingId); } @Override public DcActionResponse createForFile(String id, DavNode davNode) { throw new EsClientException(id); } } /** * create処理が正常に終了する. */ @Test public void create処理が正常に終了する() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); // データ登録実行 DcIndexResponse response = davNodeAccessor.create(davNode); // レスポンスのチェック assertNotNull(response); assertFalse(response.getId().equals("")); // マスタにデータが登録されていることを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(1, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); } /** * create処理にてAdsが例外を上げた場合でも正常に終了すること. */ @Test public void create処理にてAdsが例外を上げた場合でも正常に終了すること() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); try { davNodeAccessor.setAds(new JdbcAdsMock()); } catch (Exception e1) { throw new RuntimeException(e1); } // データ登録実行 DcIndexResponse response = davNodeAccessor.create(davNode); // レスポンスのチェック assertNotNull(response); assertFalse(response.getId().equals("")); } /** * update処理が正常に終了する. */ @Test public void update処理が正常に終了する() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); DcIndexResponse createResponse = davNodeAccessor.create(davNode); assertNotNull(createResponse); assertFalse(createResponse.getId().equals("")); // データ更新実行 long dateTime = new Date().getTime(); davNode.setUpdated(dateTime); DcIndexResponse updateResponse = davNodeAccessor.update(createResponse.getId(), davNode); // レスポンスのチェック assertNotNull(updateResponse); assertEquals(createResponse.getId(), updateResponse.getId()); // マスタにデータが更新されていることを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); List<JSONObject> list = ads.getDavNodeList(INDEX_NAME, 0, 1); assertEquals(1, list.size()); assertEquals(dateTime, Long.parseLong((String) ((JSONObject) list.get(0).get("source")).get("u"))); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); } /** * update処理にてAdsが例外を上げた場合でも正常に終了すること. */ @Test public void update処理にてAdsが例外を上げた場合でも正常に終了すること() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); DcIndexResponse createResponse = davNodeAccessor.create(davNode); assertNotNull(createResponse); assertFalse(createResponse.getId().equals("")); try { davNodeAccessor.setAds(new JdbcAdsMock()); } catch (Exception e1) { throw new RuntimeException(e1); } // データ更新実行 long dateTime = new Date().getTime(); davNode.setUpdated(dateTime); DcIndexResponse updateResponse = davNodeAccessor.update(createResponse.getId(), davNode); // レスポンスのチェック assertNotNull(updateResponse); assertEquals(createResponse.getId(), updateResponse.getId()); } /** * delete処理が正常に終了する. */ @Test public void delete処理が正常に終了する() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); DcIndexResponse response = davNodeAccessor.create(davNode); assertNotNull(response); assertFalse(response.getId().equals("")); // データを削除する davNodeAccessor.delete(davNode); // データが削除されていることを確認する if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(0, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } } /** * delete処理にてAdsが例外を上げた場合でも正常に終了すること. */ @Test public void delete処理にてAdsが例外を上げた場合でも正常に終了すること() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); DcIndexResponse response = davNodeAccessor.create(davNode); assertNotNull(response); assertFalse(response.getId().equals("")); try { davNodeAccessor.setAds(new JdbcAdsMock()); } catch (Exception e1) { throw new RuntimeException(e1); } // データを削除する davNodeAccessor.delete(davNode); } /** * ファイルありcreate処理が正常に終了する. */ @Test public void ファイルありcreate処理が正常に終了する() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); // データ登録実行 DcActionResponse response = davNodeAccessor.createForFile(id, davNode); // レスポンスのチェック assertNotNull(response); String resId = null; if (response instanceof DcIndexResponse) { resId = ((DcIndexResponse) response).getId(); } else if (response instanceof DcGetResponse) { resId = ((DcGetResponse) response).getId(); } assertEquals(id, resId); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // マスタにデータが登録されていることを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(1, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); deleteTestTmpFile(id); } /** * ファイルありcreate処理でESエラーが発生した場合ファイルが存在しないこと. */ @Test public void ファイルありcreate処理でESエラーが発生した場合ファイルが存在しないこと() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); // データ登録実行 DcActionResponse response = davNodeAccessor.createForFile(id, davNode); // レスポンスのチェック assertNotNull(response); String resId = null; if (response instanceof DcIndexResponse) { resId = ((DcIndexResponse) response).getId(); } else if (response instanceof DcGetResponse) { resId = ((DcGetResponse) response).getId(); } assertEquals(id, resId); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // マスタにデータが登録されていることを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(1, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } // テスト用にファイル削除 deleteTestTmpFile(id); try { // データ登録実行 // Mockを使用してESClientExceptionを発生させる new JdbcAdsMockDavNodeAccessor(index, TYPE_NAME, ROUTING_ID).createForFile(id, davNode); } catch (Exception e) { e.printStackTrace(); } assertFalse(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // データを削除する davNodeAccessor.delete(davNode); } /** * ファイルありcreate処理でMySQLエラーが発生した場合ファイルが存在しないこと. */ @Test public void ファイルありcreate処理でMySQLエラーが発生した場合ファイルが存在しないこと() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); DavNodeAccessor davNodeAccessorTest = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); try { davNodeAccessorTest.setAds(new JdbcAdsMock()); } catch (Exception e1) { throw new RuntimeException(e1); } // データ登録実行 DcActionResponse response = davNodeAccessorTest.createForFile(id, davNode); // レスポンスのチェック assertNotNull(response); String resId = null; if (response instanceof DcIndexResponse) { resId = ((DcIndexResponse) response).getId(); } else if (response instanceof DcGetResponse) { resId = ((DcGetResponse) response).getId(); } assertEquals(id, resId); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // マスタにデータが登録されていないことを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(0, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); deleteTestTmpFile(id); } /** * ファイルありcreate処理で一時ファイルのコピーに失敗した場合ファイルが存在しないこと. */ @Test public void ファイルありcreate処理で一時ファイルのコピーに失敗した場合ファイルが存在しないこと() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(); try { // データ登録実行 davNodeAccessor.createForFile(id, davNode); } catch (Exception e) { e.printStackTrace(); } // レスポンスのチェック assertFalse(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // マスタにデータが登録されていないことを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); assertEquals(0, ads.countDavNode(INDEX_NAME)); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); } /** * ファイルありupdate処理が正常に終了する. */ @Test public void ファイルありupdate処理が正常に終了する() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); DcActionResponse createResponse = davNodeAccessor.createForFile(id, davNode); assertNotNull(createResponse); String resId = null; if (createResponse instanceof DcIndexResponse) { resId = ((DcIndexResponse) createResponse).getId(); } else if (createResponse instanceof DcGetResponse) { resId = ((DcGetResponse) createResponse).getId(); } assertFalse(resId.equals("")); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // データ更新実行 long dateTime = new Date().getTime(); davNode.setUpdated(dateTime); createTestTmpFile(id, "DavNodeAccessorTest Update!"); DcIndexResponse updateResponse = davNodeAccessor.updateForFile(resId, davNode, -1); // レスポンスのチェック assertNotNull(updateResponse); assertEquals(resId, updateResponse.getId()); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); assertEquals("DavNodeAccessorTest Update!", readFile(id)); // マスタにデータが更新されていることを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); List<JSONObject> list = ads.getDavNodeList(INDEX_NAME, 0, 1); assertEquals(1, list.size()); assertEquals(dateTime, Long.parseLong((String) ((JSONObject) list.get(0).get("source")).get("u"))); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); deleteTestTmpFile(id); } /** * ファイルありupdate処理でMySQLエラーが発生した場合ファイルが更新されないこと. */ @Test public void ファイルありupdate処理でMySQLエラーが発生した場合ファイルが更新されないこと() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); DcActionResponse createResponse = davNodeAccessor.createForFile(id, davNode); assertNotNull(createResponse); String resId = null; if (createResponse instanceof DcIndexResponse) { resId = ((DcIndexResponse) createResponse).getId(); } else if (createResponse instanceof DcGetResponse) { resId = ((DcGetResponse) createResponse).getId(); } assertFalse(resId.equals("")); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // データ更新実行 long dateTime = new Date().getTime(); davNode.setUpdated(dateTime); createTestTmpFile(id, "DavNodeAccessorTest Update!"); DavNodeAccessor davNodeAccessorUp = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); try { davNodeAccessorUp.setAds(new JdbcAdsMock()); } catch (Exception e1) { throw new RuntimeException(e1); } DcIndexResponse updateResponse = davNodeAccessorUp.updateForFile(resId, davNode, -1); // レスポンスのチェック assertNotNull(updateResponse); assertEquals(resId, updateResponse.getId()); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); assertEquals("DavNodeAccessorTest Update!", readFile(id)); // マスタにデータが更新されていないことを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); List<JSONObject> list = ads.getDavNodeList(INDEX_NAME, 0, 1); assertEquals(1, list.size()); assertFalse(Long.toString(dateTime).equals((String) ((JSONObject) list.get(0).get("source")).get("u"))); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); deleteTestTmpFile(id); } /** * ファイルありupdate処理で一時ファイルのコピーに失敗した場合ファイルが更新されないこと. */ @Test public void ファイルありupdate処理で一時ファイルのコピーに失敗した場合ファイルが更新されないこと() { // 事前準備 EsIndex index = esClient.idxUser(UNIT_PREFIX, UNIT_USER_NAME); assertNotNull(index); String id = DcUUID.randomUUID(); DavNodeAccessor davNodeAccessor = new DavNodeAccessor(index, TYPE_NAME, ROUTING_ID); DavNode davNode = createTestDavNode(id); DcActionResponse createResponse = davNodeAccessor.createForFile(id, davNode); assertNotNull(createResponse); String resId = null; if (createResponse instanceof DcIndexResponse) { resId = ((DcIndexResponse) createResponse).getId(); } else if (createResponse instanceof DcGetResponse) { resId = ((DcGetResponse) createResponse).getId(); } assertFalse(resId.equals("")); assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); // データ更新実行 long dateTime = new Date().getTime(); davNode.setUpdated(dateTime); try { davNodeAccessor.updateForFile(resId, davNode, -1); } catch (Exception e) { e.printStackTrace(); } // レスポンスのチェック assertTrue(binaryDataAccessor.existsForFilename(id)); assertFalse(binaryDataAccessor.existsForFilename(id + ".tmp")); assertEquals("DavNodeAccessorTest", readFile(id)); // マスタにデータが更新されていないことを確認 if (davNodeAccessor.getAds() != null) { JdbcAds ads = null; try { ads = new JdbcAds(); List<JSONObject> list = ads.getDavNodeList(INDEX_NAME, 0, 1); assertEquals(1, list.size()); assertFalse(Long.toString(dateTime).equals((String) ((JSONObject) list.get(0).get("source")).get("u"))); } catch (Exception e) { fail(e.getMessage()); } } // データを削除する davNodeAccessor.delete(davNode); deleteTestTmpFile(id); } /** * DavCmpEsImplを生成する. * @return DavCmpEsImpl */ private DavNode createTestDavNode() { DavNode davNode = new DavNode(); return davNode; } /** * DavCmpEsImplを生成する. * @return DavCmpEsImpl */ private DavNode createTestDavNode(String id) { DavNode davNode = new DavNode(); // 一時ファイル作成 createTestTmpFile(id); return davNode; } private void createTestTmpFile(String id) { createTestTmpFile(id, "DavNodeAccessorTest"); } private void createTestTmpFile(String id, String body) { InputStream is = new ByteArrayInputStream(body.getBytes()); BufferedInputStream bufferedInput = new BufferedInputStream(is); try { binaryDataAccessor.create(bufferedInput, id); } catch (BinaryDataAccessException e) { fail(e.getMessage()); } } private void deleteTestTmpFile(String id) { try { binaryDataAccessor.deletePhysicalFile(id); } catch (BinaryDataAccessException e) { fail(e.getMessage()); } } private String readFile(String filename) { FileReader f = null; BufferedReader b = null; StringBuffer sb = new StringBuffer(); String filepath = binaryDataAccessor.getFilePath(filename); try { f = new FileReader(filepath); b = new BufferedReader(f); String s; while ((s = b.readLine()) != null) { sb.append(s); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (b != null) { try { b.close(); } catch (IOException e) { e.printStackTrace(); } } if (f != null) { try { f.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); } }