How to Convert Blocking Feign Clients to Reactive Feign Clients - spring-cloud-feign

Introduction
1. We have quite a bunch of Spring microservices, some totally reactive (spring-webflux) and some old style (spring-web).
2. We use Feign to define API (and the client) in our microservices as interface and implement them in our controllers.
3. Each microservice might have dependencies on both types.
Objective
To prevent code duplication, generate Reactive Feign clients based on normal Feign clients (and vice versa).
Questions
I already developed a (PoC) Maven plugin which reads Feign interfaces and generates Reactive ones with the same signature but a reactive return type.
1. Is this a stupid idea? If so, what should I do to have both technology supported in our clients without code duplication?
2. Is there any tools/solutions in the market I can use? (Or should I continue with my maven plugin?)

Feign includes simple Reactive streams support that allows for the use of Reactive return types. This library wraps the method execution in a Reactive wrapper. It is not "reactive all the way down", the method execution is still blocking, but it can be integrated into an existing Reactive execution chain.
To use the provided library, include it as a dependency:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-reactive-wrappers</artifactId>
<version>10.4.0</version>
</dependency>
And use the appropriate builder for the reactive streams implementation you want, Reactor and RxJava2+ are supported.
public class ExampleReactor {
public static void main(String args[]) {
GitHubReactor gitHub = ReactorFeign.builder()
.target(GitHubReactor.class, "https://api.github.com");
List<Contributor> contributors = gitHub.contributors("OpenFeign", "feign")
.collect(Collectors.toList())
.block();
}
}
You can use this library to get you started. Our roadmap includes full reactive support in the near future.

Related

Is it possible to register dependencies by convention in .NET Core?

Some containers allow for registration by name. Ninject is one as an example.
Does the .NET Core DI container support this? And if not, are there plans or third party libraries to support this?
You can write your own convention, a simple example would look like this:
Assembly.GetAssembly(typeof(Startup))
.ExportedTypes
.Where(t => t.IsClass)
.SelectMany(t => t.GetInterfaces(), (c, i) => new {Class = c, Interface = i})
.ToList()
.ForEach(x => services.AddTransient(x.Interface, x.Class));
You can extend it to include abstract classes, non-public types, etc.
Does the .NET Core DI container support this? And if not, are there
plans or third party libraries to support this?
Short Answer: NO and NO
Source: Introduction to Dependency Injection in ASP.NET Core
Replacing the default services container
The built-in services container is meant to serve the basic needs of
the framework and most consumer applications built on it. However,
developers can replace the built-in container with their preferred
container. The ConfigureServices method typically returns void, but if
its signature is changed to return IServiceProvider, a different
container can be configured and returned. There are many IOC
containers available for .NET.
(Emphasis mine)
With that you can check if Ninject has an extension for .net core and see if you can integrate it.
And if not, are there plans or third party libraries to support this?
Try this https://github.com/khellang/Scrutor

Does libgit2sharp provide public bindings for the smart transport protocol?

I am attempting to implement the smart HTTP transport protocol in an Asp.Net MVC application. Ultimately, my goal is to enforce permissions at a branch level rather than for the whole repository. To this point, I have implemented a parser for the receive-pack and upload-pack headers but I am stuck when it comes to handling the thin packfile that makes up the rest of the request.
From hunting through the libgit2 source it appears the contents of this thin pack file are intended to just be appended to the object database. The bindings for this functionality appear to be currently implemented in libgit2sharp but are encapsulated away from the public api.
Does libgit2sharp provide any public apis for the packbuilder or for the smart transport protocol directly? If not, is there a better way to accomplish this with the libgit2sharp library?
There is an oldish PR which exposes the pack indexer to C# but I never got around to finishing it. As is so often the case in software, the pack builder isn't in libgit2sharp because nobody's cared enough yet to implement it in the mainline repository.
There is no direct access to the on-the-wire protocol parsing, and exposing it would be more work than reimplementing the parser in a nicer language (which I have done previously). There is no server component in libgit2, so it wouldn't do any of the work for you in any case.

