[ 
https://issues.apache.org/jira/browse/IGNITE-13152?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Moldachev Sergey updated IGNITE-13152:
--------------------------------------
    Description: 
h3. Motivation

We have a *@RepositoryConfig* annotation, which have only one parameter: 
*_cacheName_* (can be *simple string* or *spring evaluate expression*). 
Sometimes we need more flexability, for example:
 # We want to create cache by SQL create query.
 # We want to add SQL indexes for entity fields.
 # We want to set dynamic cache expire policy.
 # We want to set ignite instance bean name, in case when we have a more than 
one client node (for example we have a separate clusters).

Now we can't done such things with *@RepositoryConfig*. I suggest to introduce 
the *IgniteSpringDataConfiguration* bean.
h3. Description

The example of *ignite-spring-data configuration in yaml format*:
{code:java}
  ignite-spring-data:
    cache-configurations:
      SomeEntityCache:
        init-sql-script:
          - CREATE TABLE IF NOT EXISTS SomeEntity (
              name VARCHAR PRIMARY KEY,
              executedAt LONG,
              executionTime LONG
            ) WITH 
"template=replicated,atomicity=atomic,value_type=org.company.SomeEntity,cache_name=SomeEntityCache";
          - CREATE INDEX IF NOT EXISTS index_name ON SomeEntity (executedAt);
        touchExpirationTimeout: 6_400_000
        createExpirationTimeout: 6_400_000
        igniteInstanceName: IgniteInstanceBeanName
{code}
This configuration can be represent as *spring configuration property bean*:
{code:yaml}
@Configuration
@ConfigurationProperties(prefix = "ignite-spring-data")
public class IgniteSpringDataProperties {
    /** Map of cache name and configuration. */
    private Map<String, RepositoryConfiguration> cacheConfigurations;

    // getters/setters ommited for readability.

    public static class RepositoryConfiguration {
        /** Initial script. */
        private List<String> initSqlScript = emptyList();

        /** Create expiration timeout. */
        private Long createExpirationTimeout;

        /** Touch expiration timeout. */
        private Long touchExpirationTimeout;

        /** Ignite instance name where cache should be started. */
        private String igniteInstanceName = "SomeDefaultIgniteInstanceName"; // 
Can be null or Optional, place to discusse

        // getters/setters ommited for readability.
    }
}{code}
 This properties we can use in *IgniteRepositoryFactory* for execute initial 
sql scripts:
{code:java}
for (Map.Entry<String, GccRepositoryConfiguration> entry : 
repoProps.getConfigurations().entrySet()) {
    if (ignite.cache(entry.getKey()) == null) {
        for (String qryString : entry.getValue().getInitSqlScript())
            ignite.context().query().querySqlFields(new 
SqlFieldsQuery(qryString), true);
    }
}{code}
In *IgniteRepositoryFactory#getTargetRepository* we can apply expire policy for 
cache:
{code:java}
IgniteCache<Object, Object> cache = ignite.cache(cacheName);

// Apply create expiration timeout.
if (cfg.getCreateExpirationTimeout() != null) {
    ExpiryPolicy plc = CreatedExpiryPolicy.factoryOf(new Duration(MILLISECONDS, 
cfg.getCreateExpirationTimeout())).create();

    cache = cache.withExpiryPolicy(plc);
}

// Apply touch expiration timeout.
if (cfg.getTouchExpirationTimeout() != null) {
    ExpiryPolicy plc = TouchedExpiryPolicy.factoryOf(new Duration(MILLISECONDS, 
cfg.getTouchExpirationTimeout())).create();

    cache = cache.withExpiryPolicy(plc);
}

return getTargetRepositoryViaReflection(metadata, cache); {code}
In the *IgniteRepositoryFactoryBean#createRepositoryFactory* method we can get 
ignite instance by *igniteInstanceName* property and create repository factory 
with specific ignite instance:
{code:java}
/** {@inheritDoc} */
@Override protected RepositoryFactorySupport createRepositoryFactory() {
    IgniteSpringDataProperties springDataProps = 
ctx.getBean(IgniteSpringDataProperties.class);

    try {
        String cacheName = 
getObjectType().getAnnotation(RepositoryConfig.class).cacheName();

        RepositoryConfiguration cfg = springDataProps.configuration(cacheName);

        IgniteEx ignite = (IgniteEx)ctx.getBean(cfg.getIgniteInstanceName());

        return new IgniteRepositoryFactory(ignite, repoProps);
    }
    catch (BeansException ex) {
        // ...
    }
}{code}
h3.  

> Introduce spring-data repository configuration properties
> ---------------------------------------------------------
>
>                 Key: IGNITE-13152
>                 URL: https://issues.apache.org/jira/browse/IGNITE-13152
>             Project: Ignite
>          Issue Type: New Feature
>          Components: springdata
>            Reporter: Moldachev Sergey
>            Assignee: Moldachev Sergey
>            Priority: Major
>             Fix For: 2.9
>
>
> h3. Motivation
> We have a *@RepositoryConfig* annotation, which have only one parameter: 
> *_cacheName_* (can be *simple string* or *spring evaluate expression*). 
> Sometimes we need more flexability, for example:
>  # We want to create cache by SQL create query.
>  # We want to add SQL indexes for entity fields.
>  # We want to set dynamic cache expire policy.
>  # We want to set ignite instance bean name, in case when we have a more than 
> one client node (for example we have a separate clusters).
> Now we can't done such things with *@RepositoryConfig*. I suggest to 
> introduce the *IgniteSpringDataConfiguration* bean.
> h3. Description
> The example of *ignite-spring-data configuration in yaml format*:
> {code:java}
>   ignite-spring-data:
>     cache-configurations:
>       SomeEntityCache:
>         init-sql-script:
>           - CREATE TABLE IF NOT EXISTS SomeEntity (
>               name VARCHAR PRIMARY KEY,
>               executedAt LONG,
>               executionTime LONG
>             ) WITH 
> "template=replicated,atomicity=atomic,value_type=org.company.SomeEntity,cache_name=SomeEntityCache";
>           - CREATE INDEX IF NOT EXISTS index_name ON SomeEntity (executedAt);
>         touchExpirationTimeout: 6_400_000
>         createExpirationTimeout: 6_400_000
>         igniteInstanceName: IgniteInstanceBeanName
> {code}
> This configuration can be represent as *spring configuration property bean*:
> {code:yaml}
> @Configuration
> @ConfigurationProperties(prefix = "ignite-spring-data")
> public class IgniteSpringDataProperties {
>     /** Map of cache name and configuration. */
>     private Map<String, RepositoryConfiguration> cacheConfigurations;
>     // getters/setters ommited for readability.
>     public static class RepositoryConfiguration {
>         /** Initial script. */
>         private List<String> initSqlScript = emptyList();
>         /** Create expiration timeout. */
>         private Long createExpirationTimeout;
>         /** Touch expiration timeout. */
>         private Long touchExpirationTimeout;
>         /** Ignite instance name where cache should be started. */
>         private String igniteInstanceName = "SomeDefaultIgniteInstanceName"; 
> // Can be null or Optional, place to discusse
>         // getters/setters ommited for readability.
>     }
> }{code}
>  This properties we can use in *IgniteRepositoryFactory* for execute initial 
> sql scripts:
> {code:java}
> for (Map.Entry<String, GccRepositoryConfiguration> entry : 
> repoProps.getConfigurations().entrySet()) {
>     if (ignite.cache(entry.getKey()) == null) {
>         for (String qryString : entry.getValue().getInitSqlScript())
>             ignite.context().query().querySqlFields(new 
> SqlFieldsQuery(qryString), true);
>     }
> }{code}
> In *IgniteRepositoryFactory#getTargetRepository* we can apply expire policy 
> for cache:
> {code:java}
> IgniteCache<Object, Object> cache = ignite.cache(cacheName);
> // Apply create expiration timeout.
> if (cfg.getCreateExpirationTimeout() != null) {
>     ExpiryPolicy plc = CreatedExpiryPolicy.factoryOf(new 
> Duration(MILLISECONDS, cfg.getCreateExpirationTimeout())).create();
>     cache = cache.withExpiryPolicy(plc);
> }
> // Apply touch expiration timeout.
> if (cfg.getTouchExpirationTimeout() != null) {
>     ExpiryPolicy plc = TouchedExpiryPolicy.factoryOf(new 
> Duration(MILLISECONDS, cfg.getTouchExpirationTimeout())).create();
>     cache = cache.withExpiryPolicy(plc);
> }
> return getTargetRepositoryViaReflection(metadata, cache); {code}
> In the *IgniteRepositoryFactoryBean#createRepositoryFactory* method we can 
> get ignite instance by *igniteInstanceName* property and create repository 
> factory with specific ignite instance:
> {code:java}
> /** {@inheritDoc} */
> @Override protected RepositoryFactorySupport createRepositoryFactory() {
>     IgniteSpringDataProperties springDataProps = 
> ctx.getBean(IgniteSpringDataProperties.class);
>     try {
>         String cacheName = 
> getObjectType().getAnnotation(RepositoryConfig.class).cacheName();
>         RepositoryConfiguration cfg = 
> springDataProps.configuration(cacheName);
>         IgniteEx ignite = (IgniteEx)ctx.getBean(cfg.getIgniteInstanceName());
>         return new IgniteRepositoryFactory(ignite, repoProps);
>     }
>     catch (BeansException ex) {
>         // ...
>     }
> }{code}
> h3.  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to