What is the most concise way to get an injected bean for a springboot managed class? - groovy

I have a simple application that injects another component
#ComponentScan
#EnableAutoConfiguration
#Configuration
class Application {
static void main(String[] args) {
SpringApplication.run(Application, args)
}
#Bean
AuthorizationServerTokenServices tokenServices() {
return MY THING HERE
}
}
I'd like a quick/minimal way to new this up and grab the item springboot wires up (for tokenServices in this example). I'm trying to get at this to verify some configuration/settings/etc using TestNG
I should also say that I"m not using any xml to configure this (using gradle/groovy/springboot)

You can easily introduce conditional bean with the help of Spring profiles.
In your case the code would look like:
#Configuration
#Profile("tokenService")
public TestTokenServiceConfig {
#Primary
#Bean
AuthorizationServerTokenServices tokenServices() {
//implementation
}
}
The custom implementation you supply in this class will only be used by Spring in case the profile tokenService is active. The use of #Primary is needed in order to make Spring use the specified bean instead of any others present in the application context.
Also note that since you are going to be using the custom service in a test environment, you could easily mock the implementation using Mockito (or whatever other mocking framework you prefer)
And the actual integration test would be something like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#ActiveProfiles("tokenService")
class YourIntegrationTest {
#Autowired
AuthorizationServerTokenServices tokenServices;
//test
}

Related

Spring Reactive Cassandra, use custom CqlSession

How do we use a custom CqlSession on a Spring Webflux application combined with Spring starter reactive Cassandra please?
I am currently doing the following, which is working perfectly:
public class BaseCassandraConfiguration extends AbstractReactiveCassandraConfiguration {
#Bean
#NonNull
#Override
public CqlSessionFactoryBean cassandraSession() {
final CqlSessionFactoryBean cqlSessionFactoryBean = new CqlSessionFactoryBean();
cqlSessionFactoryBean.setContactPoints(contactPoints);
cqlSessionFactoryBean.setKeyspaceName(keyspace);
cqlSessionFactoryBean.setLocalDatacenter(datacenter);
cqlSessionFactoryBean.setPort(port);
cqlSessionFactoryBean.setUsername(username);
cqlSessionFactoryBean.setPassword(passPhrase);
return cqlSessionFactoryBean;
}
However, I would like to use a custom session, something like:
CqlSession session = CqlSession.builder().build();
How do we tell this configuration to use it?
Thank you
Option 1:
If you are looking to completely override the auto configured CqlSession bean, you can do so by providing your own CqlSesson bean ie.
#Bean
public CqlSession cassandraSession() {
return CqlSession.builder().withClientId(MyClientId).build();
}
The downside of override the entire bean is that you will lose the ability to configure this session via application properties and you will lose the defaults spring boot ships with.
Option 2:
If you want to leave the default values provided by spring boot and have the ability to configure the session via application properties you can use CqlSessionBuilderCustomizer to provide specific custom configurations to the CqlSession. This can be achieved by defining a bean of that type ie:
#Bean
public CqlSessionBuilderCustomizer myCustomiser() {
return cqlSessionBuilder -> cqlSessionBuilder.withClientId(MyClientId);;
}
My personal preference is option 2 as it maintains the functionality provided by spring boot which in my opinion results in an easier to maintain application over time.

Micronaut and PowerMock

I am trying to use PowerMock(as i have some legacy static methods) in a micronaut based application. But when I try to run the application all micronaut beans are getting injected as null (and the underlying mocks as well)
#RunWith(PowerMockRunner.class)
#PrepareForTest({MyStaticClass.class, ClassToBeTested.class})
public class TestClass {
#InjectMocks
private ClassToBeTested obj1;
#Mock
private LegacyStaticClass1 obj2;
#Mock
private MicronautBasedBean obj2;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
MockitoAnnotations.initMocks(this);
}
Is there a #PowerMockRunnerDelegate or PorwerMock runner from micronaut (like SpringRunner)
also my #Before doesntt get called to inject mocks in this case
I tried using
#MicronautTest on the TestClass but then PowerMock is not able to mock static class.
Is there a #PowerMockRunnerDelegate or PorwerMock runner from
micronaut?
Not currently, no. Feel free to file a feature request at https://github.com/micronaut-projects/micronaut-test/issues. We welcome pull requests too of course.

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?

ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:
How to make ServiceStack and Kephas use one DI container, if this is possible?
Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?
You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as #mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.
For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.
Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.
public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
{
public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
{
yield return (typeof(IUserAuthRepository),
new AppServiceInfo(
typeof(IUserAuthRepository),
AppServiceLifetime.Singleton));
yield return (typeof(ICacheClient),
new AppServiceInfo(
typeof(ICacheClient),
ctx => new MemoryCacheClient(),
AppServiceLifetime.Singleton));
}
}
Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.
I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
}
}
Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:
public class Startup : ModularStartup
{
public Startup(IConfiguration configuration) : base(configuration){}
public new void ConfigureServices(IServiceCollection services)
{
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
}
}
In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:
public class AppHost : AppHostBase
{
public override void Configure(IServiceCollection services)
{
services.AddSingleton<IRedisClientsManager>(
new RedisManagerPool(Configuration.GetConnectionString("redis")));
}
public override void Configure(Container container)
{
var redisManager = container.Resolve<IRedisClientsManager>();
//...
}
}

