Extending AbstractCassandraConfiguration is ignoring application.yml auto configuration - spring-data-cassandra

I'm using spring-boot-starter-data-cassandra-reactive(version 3.2.4) and have provided all the spring.data.cassaandra properties is application.yml. It works fine. But I need to add some customCassandraConversion so I extended AbstractCassandraConfiguration. The moment I extend AbstractCassandraConfiguration the application.yml aka the CassandraAutoConfiguration stops working. Is there another way to to configure customConversions without overriding AbstractCassandraConfiguration. Or how can I get both working? I'm using spring-boot 2.5.4

You can register your custom conversions as a Bean in config and they'll be picked up by AbstractCassandraConfiguration.
#Bean
public CassandraCustomConversions customConversions() {
// Add your converters here
List<?> converters = Arrays.asList(...)
return new CassandraCustomConversions(convert));
}

Related

How to set expire-groups-upon-completion with #Aggregator annotation?

The reference manul talked about how to set this in XML, and I saw the Jira issue for advanced configuration for #Aggregator completed but not seeing those advanced properties. So if using annotation, how to set expire group?
Well, according that JIRA ticket there is indeed a sample in the Reference Manual:
#ServiceActivator(inputChannel = "aggregatorChannel")
#Bean
public MessageHandler aggregator(MessageGroupStore jdbcMessageGroupStore) {
AggregatingMessageHandler aggregator =
new AggregatingMessageHandler(new DefaultAggregatingMessageGroupProcessor(),
jdbcMessageGroupStore);
aggregator.setOutputChannel(resultsChannel());
aggregator.setGroupTimeoutExpression(new ValueExpression<>(500L));
aggregator.setTaskScheduler(this.taskScheduler);
return aggregator;
}
And there is an explicit note on the matter:
Annotation configuration (#Aggregator and others) for the Aggregator component covers only simple use cases, where most default options are sufficient. If you need more control over those options using Annotation configuration, consider using a #Bean definition for the AggregatingMessageHandler and mark its #Bean method with #ServiceActivator
Even would be better to use this:
Starting with the version 4.2 the AggregatorFactoryBean is available, to simplify Java configuration for the AggregatingMessageHandler.
Seems for me everything is covered in the Docs. Is anything missed?
I mean the AggregatorFactoryBean has an option you need:
public void setExpireGroupsUponCompletion(Boolean expireGroupsUponCompletion) {
Is that not enough?

Seed value in Weld CDI custom scope

Coming from a Guice background, I know that it is possible to seed an object value from a scope using.
scope.seed(Key.get(SomeObject.class), someObject);
I suppose one could do this by registering a Bean that gets a value from an AbstractBoundContext, but examples just seeding one value from a Custom Scope seem hard to find. How do I create a custom scope that seeds a value that can be injected elsewhere?
Edit:
I am currently using the following workaround, that can be injected in an interceptor to set the Configuration when entering the scope, and can then be injected through its thread local provider. I am still looking for options that feel less hacky / are more integrated with the scope/scope context system in Weld though.
#Singleton
public class ConfigurationProducer {
private final InheritableThreadLocal<Configuration> threadLocalConfiguration =
new InheritableThreadLocal<>();
#Produces
#ActiveDataSet
public ConfigurationConfiguration() {
return threadLocalConfiguration.get()
}
public void setConfiguration(Configuration configuration) {
threadLocalConfiguration.set(configuration);
}
}
The answer is to register a custom bean with the AfterBeanDiscovery event, like so:
event.addBean()
.createWith(ctx -> commandContext.getCurrentCommandExecution())
.addType(CommandExecution.class)
.addQualifier(Default.Literal.INSTANCE)
.scope(CommandScoped.class)
.beanClass(CommandExtension.class);
There is a quite sophisticated example available at https://github.com/weld/command-context-example

constructor parameters on controller actions

I am trying to create a custom manager which is passed in the controller when it is being called and I am having troubles understanding the current implementation of new MVC5 project in c#.
Here is the default implementation:
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
above all of that are declarations for them:
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
Now from my understanding the SignInManager and UserManager get created when application gets created for the first time in Startup.Auth.cs which looks like this:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time.
I have 2 questions. Question 1 is is anything I said above wrong and Do I have a wrong understanding of how MVC5 works?
Question2: How is UserManager and SignInManager generated and passed in the controller? Where is the code that creates that first instance of the manager and passes it in the controller? I am assuming it is app.CreatePerOwnContext that does it. If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project? Will my code get the latest data from the database if I do this and not cache it?
The code you're showing is coming from the IMO very ugly MVC5 template, which works out of the box but does some ugly things.
This constructor:
public AccountController(ApplicationUserManager userManager,
ApplicationSignInManager signInManager)
makes you think OWIN automagically injects the managers for you. But in fact this is not the case. That is why the template comes with the ugly properties you supplied in the questions. When you do not change anything to the template, the default constructor is called (also present in the template). To try it, just delete, or comment, the default constructor and you'll see the AccountController can't be created anymore.
So what is actually happening there is that both managers are located using the Service Locator anti pattern in the getters of the supplied properties.
So now whenever I call UserManager I will get that first instance that was created when project ran for the first time?
No this is not the case. What this line:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
does, is creating a delegate to the Create method of both managers. The managers are cached within an Owin Request. The next request the delegates are called again and you get a fresh ApplicationUserManager etc.
To be a little bit more verbose this line could be rewritten as:
Func<ApplicationUserManager> userManagerFactory = () => ApplicationUserMangager.Create();
app.CreatePerOwinContext<ApplicationUserManager>(userManagerFactory);
So if you would a breakpoint here:
public ApplicationUserManager UserManager
{
get
{
// place breakpoint here
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
// ....
You would see that while stepping through the code, you will hit the line where you created the UserManagerFactory which in his turn will call the Create() method of the ApplicationUserManager.
How is UserManager and SignInManager generated and passed in the controller
It isn't! You would need to use dependency injection for that.
If so, can I then just create my own Manager and then register it with Owin in the same fashion and reuse throughout the project
Yes you can. You can completely refactor the ApplicationUserManager you also got 'for free' in the template. As long as you supply a factory method to the 'CreatePerOwinContext' extension method.
Will my code get the latest data from the database if I do this and not cache it?
The instances are cached on per request base. So each request you will get a new one, with a new DbContext etc.
I'm unsure how familiar you are with dependency injection but MVC5 is a pretty easy framework to start with it, IMO.
I once wrote a blogpost how to configure my DI container of choice (Simple Injector) to use with the MVC5 template.
I also wrote several answers here on SO regarding this template: specifically this one, should interest you. This one is interesting also!

RESTEasy, CDI, embedded Jetty, bean validation is ignored

I've a Groovy project where I use RESTEasy with Weld and deploy to embedded Jetty. What I can't seem to get working is bean validation. RESTEasy documentation says that adding resteasy-validator-provider-11 along with hibernate validator dependencies (hibernate-validator, hibernate-validator-cdi, javax.el-api, javax.el) is enough. But the bean validation is simply ignored by RESTEasy. I curiously also get the following message in the logs:
plugins.validation.ValidatorContextResolver - Unable to find CDI supporting ValidatorFactory. Using default ValidatorFactory
Based on the suggestions on [this][1] post, I tried registering Hibernate InjectingConstraintValidatorFactory in META-INF/validation.xml but it depends on a BeanManager being injected and blows up at runtime.
The code can be found here https://github.com/abhijitsarkar/groovy/tree/master/movie-manager/movie-manager-web
A log gist is here: https://gist.github.com/anonymous/8947319
I've tried everything under the sun without any success. Pls help.
To do this without EE, I believe you'll need to fork the existing InjectingConstraintValidatorFactory but instead of using injection of the bean manager, use the CDI 1.1 class CDI to get a reference to the bean manager, e.g. CDI.current().getBeanManager(). http://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/spi/CDI.html
You do need to be on CDI 1.1 to do this (so Weld 2+, 2.1.1 is current I believe). Here's an example impl, based on: https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main/java/org/hibernate/validator/internal/cdi/InjectingConstraintValidatorFactory.java
public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
// TODO look for something with better performance (HF)
private final Map<Object, DestructibleBeanInstance<?>> constraintValidatorMap =
Collections.synchronizedMap( new IdentityHashMap<Object, DestructibleBeanInstance<?>>() );
private final BeanManager beanManager;
public InjectingConstraintValidatorFactory() {
this.beanManager = CDI.current().getBeanManager();
Contracts.assertNotNull( this.beanManager, "The BeanManager cannot be null" );
}
#Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
DestructibleBeanInstance<T> destructibleBeanInstance = new DestructibleBeanInstance<T>( beanManager, key );
constraintValidatorMap.put( destructibleBeanInstance.getInstance(), destructibleBeanInstance );
return destructibleBeanInstance.getInstance();
}
#Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
DestructibleBeanInstance<?> destructibleBeanInstance = constraintValidatorMap.remove( instance );
destructibleBeanInstance.destroy();
}
}
I finally fixed this. Turns out, a validation.xml is not really required, resteasy-cdi module does a fine job of registering the BeanManager. What I was missing and not clearly documented anywhere, is that if an annotation is placed on a method, the validation engine just "decides" what should be validated. I placed a #NotNull on a method and it was validating the return type, not the parameters. One can use validationAppliesTo element in some cases but #NotNull doesn't have it. When I moved it from the method to the parameter, it started working.
Now I ran across what I believe is a Weld bug but I'll post that question separately.

How do I define a dependancy for use within an attribute using autofac

I have an asp.net mvc application and I am developing a custom attribute to secure some wcf end points inheriting from a CodeAccessSecurityAttribute.
I'm having difficulty finding out how I would use autofac to inject a service dependancy that I can use within this attribute.
[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class SecuredResourceAttribute : CodeAccessSecurityAttribute
{
public ISecurityService SecurityService { get; set; }
public SecuredResourceAttribute(SecurityAction action) : base(action)
{
}
public override IPermission CreatePermission()
{
// I need access to the SecurityService here
// SecurityService == null :(
}
}
I have tried from the application start to register for property auto wiring, but this is not working. What's the best way to inject a dependancy into an attribute?
builder.RegisterType<SecuredResourceAttribute>().PropertiesAutowired();
Thanks
The way you are approaching this is not going to pan out for a couple reasons:
Registering an attribute in autofac will do nothing as you're not using autofac to instantiate the attribute.
Attributes are applied before code execution, and thus rely on constant inputs.
You're going to have to use a service location pattern inside your CreatePermission() method to locate the SecurityService, as I am assuming the CreatePermission() call comes after the container is setup (and the constructor does not!)
Keep in mind ServiceLocation will hinder your class testability, as you will have to configure/set-up the service locator for each test.
Please use with caution
You should start your journey into ServiceLocation here but honestly this should make you question your design. Is an attribute best suited for the role you've tasked it? Perhaps you should look into Aspect-Oriented Programming like PostSharp

Resources