Spring Integration RedisLockRegistry example - spring

I want to use Spring Integration RedisLockRegistry . I have some questions about Spring Integration RedisLockRegistry.
Can I use the redisLockRegistry as a Spring bean ? it means my application just a single redisLockRegistry.
I see the RedisLockRegistry implement ExpirableLockRegistry in the version 5.0,
Should I need run the expireUnusedOlderThan method?

I met the same questions and start analyze spring code. So from sources I can state that:
Yes you can create and configure it as a bean of any instance of LockRegistry like RedisLockRegistry, JdbcLockRegistry. For test purposes I'd like even use PassThruLockRegistry
I tried to find any invocation of expireUnusedOlderThan inside Spring without success.
So I have created simple scheduler as following:
#Autowired
private ExpirableLockRegistry lockRegistry;
#Scheduled(fixedDelay=50000)
public void cleanObsolete(){
lockRegistry.expireUnusedOlderThan(50000);
}

Related

How Do I Access The Spring Boot Startup Actuator During A Test

I would like to record the startup information about my application during a Spring Boot test. I have the startup actuator configured and working in Spring Boot 'bootrun' mode. However, when I try to access that actuator during a test using a TestRestTemplate, I get a 404 error.
I have written an example program that demonstrates the problem. The issue isn't with acutators overall as I have the metrics and health actuators working in the same test. Just the startup actuator.
The example code is on GitHub
I have a solution for this so I thought I would post it. For complete details, see the original repo in GitHub and check the solution branch.
One possible way to enable ApplicationStartup data collection during a Spring Boot Test is to create a ContextCustomizer. This allows you to get into the testing context early enough to record all of the data that you are looking for. The ContextCustomizer should have a single static BufferingApplicationStartup that it registers as a singleton bean into the test context's bean factory. It also needs to set the bean factory's ApplicationStartup because that will be passed to the SpringApplication just before it is run.
Here is the snippet of the customizer that holds the key:
#Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Object possibleSingleton = beanFactory.getSingleton(BEAN_NAME);
// The only way it wouldn't be an instance of a BufferingApplicationStartup is if it is null or we haven't
// run yet (and it is the DefaultApplicationStartup). In either case, jam our BufferingApplicationStartup
// in here.
if(!(possibleSingleton instanceof BufferingApplicationStartup)) {
beanFactory.registerSingleton(BEAN_NAME, APPLICATION_STARTUP);
beanFactory.setApplicationStartup(APPLICATION_STARTUP);
}
}
When you do this, make sure you implement a good equals and hashCode for your customizer or else you will break the test context caching and you will refresh your test context with every test class. Since the only relevant part of the customizer is the static BufferingApplicationStartup, I chose to return its hashcode.
Finally, don't forget to add your ContextCustomizerFactory to the src/test/resources/META-INF/spring.factories or else the rest of the Spring Boot testing support won't see your customizer.
Once this is all setup, you can access the Startup Actuator endpoint just like you would any other actuator.

How to do integration tests for #RabbitListener / #RabbitHandler?

I intend to write integration tests to check whether my listener/handlers work properly.
I am using Spring Boot 2.1.9.RELEASE with the according amqp dependency.
I have written a custom sender (publisher) and listener (receiver). When conducting the publishing test I am able to debug into my publisher but I am not able to debug into my receiver which I tried to annotate with #RabbitListener(queues = "myQueue") on method level and with #RabbitListener(queues = "myQueue") on class level in conjunction with #RabbitHandler on method level.
What do I have to prepare to run such integration tests successfully?
I have already googled a lot finding some suggestions using RabbitListenerTestHarness and so on but this never worked. For RabbitListenerTestHarness I always get the error that no such bean could be found.

Spring Integration: Automated integration tests with embedded Broker?

