/** * 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.test.jersey.box.odatacol; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ws.rs.core.MediaType; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.odata4j.edm.EdmSimpleType; import com.fujitsu.dc.core.DcCoreConfig; import com.fujitsu.dc.test.jersey.AbstractCase; import com.fujitsu.dc.test.jersey.DcRequest; import com.fujitsu.dc.test.jersey.DcResponse; import com.fujitsu.dc.test.jersey.DcRestAdapter; import com.fujitsu.dc.test.jersey.ODataCommon; import com.fujitsu.dc.test.setup.Setup; import com.fujitsu.dc.test.unit.core.UrlUtils; import com.fujitsu.dc.test.utils.Http; import com.fujitsu.dc.test.utils.TResponse; import com.fujitsu.dc.test.utils.UserDataUtils; import com.sun.jersey.test.framework.WebAppDescriptor; /** * UserDataテスト用の抽象クラス. */ public abstract class AbstractUserDataTest extends AbstractCase { String cellName = "testcell1"; String boxName = "box1"; String colName = "setodata"; String entityTypeName = "Category"; String navPropName = null; /** * コンストラクタ. */ public AbstractUserDataTest() { super("com.fujitsu.dc.core.rs"); } /** * コンストラクタ. * @param build WebAppDescriptor */ public AbstractUserDataTest(WebAppDescriptor build) { super(build); } /** * ユーザーデータを作成する. * @param body リクエストボディ * @param sc 期待するステータスコード * @return レスポンス */ protected TResponse createUserData(JSONObject body, int sc) { TResponse response = Http.request("box/odatacol/create.txt") .with("cell", cellName) .with("box", boxName) .with("collection", colName) .with("entityType", entityTypeName) .with("accept", MediaType.APPLICATION_JSON) .with("contentType", MediaType.APPLICATION_JSON) .with("token", "Bearer " + DcCoreConfig.getMasterToken()) .with("body", body.toJSONString()) .returns() .statusCode(sc) .debug(); return response; } /** * ユーザデータの一覧を作成. * @param userdataId1 1つめのID * @param userdataId2 2つめのID */ @SuppressWarnings("unchecked") public void createUserDataList(String userdataId1, String userdataId2) { // リクエストボディを設定 JSONObject body = new JSONObject(); body.put("__id", userdataId1); body.put("dynamicProperty1", "dynamicPropertyValue1"); body.put("dynamicProperty2", "dynamicPropertyValue2"); body.put("dynamicProperty3", "dynamicPropertyValue3"); JSONObject body2 = new JSONObject(); body2.put("__id", userdataId2); body2.put("dynamicProperty1", "dynamicPropertyValueA"); body2.put("dynamicProperty2", "dynamicPropertyValueB"); body2.put("dynamicProperty3", "dynamicPropertyValueC"); // ユーザデータ作成 createUserData(body, HttpStatus.SC_CREATED); createUserData(body2, HttpStatus.SC_CREATED); } /** * ユーザデータの一覧を作成(Etag返却). * @param userdataId1 1つめのID * @param userdataId2 2つめのID * @param etag etag */ @SuppressWarnings("unchecked") public void createUserDataList(String userdataId1, String userdataId2, Map<String, String> etag) { // リクエストボディを設定 JSONObject body = new JSONObject(); body.put("__id", userdataId1); body.put("dynamicProperty1", "dynamicPropertyValue1"); body.put("dynamicProperty2", "dynamicPropertyValue2"); body.put("dynamicProperty3", "dynamicPropertyValue3"); JSONObject body2 = new JSONObject(); body2.put("__id", userdataId2); body2.put("dynamicProperty1", "dynamicPropertyValueA"); body2.put("dynamicProperty2", "dynamicPropertyValueB"); body2.put("dynamicProperty3", "dynamicPropertyValueC"); // ユーザデータ作成 TResponse response = createUserData(body, HttpStatus.SC_CREATED); // Etag取得 etag.put(userdataId1, response.getHeader(HttpHeaders.ETAG)); // ユーザデータ作成 response = createUserData(body2, HttpStatus.SC_CREATED); // Etag取得 etag.put(userdataId2, response.getHeader(HttpHeaders.ETAG)); } /** * ユーザーデータを作成する. * @param body リクエストボディ * @param sc 期待するステータスコード * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @return レスポンス */ protected TResponse createUserData(JSONObject body, int sc, String cell, String box, String col, String entityType) { TResponse response = Http.request("box/odatacol/create.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("accept", MediaType.APPLICATION_JSON) .with("contentType", MediaType.APPLICATION_JSON) .with("token", "Bearer " + DcCoreConfig.getMasterToken()) .with("body", body.toJSONString()) .returns() .statusCode(sc) .debug(); return response; } /** * ユーザーデータを一覧取得する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @return レスポンス */ protected TResponse getUserDataList(String cell, String box, String col, String entityType) { TResponse response = Http.request("box/odatacol/list.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("query", "") .with("accept", MediaType.APPLICATION_JSON) .with("token", DcCoreConfig.getMasterToken()) .returns() .statusCode(HttpStatus.SC_OK) .debug(); return response; } /** * ユーザーデータを一覧取得する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param query クエリ * @return レスポンス */ protected TResponse getUserDataList(String cell, String box, String col, String entityType, String query) { TResponse response = Http.request("box/odatacol/list.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("query", query) .with("accept", MediaType.APPLICATION_JSON) .with("token", DcCoreConfig.getMasterToken()) .returns() .statusCode(HttpStatus.SC_OK) .debug(); return response; } /** * ユーザーデータを一覧を取得する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param targetEntityTypeName エンティティ名 * @param query リクエストクエリ * @return ユーザーデータ取得時のレスポンスオブジェクト */ protected static DcResponse getUserDataWithDcClient(String cell, String box, String col, String targetEntityTypeName, String query) { DcRestAdapter rest = new DcRestAdapter(); DcResponse res = null; // リクエストヘッダをセット HashMap<String, String> requestheaders = new HashMap<String, String>(); requestheaders.put(HttpHeaders.AUTHORIZATION, "Bearer " + DcCoreConfig.getMasterToken()); requestheaders.put(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); // リクエストを実行する try { res = rest.getAcceptEncodingGzip( UrlUtils.userData(cell, box, col, targetEntityTypeName) + query, requestheaders); } catch (Exception e) { fail(e.getMessage()); } return res; } /** * ユーザーデータを取得する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param userDataId ユーザデータID * @param token 認証トークン * @param sc 期待するステータスコード * @return レスポンス */ protected TResponse getUserData(String cell, String box, String col, String entityType, String userDataId, String token, int sc) { return getUserData(cell, box, col, entityType, userDataId, token, "", sc); } /** * ユーザーデータを取得する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param userDataId ユーザデータID * @param token 認証トークン * @param query クエリ * @param sc 期待するステータスコード * @return レスポンス */ protected TResponse getUserData(String cell, String box, String col, String entityType, String userDataId, String token, String query, int sc) { TResponse response = Http.request("box/odatacol/get.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("id", userDataId) .with("token", token) .with("accept", MediaType.APPLICATION_JSON) .with("query", query) .returns() .statusCode(sc) .debug(); return response; } /** * ユーザーデータを更新する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param userDataId ユーザデータID * @param body リクエストボディ * @return レスポンス */ protected TResponse updateUserData(String cell, String box, String col, String entityType, String userDataId, JSONObject body) { return Http.request("box/odatacol/update.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("id", userDataId) .with("accept", MediaType.APPLICATION_JSON) .with("contentType", MediaType.APPLICATION_JSON) .with("ifMatch", "*") .with("token", DcCoreConfig.getMasterToken()) .with("body", body.toJSONString()) .returns() .statusCode(HttpStatus.SC_NO_CONTENT) .debug(); } /** * ユーザーデータを1件作成する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティ名 * @param body リクエストボディ * @return ユーザーデータ作成時のレスポンスオブジェクト */ protected DcResponse createUserDataWithDcClient(String cell, String box, String col, String entityType, JSONObject body) { DcRestAdapter rest = new DcRestAdapter(); DcResponse res = null; // リクエストヘッダをセット HashMap<String, String> requestheaders = new HashMap<String, String>(); requestheaders.put(HttpHeaders.AUTHORIZATION, BEARER_MASTER_TOKEN); // リクエストを実行する try { res = rest.post(UrlUtils.userData(cell, box, col, entityType), body.toJSONString(), requestheaders); } catch (Exception e) { fail(e.getMessage()); } return res; } /** * ユーザーデータをNP経由で作成する. * @param id エンティティID * @param body リクエストボディ * @param sc 期待するステータスコード * @return レスポンス */ protected TResponse createUserDataWithNP(String id, JSONObject body, int sc) { TResponse response = Http.request("box/odatacol/createNP.txt") .with("cell", cellName) .with("box", boxName) .with("collection", colName) .with("entityType", entityTypeName) .with("id", id) .with("navPropName", "_" + navPropName) .with("accept", MediaType.APPLICATION_JSON) .with("contentType", MediaType.APPLICATION_JSON) .with("token", DcCoreConfig.getMasterToken()) .with("body", body.toJSONString()) .returns() .statusCode(sc) .debug(); return response; } /** * ComplexTypeユーザデータをNP経由で作成する. * @param id エンティティID * @param reqBody リクエストボディ * @return レスポンス */ protected DcResponse createComplexTypeUserDataWithNP(String id, HashMap<String, Object> reqBody) { // UserData作成 String requestUrl = UrlUtils.userdataNP(Setup.TEST_CELL1, Setup.TEST_BOX1, UserDataListWithNPTest.ODATA_COLLECTION, entityTypeName, id, navPropName); DcRequest req = DcRequest.post(requestUrl); req.header(HttpHeaders.AUTHORIZATION, BEARER_MASTER_TOKEN); for (String key : reqBody.keySet()) { req.addJsonBody(key, reqBody.get(key)); } // 登録 return request(req); } /** * ユーザーデータを削除する. * @param userDataId 削除対象ID */ protected void deleteUserData(String userDataId) { // リクエスト実行 Http.request("box/odatacol/delete.txt") .with("cell", cellName) .with("box", boxName) .with("collection", colName) .with("entityType", entityTypeName) .with("id", userDataId) .with("token", DcCoreConfig.getMasterToken()) .with("ifMatch", "*") .returns() .statusCode(-1); } /** * ユーザーデータを削除する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param userDataId 削除対象ID * @param token 認証トークン * @param sc レスポンス */ protected void deleteUserData(String cell, String box, String col, String entityType, String userDataId, String token, int sc) { // リクエスト実行 deleteUserData(cell, box, col, entityType, userDataId, token, "*", sc); } /** * ユーザーデータを削除する. * @param cell セル名 * @param box ボックス名 * @param col コレクション名 * @param entityType エンティティタイプ名 * @param userDataId 削除対象ID * @param token 認証トークン * @param ifMatch ifMatch * @param sc レスポンス */ protected void deleteUserData(String cell, String box, String col, String entityType, String userDataId, String token, String ifMatch, int sc) { // リクエスト実行 Http.request("box/odatacol/delete.txt") .with("cell", cell) .with("box", box) .with("collection", col) .with("entityType", entityType) .with("id", userDataId) .with("token", token) .with("ifMatch", ifMatch) .returns() .statusCode(sc); } /** * ユーザデータの一覧を削除. * @param id1 1つめのID * @param id2 2つめのID */ public void deleteUserDataList(String id1, String id2) { deleteUserData(id1); deleteUserData(id2); } /** * ユーザーデータのリンク情報を削除する. * @param userDataId 削除対象ID * @param navPropId 削除対象のNavigationPropertyのID */ protected void deleteUserDataLinks(String userDataId, String navPropId) { // リクエスト実行 Http.request("box/odatacol/delete-link.txt") .with("cell", cellName) .with("box", boxName) .with("collection", colName) .with("entityType", entityTypeName) .with("id", userDataId) .with("navProp", "_" + navPropName) .with("navKey", navPropId) .with("contentType", MediaType.APPLICATION_JSON) .with("token", DcCoreConfig.getMasterToken()) .with("ifMatch", "*") .returns() .statusCode(HttpStatus.SC_NO_CONTENT); } /** * UserDataの名前空間を取得する. * @param entityType エンティティタイプ名 * @return UserDataの名前空間 */ protected String getNameSpace(String entityType) { // NameSpace取得のためにメタデータを取得する return getNameSpace(entityType, colName); } /** * UserDataの名前空間を取得する. * @param entityType エンティティタイプ名 * @param col コレクション名 * @return UserDataの名前空間 */ protected String getNameSpace(String entityType, String col) { // NameSpace取得のためにメタデータを取得する TResponse res = Http.request("box/$metadata-$metadata-get.txt") .with("path", "\\$metadata") .with("col", col) .with("accept", "application/xml") .with("token", DcCoreConfig.getMasterToken()) .returns() .statusCode(HttpStatus.SC_OK) .debug(); Pattern pattern = Pattern.compile("Namespace=\"([^\"]+)\">"); Matcher matcher = pattern.matcher(res.getBody()); matcher.find(); return matcher.group(1) + "." + entityType; } /** * リンク確認用のデータを取得する. * @param linkColName コレクション名 * @param linkEntityTypeName エンティティタイプ名 * @param links リンク対象のエンティティタイプ名配列 * @return リンク確認用のデータ */ protected Map<String, Object> getLinkCheckData(String linkColName, String linkEntityTypeName, ArrayList<String> links) { String baseUrl = UrlUtils.userData(cellName, boxName, linkColName, linkEntityTypeName + "('parent')/_"); Map<String, Object> additional = new HashMap<String, Object>(); additional.put("__id", "parent"); for (String link : links) { Map<String, Object> uri = new HashMap<String, Object>(); Map<String, Object> deferred = new HashMap<String, Object>(); uri.put("uri", baseUrl + link); deferred.put("__deferred", uri); additional.put("_" + link, deferred); } return additional; } /** * 4階層のComplexTypeスキーマを作成する. */ protected void create4ComplexTypeSchema() { UserDataComplexTypeUtils.createComplexTypeSchema(UserDataComplexTypeUtils.ENTITY_TYPE_NAME, UserDataComplexTypeUtils.COMPLEX_TYPE_NAME, UserDataComplexTypeUtils.ET_STRING_PROP, UserDataComplexTypeUtils.ET_CT1ST_PROP, UserDataComplexTypeUtils.CT1ST_STRING_PROP); addComplexType(UserDataComplexTypeUtils.COMPLEX_TYPE_NAME, "ct1stComplexProp", "complexType2nd", "ct2ndStrProp"); addComplexType("complexType2nd", "ct2ndComplexProp", "complexType3rd", "ct3rdStrProp"); } /** * コンプレックスタイプを追加する. * @param parentComplex 親ComplexType * @param parentComplexProperty 親ComplexTypeに追加するComplexTypeProperty * @param addComplex 追加ComplexType * @param addComplexProerty 追加ComplexTypeのプロパティ */ protected void addComplexType(String parentComplex, String parentComplexProperty, String addComplex, String addComplexProerty) { // ComplexType作成 UserDataUtils.createComplexType(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, addComplex); // complexTypeProperty作成 UserDataUtils.createComplexTypeProperty(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, parentComplexProperty, parentComplex, addComplex, false, null, null); UserDataUtils.createComplexTypeProperty(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, addComplexProerty, addComplex, EdmSimpleType.STRING.getFullyQualifiedTypeName(), false, null, null); } /** * 5階層のComplexTypeスキーマを削除する. */ protected void delete5ComplexTypeSchema() { deleteComplexType("complexType3rd", "ct3rdComplexProp", "complexType4th", "ct4thStrProp"); deleteComplexType("complexType2nd", "ct2ndComplexProp", "complexType3rd", "ct3rdStrProp"); deleteComplexType(UserDataComplexTypeUtils.COMPLEX_TYPE_NAME, "ct1stComplexProp", "complexType2nd", "ct2ndStrProp"); UserDataComplexTypeUtils.deleteComplexTypeSchema(); } /** * コンプレックスタイプを削除する. * @param parentComplex 親ComplexType * @param parentComplexProperty 親ComplexTypeから削除するComplexTypeProperty * @param delComplex 削除ComplexType * @param delComplexProerty 削除ComplexTypeのプロパティ */ protected void deleteComplexType(String parentComplex, String parentComplexProperty, String delComplex, String delComplexProerty) { String ctplocationUrl = UrlUtils.complexTypeProperty(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, delComplexProerty, delComplex); String pctplocationUrl = UrlUtils.complexTypeProperty(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, parentComplexProperty, parentComplex); String ctlocationUrl = UrlUtils.complexType(Setup.TEST_CELL1, Setup.TEST_BOX1, Setup.TEST_ODATA, delComplex); // 作成したComplexTypePropertyを削除 ODataCommon.deleteOdataResource(ctplocationUrl); ODataCommon.deleteOdataResource(pctplocationUrl); // 作成したComplexTypeを削除 ODataCommon.deleteOdataResource(ctlocationUrl); } /** * 一件取得のレスポンスボディ情報を取得する. * @param json レスポンスボディ * @return ユーザOData情報 */ protected JSONObject getResult(JSONObject json) { return (JSONObject) ((JSONObject) json.get("d")).get("results"); } /** * 一覧取得のレスポンスボディ情報を取得する. * @param userDataId ユーザODataID * @param json レスポンスボディ * @return 指定されたIDのユーザOData情報 */ protected JSONObject getResultsFromId(String userDataId, JSONObject json) { JSONArray results = ((JSONArray) ((JSONObject) json.get("d")).get("results")); for (Object result : results) { JSONObject entity = (JSONObject) result; if (userDataId.equals(entity.get("__id").toString())) { return entity; } } return null; } }