timetoliveseconds ehcache spring boot config is not working - java

Below is my ehcache Config file
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="trans"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="0"
timeToLiveSeconds="6"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
All Spring annotation and configurations are working correctly
#Component
#CacheConfig(cacheNames = {"trans" })
public class MyTransService {
private List<Trans> list;
#Autowired
private EhCacheCacheManager manage;
#PostConstruct
public void setup() {
list = new ArrayList<>();
}
#CachePut
public void addTransaction(Trans trans) {
this.list.add(trans);
}
#CacheEvict(allEntries = true)
public void deleteAll() {
this.list.clear();
}
}
But the cache is not getting clear after timetoliveseconds.
Can someone help me whats wrong in my config.
Below page says that it's bug , but not sure how to fix this ?
I am using spring-boot-starter-cache-2.0.3 version
https://github.com/ehcache/ehcache-jcache/issues/26
there are some similar questions but not providing any solutions

Was able to resolve this using ehcache-JSR-107 wrapper. Below is java config
#Component
public class CachingSetup implements JCacheManagerCustomizer {
#Override
public void customize(CacheManager cacheManager)
{
cacheManager.createCache("trans", new MutableConfiguration<>()
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(SECONDS, 10)))
.setStoreByValue(false)
.setStatisticsEnabled(true));
}
}
Pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId> <!--Starter for using Spring Framework's caching support-->
</dependency>
<dependency>
<groupId>javax.cache</groupId> <!-- JSR-107 API-->
<artifactId>cache-api</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>

If you are expecting the cache content to disappear without interaction, that is indeed not happening. Ehcache does not have a background check for expired items that removes them eagerly.
Instead removal of expired items happens inline, whenever you try to access them or if during a write to the cache, eviction kicks in because the cache is full.

Related

How to apply IP based rate-limiting in spring boot

I want to apply rate-limit on the basis of IP for each (/get)service for my project for e.g each IP can access each service for a particular no. of time i.e 5 times /10 second. I have used bucket4j rate-limiting but it's not working. Does anyone have any idea about it??
this is my application.properties
spring.cache.jcache.config=classpath:ehcache.xml
logging.level.org.ehcache=info
bucket4j.enabled=true
bucket4j.filters[0].cache-name=buckets
bucket4j.filters[0].filter-method=servlet
bucket4j.filters[0].url=.*
bucket4j.filters[0].rate-limits[0].bandwidths[0].capacity=5
bucket4j.filters[0].rate-limits[0].bandwidths[0].time=10
bucket4j.filters[0].rate-limits[0].bandwidths[0].unit=seconds
bucket4j.filters[0].rate-limits[0].expression="getRemoteAddress()"
bucket4j.filters[0].rate-limits[0].bandwidths[0].fixed-refill-interval=0
bucket4j.filters[0].rate-limits[0].bandwidths[0].fixed-refill-interval-unit=seconds
this is encache.xml
<config xmlns='http://www.ehcache.org/v3'
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
<cache alias="buckets">
<expiry><ttl unit="seconds">6</ttl></expiry>
<heap unit="entries">2000</heap>
<jsr107:mbeans enable-statistics="true"/>
</cache>
</config>
pom.xml
<dependency>
<groupId>com.giffing.bucket4j.spring.boot.starter</groupId>
<artifactId>bucket4j-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<scope>runtime</scope>
</dependency>
server Initializer
#EnableCaching
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(EwseparationApplication.class);
}
}
I was having the same issue. It looks like there was an issue opened with the bucket4j spring boot starter github project about this (link).
I converted my application.properties to application.yml as the individual reported in the issue and my rate limit started working. I'm not sure what the actual issue is (why application.yml works and application.properties does not). I kindof prefer the properties format over yml.
you can use .yaml as .properties is still having some issue in recognizing the tags

Spring MVC - configuring Ehcache - Not caching

I am trying to integrate Ehcache with my Java Spring MVC Web Applications. I have followed the instructions from the following article:
https://dzone.com/articles/implementing-ehcache-using.
I have added the following dependency to my pom.xml file:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
</dependency>
My ehcache.xml is as follows:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="swcmRestData"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
I have the following entries in my root-context.xml:
<!-- EhCache Configuration -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="true"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
And I have a method for which I want to enable ehCache:
#Cacheable(value="swcmRestData", key="url")
public <T> T getEntity(String url, java.lang.Class<T> gt) throws RestException
{
T t = restClientService.getEntity(url, gt);
return t;
}
I want the data to be retrieved from the ehCache if the same url is passed to the specified method. I do not get any errors while running the code. But looks like the caching is not working. Is there anything that I am missing here
Two things that could be the cause of the problem:
You are missing the Spring configuration so that there is a link between the defined beans and the caching annotation. Effectively that's point 2 in the article you link which you do not mention here.
As suggested in comments, the method you are caching is called from within the same class. That's a limitation of Spring AOP implementation when using proxies. If you configure Spring to do bytecode weaving it will work.
If none of the above are the source of error, please provide more information on your setup.

Spring boot AOP Aspect not being invoked