enable SNMP monitoring for Java app with existing MBeans

I'm looking for an example to expose the methods already exposed via MBean server with SNMP.
I read that since Java6 this is already supported in the JDK, but I also found snmp4j as a library. But I couldn't find any example that fits my scenario, or would be helpful.
I already have MBeans registered to the MBeanServer, and I'm looking for a way to enhance the classes I already have in order to make them suitable for SNMP. I can't use mibgen, as it would be the other way around.
Maybe someone can give me an example on what I need to do in order to be able to monitor my application via some SNMP manager.
An example MBean would be
public interface ExporterMXBean {
public static String BEANNAME = "exporter:type=Exporter,name=Exporter";
String getOutputDirectory();
void setOutputDirectory(String outputDirectory);
void startExport();
int getNumberOfThreadsWorking();
}
What would I need to add to the implementation of the interface, how would I register this to a MIB, and how would it be exposed/viewable to a Manager?
Thanks in advance.
I would recommend using SNMP4J-AgentJMX on top of SNMP4J-Agent and SNMP4J like the in the example of SNMP4J-AgentJMX called JvmManagementMibInst.java.
With this approach you do not modify your existing classes (MBeans). Instead your programm or generate a mapping which makes use of the above APIs.
A basic How-To on the necessary steps to create a SNMP agent based on some MBeans of a MBean server is described in the SNMP4J-AgentJMX HowTo

SignalR and AspNetHost.DependencyResolver

I'm using SignalR in the application I am writing, but I'm confused by examples like the last example at https://github.com/SignalR/SignalR/wiki/Hubs in particular the use of AspNetHost.DependencyResolver
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
If I'm not mistaken this is a Dependency Injection tool? Problem is I'm using StructureMap for everything else, and I'd rather not have two dependency Injection frameworks.
Is AspNetHost.DependencyResolver necessary?
SignalR has a bunch of dependencies/services that it needs to function, and it gets those through a DependencyResolver.
You can replace that resolver with your own (e.g StructureMap, Ninject etc.), but if you don't, SignalR will use it's default resolver.

Can I make arbitrary classes "injectable" in Java EE?

I'm working on a large legacy application using stateless session beans that has recently been migrated from EJB2 to EJB3, and I'd like to use dependency injection. Unfortunately, in a (IMO misguided) attempt to achieve decoupling, all actual business logic lies in "manager" classes to which the session beans forward their calls. Those manager classes then often use other EJBs.
Can I somehow make these manager classes capable of being injected into the EJBs via #Resource and then having the other EJBs injected into them via #EJB?
The application has to run on glassfish 2.1.
(...) all actual business logic lies in "manager" classes to which the session beans forward their calls.
That was a very common pattern with EJB 2.x allowing to unit test the "manager" classes easily, outside the container, without any adherence to the EJB API.
Can I somehow make these manager classes capable of being injected into the EJBs via #Resource and then having the other EJBs injected into them via #EJB?
Not out-of-the-box with Java EE 5. Injection is limited only to first class constructs defined in the Java EE platform, including:
SessionContext object
DataSources object
UserTransaction
EntityManager interface
TimerService interface
Other enterprise beans
Web services
Message queues and topics
Connection factories for resource adaptes
Environment entries limited to String, Character, Byte, Short, Integer, Long, Boolean, Double, and Float.
In Java EE 6, this would be possible using CDI (JSR-199) and the #Inject annotation in EJBs to inject your managers and also in you managers to get EJBs injected.
Maybe you could try to deploy Weld (the RI of JSR-199) as part of your application on GlassFish v2.1. I didn't experiment this myself, so I can't confirm anything. Just in case, maybe have a look at the Chapter 18. Application servers and environments supported by Weld (GlassFish v2.1 hasn't been tested, but it doesn't mean it doesn't work).
Pascal's suggestion about upgrading to GlassFish 3 sounds probably like the most elegant approach ;)
I'd be curious to hear what prevents moving to a more recent version (not saying there can't be a reason, just wondering what the issue is here).

Resources