Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

IDIEP-126
Author
Sponsor
Created 10.09.2024
Status
Status
colourGrey
titleDRAFT


Table of Contents

Motivation

When processing data, users want to have access to client non-tabular (not stored in cache structures) data. Example of such data is application attributes - an associative array specified on an application side. Usage scenarios:

  1. To run certain business logic that depends on the value of the attribute (for example, the application language [2], progress monitoring [4]).
  2. To audit changes in the database (for example, CacheInterceptor extracts the user from the attributes and saves it along with data).
  3. To optimize the transfer of parameters to processing functions (for example, multiple QuerySqlFunction use the same parameter and it is convenient to take it from the attributes, rather than transfer it separately to each function).

Another examples of non-tabular data that can be accessed is SecuritySubject, UserAttributes and current Transaction.

The requirements also include:

  1. Attributes must also be accessible from user defined functions (QuerySqlFunction, CacheInterceptor).
  2. Setting attributes via protocols: thick client, thin client, jdbc:thin.
  3. Attribute values ​​can change during the life of the connection (a connection from a connection pool can be sequentially used by different applications).

...

A similar context mechanism exists in Oracle [1] and it's widely used. 

Description

Accessing attributes

  1. SessionContext ApplicationContext is an entrypoint for accessing the attributes.SessionContext can be further extended to retrieve other all non-tabular information, such as SecuritySubject, Transaction, ServiceCallContext, etcdata.
  2. Access requires static methods, because objects injection isn't possible for user functions (QuerySqlFunction are static, CacheInterceptor is a singleton for cache).

...

Code Block
languagejava
/** SessionContextApplicationContext interface. It's an entrypoint for all non-tabular information. */
public class SessionContextApplicationContext {
    /** @return ClientApplication attributes set for current thread. */
    public static @Nullable Map<String, String> getClientAttributesgetAttributes();
 }
 
/** Example, use it in QuerySqlFunction. */
public static class UserDefinedFunctions {
    /** @return Session ID, clientapplication attribute. */
    @QuerySqlFunction
    public static String sessionId() {
        Map<String, String> clnAttrsappAttrs = SessionContextApplicationContext.getClientAttributesgetAttributes();
 
        return clnAttrsappAttrs == null ? null : clnInfoappAttr.getPropertyget(SESSION_ID);
    }
}

Setting attributes

Ignite 

...

  1. Ignite doesn't have support an abstraction "session". It also doesn't restrict usage on Ignite instance from multiple threads by different applications. Also the same thread can be shared between multiple applications.
  2. The application attributes might be used in SQL, Cache API. The ApplicationContext should not depend on the used API.
  3. Then minimal unit of interaction between application and Ignite is a transaction. I suggest to attach the attributes to a transaction

...

  1. .


Code Block
languagejava
// Extends the interface with new public method.
public interface IgniteTransactions {
 	...

    /** @param clnAttrsappAttrs ClientApplication attributes. */
    public IgniteTransactions withClientAttributeswithApplicationAttributes(Map<String, String> clnAttrsappAttrs);
}

// Example of usage.
try (Ignite ign = Ignition.localIgnite()) {
     Map<String, String> clnAttrsappAttrs = F.asMap("SESSION_ID", "1234");
 
     try (Transaction tx = ign.transactions().withClientAttributeswithApplicationAttributes(clnAttrsappAttrs).txStart()) {
        clnAttrs.setAttribute("SESSION_ID", "1234");
 
        ...
    }
}

IgniteClient (Java)

Implementation features:

  1. The Java implementation of the thin client allows working in a multi-threaded environment, unlike the jdbc connection. Then it is suggested to bind the ClientAttributes setting to transaction.
  2. It's required to extend ClientTransactions interface with withClientAttributes method, similar to withLabelClient should mirror the logic of Ignite node.
  3. New feature is needed in the ClientBitmaskFeature protocol).


Code Block
languagejava
// Extends the interface with new public method.
public interface ClientTransactions {
	...

    /** @param clnAttrsappAttrs ClientApplication attributes. */
    public ClientTransactions withClientAttributeswithApplicationAttributes(Map<String, String> clnAttrsappAttrs);
}

// Example of usage.
try (IgniteClient cln = Ignition.startClient(clnCfg)) {
    Map<String, String> clnAttrsappAttrs = F.asMap("SESSION_ID", "1234");

    try (ClientTransaction tx = cln.transactions().withClientAttributeswithApplicationAttributes(clnAttrsappAttrs).txStart()) {
        ...
    }
}

JDBC

The standard jdbc protocol describes the methods Connection#setClientInfo, which allow changing the values ​​of client attributes during the life of the connection [3]. Implementation features:

...

Code Block
languagejava
// JDBC connection to Ignite server.
try (Connection conn = DriverManager.getConnection(URL)) {
    conn.setClientInfo("SESSION_ID", "1234");
 
    ...
}

Spreading context across cluster nodes

  1. Via the QueryStartRequest SQL message protocol (for jdbc, SQL transactions)
  2. Via the transaction protocol for handling inserts (CacheInterceptor), since inserts are not always performed on the request initiator node.

Risks and Assumptions

// Describe project risks, such as API or binary compatibility issues, major protocol changes, etc.

  1. It doesn't work for non-transactional ignite-node SQL but work for JDBC.

Discussion Links

// Links to discussions on the devlist, if applicable.

Reference Links

[1] https://docs.oracle.com/en/database/oracle/oracle-database/19/

...

dbseg/using-application-contexts-to-retrieve-user-information.html#GUID-51C9D5FA-6787-4F05-82EF-A5968BEDC5A0

[2] https://stackoverflow.com/questions/71067911/use-oracles-dbms-session-set-context-in-entity-framework-core

[3] https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/Connection.html#setClientInfo(java.lang.String,java.lang.String)

[4] https://torofimofu.blogspot.com/2014/05/oracle.html

[5] https://docs.oracle.com/database/121/JJDBC/jdbcvers.htm#BABDAEEC

Tickets

// Links or report with relevant JIRA tickets.