-
Notifications
You must be signed in to change notification settings - Fork 198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support including Module and Action in each JDBC session with Oracle JDBC #3183
Conversation
...java/io/micronaut/data/connection/jdbc/operations/DefaultDataSourceConnectionOperations.java
Outdated
Show resolved
Hide resolved
@@ -83,4 +83,29 @@ | |||
*/ | |||
boolean readOnly() default false; | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is ConnectableInterceptor
that is creating custom ConnectionDefinition
I thought we could use this annotation for this purpose so users can customize module and action that will be traced. Don't see other way than use this annotation for the repository that needs to be traced. Without it, we cannot obtain details about class/method being executed when connection is established.
...onnection/src/main/java/io/micronaut/data/connection/interceptor/ConnectableInterceptor.java
Outdated
Show resolved
Hide resolved
Maybe we can introduce |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this makes sense at the annotation level. You likely just want to configure it once for your whole application. I would refactor this logic to be something that can be configured.
Potentially you can add a strategy interface ConnectionCustomizer
or something that is invoked and implement the Oracle specific logic..
One or more customisers could be registered and ordered with @Ordered
...java/io/micronaut/data/connection/jdbc/operations/DefaultDataSourceConnectionOperations.java
Outdated
Show resolved
Hide resolved
...onnection/src/main/java/io/micronaut/data/connection/interceptor/ConnectableInterceptor.java
Outdated
Show resolved
Hide resolved
I thought users might want to customize module and action with some specific naming in some cases and not just use class name/method name. This is why I thought annotation could be used and also option to enable logging for just some classes. But, I agree it wouldn't be the easiest option to configure and something global might make sense.
or
|
I think we could use |
Still the problem persists, we must somehow populate JDBC client info parameters in
And |
ok does this info need to be set before any SQL is executed? |
I guess so, and it seemed that right place to do it is in |
Seems weird if that is the case, what if you want different actions per query |
according to https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_APPLICATION_INFO.html
So |
Then would do this for the method
since |
*/ | ||
@EachBean(DataSource.class) | ||
@Requires(condition = OracleClientInfoCondition.class) | ||
@Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EachBean(DataSource.class)
was not creating this bean until added @Context
. Not sure if this can cause some issues, I would prefer if it could work without @Context
but not sure what is missing.
...c/main/java/io/micronaut/data/connection/jdbc/oracle/OracleClientInfoConnectionListener.java
Outdated
Show resolved
Hide resolved
/** | ||
* @return whether connection should set client info | ||
*/ | ||
boolean enabled() default true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the point of enabled? Just remove the annotation of you don't want to have the values set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If class is annotated and maybe some methods want to be skipped. If you think it makes no sense, I will remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it is removed it makes sense for ConnectionClientInfo
to become a repeatable container so you can just do
@ConnectionClientInfo(name="foo", value ="bar")
@ConnectionClientInfo(name="foo2", value ="baz")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed, removed enabled and added repeatable.
Quality Gate passedIssues Measures |
public interface OracleXEAuthorRepository extends AuthorRepository { | ||
@Override | ||
@Join(value = "books", type = Join.Type.LEFT_FETCH) | ||
@ConnectionClientInfoAttribute(name = "OCSID.ACTION", value = "QueryAuthorByName") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would renamed the annotation to something ahorter
@Retention(RetentionPolicy.RUNTIME) | ||
@Repeatable(ConnClientInfo.class) | ||
@Connectable | ||
public @interface ConnClientInfoAttr { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this to just @ClientInfo
(the word connection
is already in the package) and make the repeatable annotation an annotation named List
that is an inner type. See https://github.com/sergiy-naumovych/Professional-Java-for-Web-Applications/blob/master/Chapter%2021/Eclipse/Spring-JPA/source/production/java/com/wrox/site/validation/NotBlank.java for an example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then repository looks super awkward
@JdbcRepository(dialect = Dialect.ORACLE)
@ClientInfo.List
public interface OracleXEAuthorRepository extends AuthorRepository {
@Override
@Join(value = "books", type = Join.Type.LEFT_FETCH)
@ClientInfo(name = "OCSID.ACTION", value = "QueryAuthorByName")
Author queryByName(String name);
}
Please suggest something new, I have no more ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the annotation needed on the type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because from type we get module and don't have to annotate each method. Then module will be repository class name and action will be method name. But, it can be added on the method as well, for example if users want to name module/action differently.
I would be ok with @ClientInfo
and @ClientInfoAttr
(or @ClientInfoAttribute
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then can't it be:
@JdbcRepository(dialect = Dialect.ORACLE)
@ClientInfo(name = "OCSID.MODULE", value = "SomeModule")
public interface OracleXEAuthorRepository extends AuthorRepository {
@Override
@Join(value = "books", type = Join.Type.LEFT_FETCH)
@ClientInfo(name = "OCSID.ACTION", value = "QueryAuthorByName")
Author queryByName(String name);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but if want to allow fallback for module attribute (to the repository class name) then we do this
@JdbcRepository(dialect = Dialect.ORACLE)
@ClientInfo
public interface OracleXEAuthorRepository extends AuthorRepository {
@Override
@Join(value = "books", type = Join.Type.LEFT_FETCH)
@ClientInfo.Attribute(name = "OCSID.ACTION", value = "QueryAuthorByName")
Author queryByName(String name);
}
and on methods we can override module or action attributes. That's how it looks like now and I think this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think @ClientInfo
without anything makes sense. I would expect exactly what Graeme suggested; otherwise, it needs to be some custom annotation that will transform the method/package into custom client info.
Another option would have some placeholders like MD.METHOD_NAME
which we will replace at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed now since we can use metadata from SqlPreparedQuery
when executing calls and just populate defaults if not provided in the annotations. And will be applied to all Oracle jdbc calls if datasources.<datsource-name>.enable-oracle-client-info=true
Quality Gate passedIssues Measures |
Created as draft, not sure if this approach is correct