Apache CXF REST Services w/ Spring AOP - aop

I'm trying to get Apache CXF JAX-RS services working with Spring AOP. I've created a simple logging class:
public class AOPLogger {
public void logBefore(){
System.out.println("Logging Before!");
}
}
My Spring configuration (beans.xml):
<aop:config>
<aop:aspect id="aopLogger" ref="test.aop.AOPLogger">
<aop:before method="logBefore" pointcut="execution(* test.rest.RestService.*(..))"/>
</aop:aspect>
</aop:config>
<bean id="aopLogger" class="test.aop.AOPLogger"/>
I always get an NPE in RestService when a call is made to a Method getServletRequest(), which has:
return messageContext.getHttpServletRequest();
If I remove the aop configuration or comment it out from my beans.xml, everything works fine.
All of my actual Rest services extend test.rest.RestService (which is a class) and call getServletRequest(). I'm just trying to just get AOP up and running based off of the example in the CXF JAX-RS documentation. What am I doing wrong?

You just need to have your resource class implementing some simple interface with a method
#Context
void setMessageContext(MessageContext mc) {}
this will enable the CXF SpringAOPHelper to discover the method

Related

Add SignalR client functionality to a Fable.Elmish application

I found 2 resources from the community
1.Fable.SignalR - A functional type-safe wrapper for SignalR and Fable. I am using Elmish so the package is Fable.SignalR.Elmish
2.fable-signalr - Fable bindings for SignalR
2 Is declared to work only before Fable 3, which is not my case.
With 1 I have a problem: I do not control the server side. The server application is a standard C# ASP.NET core Web Api application that uses SignalR.
All the examples I found for 1 require a shared F# library, which cannot be done in this case.
Let's suppose to have a simple Hub like in the official docs:
using Microsoft.AspNetCore.SignalR;
namespace SignalRChat.Hubs
{
public class ChatHub : Hub {}
}
and an Api controller that receives the hub context through DI and simply broadcasts a message:
class YatpApiController(IHubContext<ChatHub> hubContext) : ControllerBase() {
[HttpPost("signalr-broadcast")]
public SignalrBroadcast()
{
hubContext.Clients.All.SendAsync("Method1", "Message1");
}
}
Can someone please
Show how to use Fable.SignalR.Elmish client side with this very simple case?
Give advise on an alternative way to connect to this simple hub from a Fable.Elmish application, without writing bindings to the javascript signalr package?

Logging HTTP requests and responses in quarkus resteasy

I am running into a problem with calling a REST endpoint on a server, using a REST client in Quarkus, built with the org.eclipse.microprofile.rest.client.RestClientBuilder. I would very much like to debug the service, by writing the HTTP requests and responses to the log, so I might see what is actually being sent to the server. The hunt for a guide for that particular issue has eluded me however.
I managed to build a logging filter but that only logs out the URL and the Entitys toString value, which is not at all the same as the HTTP request and response being sent.
Help me by pointing me to a solution to log the actual HTTP request and response.
You can try to enable the logging for all the traffic including wire or just some components, here in the logging configuration guide you can find how enable just some components logging.
Add this to your application.properties and you should be able to see some logging information quarkus.log.category."org.apache.http".level=DEBUG
If you need to log everything you can always put quarkus in debug level ALL, and the pick the components you need to constraint the logging, whit this you see all the traces at wire level.
You can also enable the http access log with this guide
Good luck.
If you are using resteasy reactive you can turn on logging with:
quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.logging.body-limit=1024
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
Check this: https://quarkus.io/guides/resteasy-reactive#the-jax-rs-way
Simply implement that class and you will start logging. Like this:
#Provider
class LoggingFilter implements ContainerRequestFilter,
ContainerResponseFilter {
/* Useful stuff for later development purposes.
#Context
UriInfo info;
#Context
HttpServerRequest request;
*/
#Override
public void filter(ContainerRequestContext requestContext) {
Log.info(requestContext);
}
#Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
Log.info(responseContext);
}
}
Then you may use UriInfo, HttpServerRequest and ContainerRequestContext to get any data you want and add to your custom log.

register server wide javax.ws.rs.client.ClientRequestFilter on JBoss EAP 7

