Can I reference ResourceResolver? - servlet-filters

I have this Filter:
#SlingFilter(description="", vendor="", order=10)
class MyFilter extends DoNothingFilter {
#Reference private ResourceResolver;
}
When I am building with this #Reference line my bundle is not containing attached filter (otherwise it's here). What is wrong with this and how to avoid it? Logs say nothing about any issue related to this bundle update.

the resource resolver is not an OSGi service and so it cannot be referenced like that.
you either get it from a sling http request or create a new one using the resource resolver factory (which is an OSGi service)

Related

access ResourceInfo in Quarkus / Vertx HttpAuthenticationMechanism

In Quarkus (resteasy reactive), is there a way to get hold of the "ResourceInfo" in an HTTP Authentication Mechanism?
What I'm trying to do is read an annotation that is defined on the resource class or method, in order to choose an authentication mechanism based on it.
Injecting the ResourceInfo directly in the mechanism class does not work (and also, it is application scoped and not request scoped, so not sure it could work). I also couldn't find the info I need in the RoutingContext parameter.
I have also tried adding a ContainerRequestFilter, in which injecting the ResourceInfo with #Context works well, but I think perhaps the filters are called after the httpAuthenticationMechanism.authenticate(), because it's not called in my test when the endpoint requires authentication.
Is there another way to do this?
----> To clarify with code what I would like to do:
have different JAX-RS resources with a custom #Authorization annotations with different "api names" like this:
#Path("/jwttest")
#ApplicationScoped
#Authorization("jwttest")
public class JWTTestController {
...
}
#Path("/oidctest")
#ApplicationScoped
#Authorization("myoidc")
public class OIDCTestController {
...
}
and then different configs like this:
myframework.auth.jwttest.type=jwt
myframework.auth.jwttest.issuer=123
myframework.auth.jwttest.audience=456
myframework.auth.myoidc.type=oidc
myframework.auth.myoidc.auth-server-url=myurl
And in the HttpAuthenticationMechanism, find the value of #Authorization, and based on it, call another provider like suggested in https://quarkus.io/guides/security-customization#dealing-with-more-than-one-httpauthenticationmechanism with the right api name so that it can load the config.

How to change the operation name of a span with Apache Camel OpenTracing component?