Is it in a way possible to, say in memory, start a broker that can be used to execute automated test cases using Spring Integration MQTT?
I've tried achieving this with ActiveMQ (following https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-messaging.html) but somehow didn't succeed, maybe anyone has a short working example?
It's not Spring Integration (Spring Boot) responsibility to provide some embedded broker for such a protocol. If there is one, we could consider to implement an auto-configuration on the matter , similar to what we do for embedded RDBMS, JMS and MongoDB. You really need to consult ActiveMQ documentation.
Looks like we can do it like this in the test class:
private static BrokerService activeMQBroker;
...
#BeforeClass
public static void setup() throws Exception {
activeMQBroker = new BrokerService();
activeMQBroker.addConnector("mqtt://localhost:1883");
activeMQBroker.setPersistent(false);
activeMQBroker.setUseJmx(false);
activeMQBroker.start();
}
I didn't try it, but this is exactly what I do to test against STOMP.

Applying #PreAuthorize to a method contained in a Spring Roo-generated ITD (*.aj)

I would like to apply the Spring Security #PreAuthorize annotation to a service method defined in the following Spring Roo ITD (without performing a push in refactor of the method):
privileged aspect CurriculumServiceImpl_Roo_Service {
declare #type: CurriculumServiceImpl: #Service;
declare #type: CurriculumServiceImpl: #Transactional;
public Curriculum CurriculumServiceImpl.updateCurriculum(Curriculum curriculum) {
return curriculumRepository.save(curriculum);
}
Is this possible? If so how?
There is a way to achieve this using Spring Roo: See detailed comment here.
To quote the comment:
If you want try and use the PermissionEvaluator, follow these steps
(preferably on a test project).
Run the Roo command "permissionEvaluator --package {the package to which you want to add the PermissionEvaluator} " (security must be
installed first)
Spring Roo will create three files: ApplicationPermissionEvaluator, ApplicationPermissionEvaluator_Roo_PermissionEvaluator,
applicationContext-security-permissionEvaluator.xml.
Add userPermissionEvalutor=true to the #RooService annotation of the service you want to secure.
Spring Roo will append additional criteria to #PreAuthorize e.g. "OR hasPermission(#myDomanObject,
'MyService:deleteMyDomainObjectIsAllowed')"
Add/Update the method hasPermission(Authentication authentication, Object targetObject, Object permission)) in
ApplicationPermissionEvaluator
By the way performing a push in refactor is not a solution for my application. It is always better to go the Roo way and rely on Roo features.

Unit testing with Spring and the Jersey Test Framework

I'm writing some JUnit-based integration tests for a RESTful web service using JerseyTest. The JAX-RS resource classes use Spring and I'm currently wiring everything together with a test case like the following code example:
public class HelloResourceTest extends JerseyTest
{
#Override
protected AppDescriptor configure()
{
return new WebAppDescriptor.Builder("com.helloworld")
.contextParam( "contextConfigLocation", "classpath:helloContext.xml")
.servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class)
.requestListenerClass(RequestContextListener.class)
.build();
}
#Test
public void test()
{
// test goes here
}
}
This works for wiring the servlet, however, I'd like to be able to share the same context in my test case so that my tests can have access to mock objects, DAOs, etc., which seems to call for SpringJUnit4ClassRunner. Unfortunately, SpringJUnit4ClassRunner creates a separate, parallel application context.
So, anyone know how can I create an application context that is shared between the SpringServlet and my test case?
Thanks!
Override JerseyTest.configure like so:
#Override
protected Application configure() {
ResourceConfig rc = new JerseyConfig();
rc.register(SpringLifecycleListener.class);
rc.register(RequestContextFilter.class);
rc.property("contextConfigLocation", "classpath:helloContext.xml");
return rc;
}
For me the SpringServlet was not required, but if you need that you may be able to call rc.register for that too.
I found a couple of ways to resolve this problem.
First up, over at the geek#riffpie blog there is an excellent description of this problem along with an elegant extension of JerseyTest to solve it:
Unit-testing RESTful Jersey services glued together with Spring
Unfortunately, I'm using a newer version of Spring and/or Jersey (forget which) and couldn't quite get it to work.
In my case, I ended up avoiding the problem by dropping the Jersey Test Framework and using embedded Jetty along with the Jersey Client. This actually made better sense in my situation anyway since I was already using embedded Jetty in my application. yves amsellem has a nice example of unit testing with the Jersey Client and embedded Jetty. For Spring integration, I used a variation of Trimbo's Jersey Tests with Embedded Jetty and Spring

Resources