Is it possible to register a javax.ws.rs.client.ClientRequestFilter server wide on JBoss EAP 7? I would like to intercept all outbound JAX-RS calls to dynamically add some context information in HTTP headers.
For JAX-WS calls I was able to do this with https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/developing_web_services_applications/#jax_ws_handler_chains. I can't find any documentation on a similar mechanism for JAX-RS.
Or alternatively, is there maybe another way to intercept outbound HTTP calls in general?
For a per server solution, according to Using HttpHandler class in Undertow "you need to package your handler(s) into a module, and configure custom-filter in undertow subsystem."
The module.xml example and undertow configuration has been given as well as filter source code!
Update
There's an example of using the HTTPExchange here though I dont really care much for that site. SO also has this slightly related example - it does look like it can work similarly to the JAX-WS Handlers/Interceptor How to properly read post request body in a handler
Another good example file upload using httphandler I know they're different that dealing with JAX-RS but still may apply.
I implemented it by creating a module with the following contents:
package be.fgov.kszbcss.tracer.jaxrs;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
public class TracerResteasyClientBuilder extends ResteasyClientBuilder {
#Override
public ResteasyClient build() {
return super.build().register(TracerJaxRsClientRequestFilter.class);
}
}
/META-INF/services/javax.ws.rs.client.ClientBuilder
be.fgov.kszbcss.tracer.jaxrs.TracerResteasyClientBuilder
And registering it as a global module on JBoss EAP.

Ninject 3, WCF Service and parameterized constructor

I have a WCF Service hosted in IIS. This solution is composed of 2 projects: Service and Data. Service depends on Data, like so:
Service -> Data
I've been trying to invert the dependency, like so:
Service <- Data
Which is quite a headache using WCF, since the WCF service constructor must be parameter-less (by default).
I hear it's possible to inject the dependency using Ninject and its WCF extension, so I tried to integrate it to my solution, but it's still not clear to me in which project should be the related files and references? What I did is :
Download Ninject using NuGet
Add Ninject to both my Data and Service projects (that created the NinjectWebCommon file in the App_Start folder of the Service Project
Create a IDataProxy interface in my Service project
Implement the interface in my Data project
Add a IDataProxy argument to the WCF service constructor
Added the factory configuration in the .svc file markup
Up to that point, I'm pretty sure I'm doing it right. Now the shaky part :
I created a DataInjectionModule in my data project with this code :
namespace Data
{
public class DataInjectionModule : NinjectModule
{
public override void Load()
{
Bind<IResolutionRoot>().ToConstant(Kernel);
Bind<ServiceHost>().To<NinjectServiceHost>();
Bind<IDataProxy>().To<DataProxy>();
}
}
}
I finally tried to register the service in the NinjectWebCommon files (of both projects to be sure) like that :
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IService>().To<Service>()
.WithConstructorArgument("IDataProxy", context => context.Kernel.Get<IDataProxy>());
}
When I try to start my service, I still get this :
The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.
I have a feeling that the problem resides in the fact that I did not bind my DataInjectionModule in the kernel, but if I try to do so, I must add a dependency from Service to Data, which is what I'm trying to avoid.
General expert advice would be greatly appreciated. Thanks.
Please check your point 6: "Added the factory configuration in the .svc file markup."
Have you done it properly?
The *.svc file should have this code:
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"

Jboss 7.1.1 - Jackson ContextResolver<ObjectMapper> works only on one deployment

I have two rest webapps I want to deploy on Jboss 7.1.1. server.
Rest requests in both apps produces and consumes Json. I use jackson provider to serialize and deserialize objects.
Now, I need custom ObjectMapper configurations for each webapp.
So to resolve this problem I added #Provider classes implementing ContextResolver. One for each project. Fe. One of my class looks like that:
#provider
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public JacksonConfig()
{
objectMapper = new ObjectMapper();
objectMapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
}
#Override
public ObjectMapper getContext(Class<?> objectType) {
return objectMapper;
}
}
It works well when I deploy only one of this projects on jboss. When I try to deploy both, only first initialized project use defined objectMapper. Other one never calls getContext method from ContextResolver class. What could I do wrong?
EDIT!:
After a lot of trials I decided to change method of parsing json from jackson to staxon. I hoped at least this method will work well. But not... Serialization works perfectly on both deployed applications. But again, somehow jboss decided to use jackson instead of staxon in deserialization process. Again always application which I call first after deployment works well. But Second one using jackson (no idea why...) which calls exceptions. Always...
Is there any problem with Jboss? Probably I'm just doing something wrong but I have no idea where. Anybody has idea where should I look?
Looks like I found solution for this problem.
It was known issue of resteasy, that can be removed by build-in option:
To solve this problem I just had to add param to web.xml of my projects:
<context-param>
<param-name>resteasy.use.deployment.sensitive.factory</param-name>
<param-value>false</param-value>
</context-param>
I found this solution in Resteasy jira. It's really strange for me that there is no info in any jboss or resteasy related documentation...