I successfully added Apache Camel's OpenTracing component to my application. I can see traces in Jaeger UI. But the traces for the RabbitMQ component show only the exchange name without the routing key as operation name. Because of my application uses only one exchange with different routing keys, I need to see the routing key as operation name in my traces.
Research
With OpenTracing Spring RabbitMQ I could expose another customized RabbitMqSpanDecorator, see Span decorator:
Note: you can customize your spans by declaring an overridden RabbitMqSpanDecorator bean.
(However, I coulnd't change the operation name with the RabbitMqSpanDecorator at all, because the operation name is hard coded to producer or consumer.)
Unfortunately Apache Camel uses its own different implementation of a RabbitmqSpanDecorator to decorate spans. I wrote a custom class by overiding Apache Camel's RabbitmqSpanDecorator, but my custom class wasn't used.
Question
How can I change the operation name of a span with Apache Camel OpenTracing component for Apache Camel RabbitMQ component?
It is possible to change the Tracer implementation with ServiceLoader, see OpenTracing:
EXPLICIT
Include the camel-opentracing component in your POM, along with any specific dependencies associated with the chosen OpenTracing compliant Tracer.
To explicitly configure OpenTracing support, instantiate the OpenTracingTracer and initialize the camel context. You can optionally specify a Tracer, or alternatively it can be implicitly discovered using the Registry or ServiceLoader.
With the DefaultTracer it is also possible to change the RabbitmqSpanDecorator with ServiceLoader, see Tracer.java:
static {
ServiceLoader.load(SpanDecorator.class).forEach(d -> {
SpanDecorator existing = DECORATORS.get(d.getComponent());
// Add span decorator if no existing decorator for the component,
// or if derived from the existing decorator's class, allowing
// custom decorators to be added if they extend the standard
// decorators
if (existing == null || existing.getClass().isInstance(d)) {
DECORATORS.put(d.getComponent(), d);
}
});
}
Therefore, I had to add a file org.apache.camel.tracing.SpanDecorator containing the name of my custom RabbitmqSpanDecorator, see ServiceLoader:
Deploying service providers on the class path
A service provider that is packaged as a JAR file for the class path is identified by placing a provider-configuration file in the resource directory META-INF/services. The name of the provider-configuration file is the fully qualified binary name of the service. The provider-configuration file contains a list of fully qualified binary names of service providers, one per line.
My custom RabbitmqSpanDecorator:
public class CustomRabbitmqSpanDecorator extends RabbitmqSpanDecorator {
#Override
public String getOperationName(Exchange exchange, Endpoint endpoint) {
return ((RabbitMQEndpoint) endpoint).getRoutingKey();
}
}

Is there a symbolic item to reference spring-cloud config server?

A project I'm working on is utilizing Spring Cloud Config server to handle property update/refresh.
One question that has repeatedly come up is how to reference/serve plain text from the config server.
I know that the server supports serving plain-text. What I'm trying to figure out is that if I have a reference /foo/default/master/logj42.xml.
How would I reference this in an "agnostic" way such that if I were to put:
{configserver}/foo/default/master/log4j2.xml in the config file
The reference {configserver} would be expanded.
Additionally, when using "discovery", if I inject the reference to the "resource" as above, the default mechanism will attempt to use java.net.URLConnection to load the content. I do not think it will resolve the 'discovery' host.
Thanks in advance.
It also can be resolved using Customizing Bootstrap Configuration without aspects by creating custom property source and set configserver uri after locating from discovery.
I had similar issue, more details in this stackoverflow post
I found a way to do this that is minimally invasive but "pierces the veil" of where the config server actually resides.
On the primary application class, the annotation #EnableDiscoveryClient needs to be added.
I created an aspect to add a property source with a key that indicates the actual URI of the server handling the request:
#Component
#Aspect
public class ResolverAspect {
#Autowired
private DiscoveryClient discoveryClient;
#Pointcut("execution(org.springframework.cloud.config.environment.Environment org.springframework.cloud.config.server.environment.EnvironmentController.*(..))
private void environmentControllerResolve();
#Around("environmentControllerResolve()")
public Object environmentControllerResolveServer(final ProceedingJoinPoint pjp) throws Throwable {
final Environment pjpReturn = (Environment)pjp.proceed();
final ServiceInstance localSErviceInstance = discoveryClient.getLocalServiceInstance();
final PropertySource instancePropertySource =
new PropertySource("cloud-instance", Collections.singletonMap("configserver.instance.uri", localServiceInstance.getUri().toString()));
pjpReturn.addFirst(instancePropertySource);
return pjpReturn;
}
}
By doing this, I expose a key configserver.instance.uri which can then be referenced from within a property value and interpolated/resolved on the client.
This has some ramifications with regard to exposing the actual configuration server, but for resolving resources that do not necessarily utilize the discovery client this can be utilized.

Transient Lifestyle requires HttpContext?

I am registering my component like this:
public static void Register(IWindsorContainer container)
{
container.Register(Classes.FromAssembly(Assembly.GetAssembly(typeof(GenericBaseRepository)))
.InSameNamespaceAs<GenericBaseRepository>()
.WithService.DefaultInterfaces()
.LifestyleTransient());
}
I am then resolving it in a piece of code that has no HttpContext:
var baseRepository = ContainerManager.Container.Resolve<IBaseRepository>();
(IBaseRepository being an interface implemented by GenericBaseRepository). This fails with the following message:
"HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net"
Which confuses me, because the lifestyle I choose is Transient, not PerWebRequest.
Of course, HttpContext doesn't exist during a scheduled task - but I don't really need it, I just want an instance of my Repository which will not interact with any web request.
So, why does Castle Windsor insist in requiring an HttpContext when resolving my component?
Have a look at the full exception message. Your root component may be transient but the exception indicates one of its dependencies uses per web request lifestyle.
Have a look at Windsor's diagnostics debugger view, that may help you pinpoint it.

Add another UrlHandlerMapping to Spring data rest

I'm having a normal spring-mvc project and I'm also building a rest module as a separate jar file. The goal is when I have the rest jar in my classpath to have the normal website mapped to / and the spring-data-rest repositories mapped to /rest. For the rest module I have defined RepositoryRestMvcConfiguration as well as a WebApplicationInitializer and it all works fine.
So now I want to add some more URLs to the rest module (like /synchronize, and /authenticate, etc.) but as soon as I add controllers in the rest module, they are picked up by the parent application context (the one for the website /). I tried specifying them as bean in the RepositoryRestMvcConfiguration but still they are picked up by the other parent context and the filters of the parent context are fired. And when I access the spring-data-rest through /rest no filters are triggered.
So I was wondering: is there a method I could override in the RepositoryRestMvcConfiguration so that I can add extra url handler mappings?
I assume you mean that you want to have another controller advertised as part of Spring Data REST's root hypermedia.
To do so, you need to create another class in your app like this:
#Component
class DogifierResourceProcessor implements ResourceProcessor<RepositoryLinksResource> {
#Override
public RepositoryLinksResource process(RepositoryLinksResource objects) {
objects.add(new Link(ServletUriComponentsBuilder.fromCurrentRequest()
.build()
.toUriString()
.concat("dogifier/{id}"), "dogifier"));
return objects;
}
}
This will create a hypermedia entry with rel="dogifier" that lists /dogifier/{id} as the URI. It will also prefix it with the proper URN, etc.
Of course, you can use Spring HATEOAS to link to a controller method without having to specify the actual path by hand. That would reduce maintenance and encourage better hypermedia controls.
You need to exclude those controllers from the classpath scanning of the parent context. Just follow the instructions in the Spring documentation.