Skip to content

Commit

Permalink
Tiga (#467)
Browse files Browse the repository at this point in the history
Implementation: Changed to pass OiyoInfo instance from the outside.
Changed to return URI with FQN.
Added messages regarding autoCommit, jdbcFetchSize, filterEqAutoSelect.
Added log.trace where EntityCollection is expected to take a time.
  • Loading branch information
igapyon authored May 26, 2021
1 parent 34032ba commit 9c153d6
Show file tree
Hide file tree
Showing 15 changed files with 114 additions and 48 deletions.
18 changes: 17 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
# Release 1.18 (2021-05-26)

## EN

- Implementation: Changed to pass OiyoInfo instance from the outside.
- Changed to return URI with FQN.
- Added messages regarding autoCommit, jdbcFetchSize, filterEqAutoSelect.
- Added log.trace where EntityCollection is expected to take a time.

## JA

- 実装: OiyoInfo インスタンスを外側から引き渡すよう変更
- URIをFQNで戻すよう変更
- autoCommit, jdbcFetchSize, filterEqAutoSelect のメッセージを追加
- EntityCollection で時間がかかると予見される箇所に log.trace を追加

# Release 1.17 (2021-05-25)

## EN

- Some JSON params are added to `oiyokan-settings.json`: autoCommit, jdbcFetchSize, filterEqAutoSelect
- Some JSON params are added to `oiyokan-settings.json`: autoCommit, jdbcFetchSize, filterEqAutoSelect.
- Added ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY to collection Statement.
- Use java.sql.Statement for parameterless queries.

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>jp.igapyon.oiyokan</groupId>
<artifactId>oiyokan</artifactId>
<version>1.17.20210525f-SNAPSHOT</version>
<version>1.17.20210526a-SNAPSHOT</version>
<name>oiyokan</name>
<description>Oiyokan is a simple OData v4 Server. (based on Apache
Olingo / h2 database)</description>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/jp/oiyokan/OiyokanConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class OiyokanConstants {
/**
* Oiyokan のバージョン番号
*/
public static final String VERSION = "1.17.20210525f";
public static final String VERSION = "1.17.20210526a";

/**
* 暗号化で利用するパスフレーズ。環境変数 OIYOKAN_PASSPHRASE で上書き動作。
Expand Down
53 changes: 32 additions & 21 deletions src/main/java/jp/oiyokan/OiyokanEdmProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,34 +48,43 @@
public class OiyokanEdmProvider extends CsdlAbstractEdmProvider {
private static final Log log = LogFactory.getLog(OiyokanEdmProvider.class);

private OiyoInfo oiyoInfo = null;

/**
* OiyokanSettings を singleton に記憶.
* OiyoSettings を singleton に記憶.
*/
private static volatile OiyoInfo oiyoInfo = null;
private static volatile OiyoSettings oiyoSettings = null;

/**
* Oiyokan が内部的に利用するデータベースがセットアップ済みかどうか。
*/
private static volatile boolean isKanDatabaseSetupDone = false;

public OiyokanEdmProvider(OiyoInfo oiyoInfo) {
this.oiyoInfo = oiyoInfo;
}

/**
* OiyoInfo (OiyokanSettings 設定情報を含む) を singleton に取得.
*
* このパッケージからのみアクセスを許容。
*
* @return OiyoInfo OiyokanSettings instanceを含む. 参照のみで利用.
* @return OiyoSettings instance. 参照のみで利用.
* @throws ODataApplicationException ODataアプリ例外が発生した場合.
*/
static synchronized OiyoInfo getOiyoInfoInstance() throws ODataApplicationException {
static synchronized void setupOiyoSettingsInstance(final OiyoInfo oiyoInfo) throws ODataApplicationException {
if (oiyoInfo.getSettings() != null) {
return; /* 何もする必要なし */
}

// singleton by static synchronized.
if (oiyoInfo == null) {
final OiyoInfo wrk = new OiyoInfo();
wrk.setSettings(OiyoInfoUtil.loadOiyokanSettings(wrk));
if (oiyoSettings == null) {
final OiyoSettings wrk = OiyoInfoUtil.loadOiyokanSettings(oiyoInfo);
// ロードが終わってから変数に値をセット。念には念を)
oiyoInfo = wrk;
oiyoSettings = wrk;
}

return oiyoInfo;
oiyoInfo.setSettings(oiyoSettings);
}

/**
Expand All @@ -90,6 +99,9 @@ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODa
log.trace("OiyokanEdmProvider#getEntityType(" + entityTypeName + ")");

try {
// シングルトンな OiyoSettings を利用。
setupOiyoSettingsInstance(oiyoInfo);

OiyoSettingsEntitySet entitySet = null;
final OiyoSettings settingsOiyokan = oiyoInfo.getSettings();
for (OiyoSettingsEntitySet look : settingsOiyokan.getEntitySet()) {
Expand All @@ -104,8 +116,7 @@ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODa
OiyokanMessages.IY7119_CODE, Locale.ENGLISH);
}

OiyoBasicJdbcEntityTypeBuilder entityTypeBuilder = new OiyoBasicJdbcEntityTypeBuilder(
OiyokanEdmProvider.getOiyoInfoInstance(), entitySet);
OiyoBasicJdbcEntityTypeBuilder entityTypeBuilder = new OiyoBasicJdbcEntityTypeBuilder(oiyoInfo, entitySet);
CsdlEntityType csdlEntityType = entityTypeBuilder.getEntityType();

if (log.isTraceEnabled()) {
Expand Down Expand Up @@ -143,8 +154,8 @@ public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String enti
log.trace("OiyokanEdmProvider#getEntitySet(" + entitySetName + ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
setupOiyoSettingsInstance(oiyoInfo);

final FullQualifiedName fqn = new FullQualifiedName(oiyoInfo.getSettings().getNamespace(),
oiyoInfo.getSettings().getContainerName());
Expand Down Expand Up @@ -185,8 +196,8 @@ public CsdlEntityContainer getEntityContainer() throws ODataApplicationException
log.trace("OiyokanEdmProvider#getEntityContainer()");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
setupOiyoSettingsInstance(oiyoInfo);

final CsdlEntityContainer csdlEntityContainer = new CsdlEntityContainer();
csdlEntityContainer.setName(oiyoInfo.getSettings().getContainerName());
Expand All @@ -200,7 +211,7 @@ public CsdlEntityContainer getEntityContainer() throws ODataApplicationException
// [IY1001] Start Oiyokan server.
log.info(OiyokanMessages.IY1001 + " (Oiyokan: " + OiyokanConstants.VERSION + ")");

for (OiyoSettingsDatabase settingsDatabase : getOiyoInfoInstance().getSettings().getDatabase()) {
for (OiyoSettingsDatabase settingsDatabase : oiyoInfo.getSettings().getDatabase()) {
// [IY1051] Check JDBC Driver
log.info(OiyokanMessages.IY1051 + ": " + settingsDatabase.getJdbcDriver());

Expand Down Expand Up @@ -232,7 +243,7 @@ public CsdlEntityContainer getEntityContainer() throws ODataApplicationException
}

// Oiyokan の動作で利用する内部データベースをセットアップ.
OiyokanKanDatabase.setupKanDatabase(OiyokanEdmProvider.getOiyoInfoInstance());
OiyokanKanDatabase.setupKanDatabase(oiyoInfo);
isKanDatabaseSetupDone = true;
}

Expand Down Expand Up @@ -260,8 +271,8 @@ public List<CsdlSchema> getSchemas() throws ODataApplicationException {
log.trace("OiyokanEdmProvider#getSchemas()");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
setupOiyoSettingsInstance(oiyoInfo);

// CSDLスキーマを作成.
final CsdlSchema newCsdlSchema = new CsdlSchema();
Expand Down Expand Up @@ -312,8 +323,8 @@ public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityCo
log.trace("OiyokanEdmProvider#getEntityContainerInfo()");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
setupOiyoSettingsInstance(oiyoInfo);
final FullQualifiedName fqn = new FullQualifiedName(oiyoInfo.getSettings().getNamespace(),
oiyoInfo.getSettings().getContainerName());

Expand Down
18 changes: 16 additions & 2 deletions src/main/java/jp/oiyokan/OiyokanEntityCollectionProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ public class OiyokanEntityCollectionProcessor implements EntityCollectionProcess
*/
private ServiceMetadata serviceMetadata;

private OiyoInfo oiyoInfo = null;

public OiyokanEntityCollectionProcessor(OiyoInfo oiyoInfo) {
this.oiyoInfo = oiyoInfo;
}

/**
* 初期化タイミングにて ODataやサービスメタデータの情報を記憶. {@inheritDoc}
*
Expand Down Expand Up @@ -102,8 +108,8 @@ public void readEntityCollection(ODataRequest request, ODataResponse response, /
+ request.getRawQueryPath() + ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = OiyokanEdmProvider.getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
OiyokanEdmProvider.setupOiyoSettingsInstance(oiyoInfo);
if (oiyoInfo.getRawBaseUri() == null) {
oiyoInfo.setRawBaseUri(request.getRawBaseUri());
}
Expand All @@ -121,7 +127,9 @@ public void readEntityCollection(ODataRequest request, ODataResponse response, /

// 要素セットの指定をもとに要素コレクションを取得.
// これがデータ本体に該当.
log.trace("OiyokanEntityCollectionProcessor#readEntityCollection: eCollection: begin.");
EntityCollection eCollection = entityCollectionBuilder.build(edmEntitySet, uriInfo);
log.trace("OiyokanEntityCollectionProcessor#readEntityCollection: eCollection: end.");

// 指定のレスポンスフォーマットに合致する直列化を準備.
ODataSerializer serializer = odata.createSerializer(responseFormat);
Expand Down Expand Up @@ -150,6 +158,9 @@ public void readEntityCollection(ODataRequest request, ODataResponse response, /
|| (entitySet.getFilterEqAutoSelect() == null || !entitySet.getFilterEqAutoSelect())) {
builder.select(uriInfo.getSelectOption());
} else {
// [IY2151] DEBUG: filterEqAutoSelect: (experimental) Auto select property if
// `$filter` specify property with eq.
log.debug(OiyokanMessages.IY2151);
// ここにはEQ対象項目を$selectに自動で加える特殊モードが実装されている。
String propNames = "";
for (int index = 0; index < eCollection.getEntities().size(); index++) {
Expand Down Expand Up @@ -187,13 +198,16 @@ public void readEntityCollection(ODataRequest request, ODataResponse response, /
}
}

log.trace("OiyokanEntityCollectionProcessor#readEntityCollection: serializer.entityCollection: begin.");
SerializerResult serResult = serializer.entityCollection( //
serviceMetadata, edmEntityType, eCollection, builder.build());
log.trace("OiyokanEntityCollectionProcessor#readEntityCollection: serializer.entityCollection: end.");

// OData レスポンスを返却.
response.setContent(serResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
log.trace("OiyokanEntityCollectionProcessor#readEntityCollection: end response.");
} catch (ODataApplicationException | ODataLibraryException ex) {
// [IY9521] WARN: EntityCollectionProcessor.readEntityCollection: exception
// caught
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/jp/oiyokan/OiyokanEntityProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class OiyokanEntityProcessor implements EntityProcessor {

private OData odata;
private ServiceMetadata serviceMetadata;
private OiyoInfo oiyoInfo = null;

public OiyokanEntityProcessor(OiyoInfo oiyoInfo) {
this.oiyoInfo = oiyoInfo;
}

/**
* {@inheritDoc}
Expand All @@ -84,8 +89,8 @@ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uri
+ ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = OiyokanEdmProvider.getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
OiyokanEdmProvider.setupOiyoSettingsInstance(oiyoInfo);
if (oiyoInfo.getRawBaseUri() == null) {
oiyoInfo.setRawBaseUri(request.getRawBaseUri());
}
Expand Down Expand Up @@ -151,8 +156,8 @@ public void createEntity(ODataRequest request, ODataResponse response, UriInfo u
+ ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = OiyokanEdmProvider.getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
OiyokanEdmProvider.setupOiyoSettingsInstance(oiyoInfo);
if (oiyoInfo.getRawBaseUri() == null) {
oiyoInfo.setRawBaseUri(request.getRawBaseUri());
}
Expand Down Expand Up @@ -231,8 +236,8 @@ public void updateEntity(ODataRequest request, ODataResponse response, UriInfo u
+ ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = OiyokanEdmProvider.getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
OiyokanEdmProvider.setupOiyoSettingsInstance(oiyoInfo);
if (oiyoInfo.getRawBaseUri() == null) {
oiyoInfo.setRawBaseUri(request.getRawBaseUri());
}
Expand Down Expand Up @@ -371,8 +376,8 @@ public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo u
+ ")");

try {
// シングルトンな OiyoInfo を利用。
final OiyoInfo oiyoInfo = OiyokanEdmProvider.getOiyoInfoInstance();
// シングルトンな OiyoSettings を利用。
OiyokanEdmProvider.setupOiyoSettingsInstance(oiyoInfo);
if (oiyoInfo.getRawBaseUri() == null) {
oiyoInfo.setRawBaseUri(request.getRawBaseUri());
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/jp/oiyokan/OiyokanMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class OiyokanMessages {
public static final String IY1065 = "[IY1065] INFO: SQL collect: elapsed";
public static final String IY1066 = "[IY1066] INFO: SQL exec";
public static final String IY1067 = "[IY1067] INFO: SQL exec: elapsed";
public static final String IY1068 = "[IY1068] DEBUG: JDBC: setFetchSize";

// Entity
public static final String IY1071 = "[IY1071] INFO: ENTITY: READ";
Expand Down Expand Up @@ -94,6 +95,8 @@ public class OiyokanMessages {
public static final String IY2112 = "[IY2112] UNEXPECTED: UriValidationException occured.";
public static final int IY2112_CODE = HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode();

public static final String IY2151 = "[IY2151] DEBUG: filterEqAutoSelect: (experimental) Auto select property if `$filter` specify property with eq.";

////////////////////////////////////////////////////////////////////////////////
// IY25XX : EntityCollection - TIMEOUT
public static final String IY2501 = "[IY2501] SQL timeout at count query";
Expand Down Expand Up @@ -271,6 +274,7 @@ public class OiyokanMessages {
public static final String IY7174 = "[IY7174] INFO: load oiyokan settings";
public static final String IY7175 = "[IY7175] DEBUG: DB set connection transaction isolation.";
public static final String IY7176 = "[IY7176] DEBUG: DB init sql exec.";
public static final String IY7181 = "[IY7181] DEBUG: JDBC: call setAutoCommit";

////////////////////////////////////////////////////////////////////////////////
// Authz (Server Side)
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/jp/oiyokan/OiyokanOdata4RegisterImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;

import jp.oiyokan.common.OiyoInfo;

/**
* Oiyokan (OData v4 server) を Spring Boot の Servlet として登録.
*
Expand All @@ -43,13 +45,14 @@ public class OiyokanOdata4RegisterImpl {
/**
* Oiyokan (OData v4 server) を Spring Boot の Servlet として登録.
*
* @param oiyoInfo Oiyokan 情報.
* @param req HTTPリクエスト.
* @param resp HTTPレスポンス.
* @param odataRootPath ルートパス名. ex: "/odata4.svc".
* @throws ServletException サーブレット例外.
*/
public static void serv(final HttpServletRequest req, final HttpServletResponse resp, final String odataRootPath)
throws ServletException {
public static void serv(final OiyoInfo oiyoInfo, final HttpServletRequest req, final HttpServletResponse resp,
final String odataRootPath) throws ServletException {
if (resp != null) {
// デフォルト挙動として no-cacne, no-store で動作させる.
resp.setHeader("Cache-Control", "no-cache, no-store");
Expand All @@ -74,14 +77,14 @@ public static void serv(final HttpServletRequest req, final HttpServletResponse
OData odata = OData.newInstance();

// EdmProvider を登録.
ServiceMetadata edm = odata.createServiceMetadata(new OiyokanEdmProvider(), new ArrayList<>());
ServiceMetadata edm = odata.createServiceMetadata(new OiyokanEdmProvider(oiyoInfo), new ArrayList<>());
ODataHttpHandler handler = odata.createHandler(edm);

// EntityCollectionProcessor を登録.
handler.register(new OiyokanEntityCollectionProcessor());
handler.register(new OiyokanEntityCollectionProcessor(oiyoInfo));

// EntityProcessor を登録.
handler.register(new OiyokanEntityProcessor());
handler.register(new OiyokanEntityProcessor(oiyoInfo));

// Spring と Servlet の挙動を調整.
handler.process(new HttpServletRequestWrapper(req) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public OiyoBasicJdbcEntityCollectionBuilder(OiyoInfo oiyoInfo) {
public EntityCollection build(EdmEntitySet edmEntitySet, UriInfo uriInfo) throws ODataApplicationException {
final EntityCollection entityCollection = new EntityCollection();

OiyokanEdmProvider provider = new OiyokanEdmProvider();
OiyokanEdmProvider provider = new OiyokanEdmProvider(oiyoInfo);
if (!edmEntitySet.getEntityContainer().getName().equals(provider.getEntityContainer().getName())) {
// Container 名が不一致. 処理せずに戻します.
return entityCollection;
Expand Down Expand Up @@ -293,6 +293,8 @@ public void processCollectionQuery(UriInfo uriInfo, String entitySetName, Connec
? connTargetDb.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
: connTargetDb.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY))) {
if (entitySet.getJdbcFetchSize() != null) {
// [IY1068] DEBUG: JDBC: setFetchSize
log.debug(OiyokanMessages.IY1068 + ": " + entitySet.getJdbcFetchSize());
stmt.setFetchSize(entitySet.getJdbcFetchSize());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ public Entity updateEntityDataPatch(UriInfo uriInfo, OiyoSettingsEntitySet entit
log.trace("[database transaction] BEGIN database transaction.");
if (database.getAutoCommit() == null || database.getAutoCommit()) {
// autoCommit 指定なし、または、true の場合、autoCommitをfalseに設定.
log.trace("conn.setAutoCommit(false)");
connTargetDb.setAutoCommit(false);
}
boolean isTranSuccessed = false;
Expand Down Expand Up @@ -295,6 +296,7 @@ public Entity updateEntityDataPatch(UriInfo uriInfo, OiyoSettingsEntitySet entit
log.trace("[database transaction] END database transaction.");
if (database.getAutoCommit() == null || database.getAutoCommit()) {
// autoCommit 指定なし、または、true の場合、autoCommitをtrueに戻す。
log.trace("conn.setAutoCommit(true)");
connTargetDb.setAutoCommit(true);
}
}
Expand Down
Loading

0 comments on commit 9c153d6

Please sign in to comment.