I'm trying to intercept rest service calls with an aspect in the following manner
package mypackage.services.Service;
#Component
public class Service {
#Override
public Response helloService() {
return handleResult("Hello test " + new Date());
}
}
#Component
#Aspect
public class AuditLog {
#Before("execution(* mypackage.services.Service.*(..))")
public void beforeServcie(JoinPoint jp){
log.info("Before ",jp.getSignature().getName());
}
}
I'm using the following maven dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
This maven plugin
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.0</version>
</plugin>
And my configuration xml contains
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="mypackage"/>
<aop:aspectj-autoproxy proxy-target-class="true" />
also in the Application class I've added the following annotation
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass=true)
public class Configuration{
...
}
On startup, by logging beans in the ApplicationContext, I can see that the aspect class "AuditLog" is being created.
I've set 2 breakpoints, but the debugger does not stop at the "beforeServcie" method but it does stop at the "helloService".
What am I missing?
Try this
execution(* mypackage.services.Service.*.*(..))
instead of
execution(* mypackage.services.Service.*(..))
If you are using spring-boot then instead of automatically adding dependency jars you can do
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
If you're using XML config <aop:aspectj-autoproxy ... /> then no need to have #EnableAspectJAutoProxy. It probably doesn't matter since AFAIK XML config wins over annotation config but better to avoid duplication
I am not quite sure why do you need aspectj-maven-plugin since Spring implements AOP by proxy and AFAIK this plugin is only needed for compile-time, post compile-time or load time weaving which are different concepts, see Spring AOP vs AspectJ
Now all the above mentioned points may not resolve your issue but the following might
execution(* mypackage.services.Service.Service.*(..))
And, don't set proxyTargetClass=true, let it be default false.
Explanation
The format is execution(<return type> <package name>.<class name>.<method name>(..)
The package name here is mypackage.services.Service and the class name is Service.

Spring Boot, #Autowire into an unmanaged class using #Configurable and load time weaving

I have a collection of unmanaged classes that I are instantiated outside of Spring. I've been attempting to use Spring AOP with load time weaving to #Autowire a bean into these classes but have so far not had any luck.
I've been testing using Tomcat 8 and Spring Boot 1.2.0.
My #Configuration where I attempt to set up class looks like this:
#Configuration
#PropertySource("classpath:application.properties")
#EnableSpringConfigured
#EnableLoadTimeWeaving
public class Config
Inside Config I define the bean I want to #Auotwire into my unmanaged classes:
#Bean
public StateProvider stateProvider() {
//setup bean
return new DynamoStateProviderImpl( );
}
The unmanaged bean looks like this:
#Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true, preConstruction = true)
public class StateOutput implements UnifiedOutput {
#Autowired
private StateProvider stateProvider;
And I have the following deps inside my pom
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-agent</artifactId>
<version>2.5.6.SEC03</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
So far, I have not been able to see anything injected into stateProvider or been able to pull any info from the logs. I've also attempted setter style injection using
#Autowired
public void setStateProvider(StateProvider stateProvider){
this.stateProvider = stateProvider;
}
Thanks
In order to instrument LTW you'll need to either use the javaagent or place spring-tomcat-weaver.jar in the \lib folder and set up TomcatInstrumentableClassLoader in context.xml.
javaagent example:
-javaagent:"${settings.localRepository}/org/springframework/spring-agent/2.5.6.SEC03/spring-agent-2.5.6.SEC03".jar
ClassLoader example:
<Context>
<Loader loaderClass="org.springframework.instrument.classl oading.tomcat.TomcatInstrumentableClassLoader" />
</Context>

Spring #Value annotation not working with mockito mock

I am using spring #Value annotation and setting values for some fields in class A.
I am writing unit tests for this class A. In the test class, I am annotating the reference for class A with Mockito #Spy. I am setting the values as system properties and then invoking MockitoAnnotations.initMocks(this).
My expectation is the spied object will have the fields initialized with the values from system properties via #Value annotation. But this is not happening.
Please anybody could explain?
I have a similar test and I'm using the following relevant code:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations="/context.xml")
public class ContextTest {
private boolean started = false;
#Spy
#Autowired
private Baz baz;
#Before
public void before() {
if (!started) {
MockitoAnnotations.initMocks(this);
started = true;
}
}
#Test
public void spy() {
Assert.assertEquals("value", baz.getProperty());
Mockito.verify(baz).getProperty();
}
}
Basically it will let spring process the test annotations (due to SpringJUnitRunner) and afterwards let Mockito process them (explicitly invoked MockitoAnnotations.initMocks(instanceOfTestClass)).
Other files to have a complete test
simple Baz.java spring class:
package foo.bar;
import org.springframework.beans.factory.annotation.Value;
public class Baz {
#Value("${property:test}")
private String property;
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
}
the context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>my.properties</value>
</property>
</bean>
<bean id="baz" class="foo.bar.Baz" />
</beans>
my.property file:
property=value
and the maven (pom.xml) file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-test</groupId>
<artifactId>my.spring.test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
the file structure is:
+ spring-test
- pom.xml
+ src/main/java
+ foo.bar
- Baz.java
+ src/main/resources
- context.xml
- my.properties
+ src/test/java
+ foo.bar
- ContextTest.java
Mockito is not Spring aware! And will never be! You'll always have to init these kind of injection yourself as it is not pure java.
However you can take a look at springockito, it is a spring extension that enable some interesting usage of Mockito with Spring. But you'll have to create a Spring context for the test.
Note that using a spring context in a JUnit test is like crafting an integration test.

Categories

Resources