Use SAP Cloud SDK to integrate with a custom backend service (oData) based on VDM Generator

I followed Alexander Duemont's blog, trying to implement a Java Spring Boot application that consumes Cloud Foundry Destination. The Destination has a custom OData V2 behind it, coming from an On-Premise ERP system. For local dev, when I perform the Maven build, the Integration-Tests module registers failure due to dependency injection
This is part of my Controller
#RestController
#RequestMapping("/resources")
public class ClassificationsController {
private static final Logger logger = CloudLoggerFactory.getLogger(ClassificationsController.class);
private final ClassificationService service;
public ClassificationsController(#Nonnull final ClassificationService service) {
this.service = service;
}
…..
}
The #Nonnull final ClassificationService Service causes org.springframework.beans.factory.UnsatisfiedDependencyException
I cannot use Spring stereotype annotations on generated Service classes (Fluent) to create Beans!
This question is more likely related to Spring Boot configuration.
I'm assuming ClassificationService is an interface and the implementing class exists in the same package.
Please make sure...
... to add the implementing class of ClassificationService to your component scan / test runtime. Feel free to share the integration test code to setup the test environment. Maybe the additional class reference is missing.
... to correctly annotate the respective Application class of your Spring Boot project. For example, assuming your ClassificationService resides in org.example.services.classification, while the rest of your application uses org.example.app. Your basic Application class would look like this, when following the Cloud SDK guide:
#SpringBootApplication
#ComponentScan({"com.sap.cloud.sdk", "org.example.services.classification", "org.example.app"})
#ServletComponentScan({"com.sap.cloud.sdk", "org.example.app"})
public class Application extends SpringBootServletInitializer
{
#Override
protected SpringApplicationBuilder configure( final SpringApplicationBuilder application )
{
return application.sources(Application.class);
}
public static void main( final String[] args )
{
SpringApplication.run(Application.class, args);
}
}
... to annotate the implementing class of ClassificationService with javax.inject.Named. In case you have multiple implementations of the same interface, make sure to give the not-used class a custom (unique) value for the #Named annotation.
... to look for exceptions (Class not found) in the application log during startup.

NServiceBus Unit of Work For Multitenancy with Custom ORM

Here are my parameters:
Simple NServiceBus Saga implementation using the default builder
In-house ORM on top of SQL Server
Multitenancy - I have two ASP.NET MVC 4 domains running on the same website, each with their own databases
We configure our ORM using a static method like so:
public class EndpointConfig: IConfigureThisEndpoint, IWantCustomInitialization {
public void Init() {
var bus = Configure.With()
.AutofacBuilder()
.UnicastBus().LoadMessageHandlers().DoNotAutoSubscribe()
.XmlSerializer()
.MsmqTransport().IsTransactional(true).PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.Sagas().RavenSagaPersister().InstallRavenIfNeeded()
.UseInMemoryTimeoutPersister()
.CreateBus()
.Start();
SlenderConfiguration.Init(bus);
}
}
public class SlenderCofnigruation {
private static ORMScope scope { get; set; }
public static void Init(IBus bus)
{
ORMConfig.GetScope = () =>
{
var environment = "dev";
if (bus.CurrentMessageContext.Headers.ContainsKey("Environment"))
environment = bus.CurrentMessageContext.Headers["Environment"];
if (scope == null)
scope = new SlenderScope(ConfigurationManager.ConnectionStrings[environment].ConnectionString);
return scope;
};
}
}
This works fine in our single-tenant Beta environment - it's fine for that static scope to get re-used because the environment header is always the same for a given deployment.
It's my understanding that this won't work for the multitenant situation described above, because NServiceBus will reuse threads across messages. The same scope would then be used, causing problems if the message was intended for a different environment.
What I think I want is a single scope per message, but I'm really not sure how to get there.
I've seen Unit Of Work Implementation for RavenDB, and the unit of work implementation in the full duplex sample, but I'm not sure that's the right path.
I've also seen the DependencyLifecycle enum, but I'm not sure how I can use that to resolve the scope given the way I have to set up the GetScope func.
Obviously I have no idea what's going on here. Any suggestions?
If you need to do something on a per-message basis, consider using message mutators (IMutateIncomingMessages) in addition to your unit-of-work management with some thread-static state.

Resources