Skip to content

Commit

Permalink
Added separate cache support for FHIR Resources (None, Caffeine, Redis).
Browse files Browse the repository at this point in the history
  • Loading branch information
volsch committed Oct 29, 2018
1 parent 32a93d9 commit 0430f6c
Show file tree
Hide file tree
Showing 14 changed files with 617 additions and 12 deletions.
20 changes: 15 additions & 5 deletions app/src/main/resources/default-application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,13 @@ spring:
driver-class-name: @db.driver@
hikari:
maximum-pool-size: 50
cache:
type: caffeine
caffeine:
spec: expireAfterAccess=60s,maximumSize=10000
artemis:
embedded:
enabled: true
server-id: 1
persistent: true
data-directory: ${dhis2.home}/services/fhir-adapter/artemis


hystrix:
command:
default:
Expand All @@ -73,6 +68,21 @@ dhis2.fhir-adapter:
system-authentication:
username: @dhis2.username@
password: @dhis2.password@
cache:
dhis:
type: caffeine
caffeine:
spec: expireAfterAccess=60s,maximumSize=10000
redis:
time-to-live: 60s
key-prefix: fhir-adapter:dhis
fhir:
type: caffeine
caffeine:
spec: expireAfterAccess=120s,maximumSize=10000
redis:
time-to-live: 120s
key-prefix: fhir-adapter:fhir
remote:
processor:
max-search-count: 10000
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
<logger name="org.hibernate" level="warn" />
<logger name="org.hibernate.cfg.AnnotationBinder" level="error" />
<logger name="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver" level="error" />
<logger name="org.springframework.data.repository.config.RepositoryConfigurationDelegate" level="warn" />
<logger name="org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport" level="warn" />

<springProfile name="dev">
<root level="INFO">
Expand Down
4 changes: 4 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,9 @@
<artifactId>artemis-jms-server</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package org.dhis2.fhir.adapter.cache;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisElementReader;
import org.springframework.data.redis.serializer.RedisElementWriter;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Nonnull;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
* Abstract simple cache configuration that can be extended multiple times for specific use cases.
*/
@Validated
public abstract class AbstractSimpleCacheConfig implements Serializable
{
private static final long serialVersionUID = 3060542002074294407L;

@NotNull
private SimpleCacheType type = SimpleCacheType.NONE;

@Valid
@NotNull
private SimpleCaffeineCacheConfig caffeine = new SimpleCaffeineCacheConfig();

@Valid
@NotNull
private SimpleRedisCacheConfig redis = new SimpleRedisCacheConfig();

@Nonnull
public SimpleCacheType getType()
{
return type;
}

public void setType( @Nonnull SimpleCacheType type )
{
this.type = type;
}

@Nonnull
public SimpleCaffeineCacheConfig getCaffeine()
{
return caffeine;
}

public void setCaffeine( @Nonnull SimpleCaffeineCacheConfig caffeine )
{
this.caffeine = caffeine;
}

@Nonnull
public SimpleRedisCacheConfig getRedis()
{
return redis;
}

public void setRedis( @Nonnull SimpleRedisCacheConfig redis )
{
this.redis = redis;
}

@Nonnull
protected <R> CacheManager createCacheManager( @Nonnull ObjectProvider<RedisConnectionFactory> redisConnectionFactoryProvider, @Nonnull RedisSerializer<R> redisSerializer )
{
switch ( getType() )
{
case NONE:
return new NoOpCacheManager();
case CAFFEINE:
final CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCacheSpecification( caffeine.getSpec() );
return caffeineCacheManager;
case REDIS:
return RedisCacheManager.builder( redisConnectionFactoryProvider.getObject() ).cacheDefaults( createRedisCacheConfiguration( redisSerializer ) ).build();
default:
throw new AssertionError( "Unhandled cache type: " + getType() );
}
}

@Nonnull
protected <R> RedisCacheConfiguration createRedisCacheConfiguration( @Nonnull RedisSerializer<R> redisSerializer )
{
return RedisCacheConfiguration.defaultCacheConfig().computePrefixWith( getRedis().getKeyPrefix() )
.entryTtl( getRedis().getTimeToLive() ).serializeValuesWith( new RedisSerializationContext.SerializationPair<R>()
{
@Override
@Nonnull
public RedisElementReader<R> getReader()
{
return RedisElementReader.from( redisSerializer );
}

@Override
@Nonnull
public RedisElementWriter<R> getWriter()
{
return RedisElementWriter.from( redisSerializer );
}
} );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.dhis2.fhir.adapter.cache;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**
* The type of simple cache to be used.
*
* @author volsch
*/
public enum SimpleCacheType
{
NONE, CAFFEINE, REDIS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.dhis2.fhir.adapter.cache;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Nonnull;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
* Simple cache configuration of a Caffeine cache.
*
* @author volsch
*/
@Validated
public class SimpleCaffeineCacheConfig implements Serializable
{
private static final long serialVersionUID = 8632490027903813823L;

@NotNull
private String spec = StringUtils.EMPTY;

@Nonnull
public String getSpec()
{
return spec;
}

public void setSpec( @Nonnull String spec )
{
this.spec = spec;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.dhis2.fhir.adapter.cache;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.springframework.data.redis.cache.CacheKeyPrefix;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Nonnull;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.Duration;

/**
* Simple cache configuration of a Redis cache.
*
* @author volsch
*/
@Validated
public class SimpleRedisCacheConfig implements Serializable
{
private static final long serialVersionUID = 7668397012800515816L;

@NotNull
private Duration timeToLive = Duration.ZERO;

@NotNull
private CacheKeyPrefix keyPrefix = CacheKeyPrefix.simple();

@Nonnull
public Duration getTimeToLive()
{
return timeToLive;
}

public void setTimeToLive( @Nonnull Duration timeToLive )
{
this.timeToLive = timeToLive;
}

@Nonnull
public CacheKeyPrefix getKeyPrefix()
{
return keyPrefix;
}

public void setKeyPrefix( @Nonnull String keyPrefix )
{
this.keyPrefix = new CacheKeyPrefix()
{
@Override
@Nonnull
public String compute( @Nonnull String cacheName )
{
return keyPrefix + ":" + cacheName + ":";
}
};
}
}
Loading

0 comments on commit 0430f6c

Please sign in to comment.