Bean not found for topic name when using BinderAwareChannelResolver - spring-cloud

I am using BinderAwareChannelResolver to publish messages to dynamic topics.
Its throwing Failed to find MessageChannel bean with name 'topic-name'.

Anyways, BinderAwareChannelResolver is deprecated in the 3.0:
https://github.com/spring-cloud/spring-cloud-stream#notable-deprecations
The BinderAwareChannelResolver is deprecated in favor if providing spring.cloud.stream.sendto.destination property. This is primarily for function-based programming model. For StreamListener it would still be required and thus will stay until we deprecate and eventually discontinue StreamListener and annotation-based programming model.
So you should use sendto.destination property, you have mor info in the docs:
https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.3.RELEASE/reference/html/spring-cloud-stream.html#_spring_cloud_stream_sendto_destination

I used the code below. I used functional programming.
We can get beans via ApplicationContext.
I create the channel name as a string and I get the bean according to this channelName from the application context.
MessageChannel messageChannel = createMessageChannel(channelName);
messageChannel.send(getMessageBuilder().apply(data));
public MessageChannel createMessageChannel(String channelName) {
return (MessageChannel) applicationContext.getBean(channelName);}
public Function<Object, Message<Object>> getMessageBuilder() {
return payload -> MessageBuilder
.withPayload(payload)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
.build();}

Related

Where to put #OpenAPIDefinition?

The documentation for defining general API information using the quarkus-smallrye-openapi extension is extremely sparse, and does not explain how to use all the annotations for setting up the openApi generation.
For some background, I am using a clean and largely empty project (quarkus version1.0.1.FINAL) generated from code.quarkus.io, with a single class defined as followed (With the attempted #OpenAPIDefinition annotation):
#OpenAPIDefinition(
info = #Info(
title = "Custom API title",
version = "3.14"
)
)
#Path("/hello")
public class ExampleResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
I have eventually found that general api information (contact info, version, etc) through much digging is defined using the #OpenAPIDefinition annotation, but when used on my existing endpoint definition, no changes are made to the generated openapi specification. What am I doing wrong?
Try putting the annotation on the JAX-RS Application class. I realize you don't need one of those in a Quarkus application, but I think it doesn't hurt either. For reference in the specification TCK:
https://github.com/eclipse/microprofile-open-api/blob/master/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java

Issues with CDI when injecting generic type : Wildfly 8.2.0.Final

We are facing weird injection issues in Widfly due to CDI changes. We have interface
public interface Command<I, O> {
}
and many classes implement this interface like this
public class ApproveUserRequests implements Command<ApproveUserRequestsRequest, List<String>> {
}
Application listener classes likes to get list of all classes available and uses injection like this
#Inject
private Instance<Command<I, O>> mActions;
However instance returned by mActions were always null. After debugging source found that the only way to get list of all instances is to use
#Inject
private Instance<Command<?, ?>> mActions;
Also we faced injection issues while using generic types , however using wildcard type helped us.
- See more at: https://developer.jboss.org/thread/256783#sthash.1s6tuXsR.dpuf
The rules for parameterized types have been clarified in CDI 1.2. Have look at Section 5.2.4 Assignability of raw and parameterized types of the spec.

Implementing Hypermedia in RESTful JAX-RS Apache CXF

I am working in a RESTful application developed in Apache CXF and I would like to introduce hypermedia functionality to it.
Most of our jaxrs:serviceBeans follow this template:
#GET
#Path("/{exampleId}")
public ExampleJSON get(#PathParam("exampleId") Integer exampleId) {
ExampleJSON example;
// Load data from repository here...
// Add link to self.
String href = javax.ws.rs.core.Link.fromResource(ExampleService.class).build().getUri().toString();
// HypermediaLink is a custom object to hold a "href" and "rel" strings
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + example.getId());
linkToSelf.setRel("self");
// Inherited method, just adds a HypermediaLink to a collection in the parent class
example.addHypermediaLink(linkToSelf);
// Return JSON compatible object, JACKSON will serialize it nicely.
return example;
}
This is the basic concept. Keep in mind that I simplified this code for explanation purposes; so, it can be easily understood.
This code works fine; but I am wondering if there is a better way to do this with Apache CXF. I have some ideas for how to enhancing it; however, it will require some custom annotations.
I see some examples using Jersey, but I would like to stick with Apache CXF.
Any help would be appreciated.
Thanks
I would leverage some features of JAX-RS and / or Jackson to implement the link adding under the hood at the serialization level. So you wouldn't need to have a specific field for the link within the bean itself.
You could implement a custom MessageBodyWriter to generate a different JSON payload (for example) for your POJOs than the default. So you could dynamically add the link.
See this answer for more details: How to write an XML MessageBodyWriter provider with jersey.
If you use Jackson for the serialization, you could implement a custom serializer. Note that this is generic and will work for all supported format of Jackson.
Below is a sample code:
public class LinkBeanSerializer extends JsonSerializer<SomeBean> {
#Override
public void serialize(SomeBean bean, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
// Fields
jgen.writeNumberField("id", bean.getId());
// Things could be generic using reflection
// Link
String href = javax.ws.rs.core.Link.fromResource(SomeBean.class).build().getUri().toString();
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + bean.getId());
linkToSelf.setRel("self");
jgen.writeObjectField("hypermediaLink", linkToSelf);
jgen.writeEndObject();
}
}
Note that we could make this serializer more generic I think (something like extends JsonSerializer<Object>)
See this answer for more details: Processing JSON response using JAX-RS (how to register the custom serializer within JAX-RS, ...).
Perhaps implementing a WriterInterceptor could solve your problem but there is impact on the beans since you need to have field hypermediaLink. The interceptor could be responsible of filling the field.
See this answer for more details: Jersey Update Entity Property MessageBodyWriter.
IMO the more convenient solution is the second one. It's transparent and support all the formats supported by Jackson.
Hope it helps you,
Thierry

Please help on equivalent concept for JBoss AOP aspect

I am using JBoss application server 6 and using JBoss AOP aspects in my application.
An example of aspect shown below:
public class DBAspect{
public Object accessDBConnection(FieldReadInvocation invocation) {
return dbConnection;
}
public Object accessDBConnection((FieldWriteInvocation invocation) {
throw exception;
}
}
Currently, these advice methods are applied to a private variable in class say DBUsage by binding it with this aspect.
I am migrating to a new application server and it is not supporting JBoss AOP. So, how do I implement this concept.
How can I implement this behavior. Please help.
Applying field get/set pointcuts to private field does not sound like good application or aspect design to me. Maybe refactoring your application would be a better idea. Anyway, in AspectJ you can use get() and set() pointcuts in order to intercept field get/set actions. If you want to access private fields, you might need to use a privileged aspect.
AspectJ quick reference
Privileged aspects
AspectJ pointcut types (incl. get/set)

what is a jaxb provider, jaxb handler, and contextResolvers?

1) What is a JaxB provider, and is it the same as a ContextResolver?
2) What is a jaxb handler?
I'm very lost in these terminologies. Please reply in simple to understand words.
Here it is from the book:
JAXB JAX-RS Handlers
The JAX-RS specification requires implementations to automatically support the marshalling and unmarshalling of classes that are annotated with #XmlRootElement or #XmlType as well as objects wrapped inside javax.xml.bind.JAXBElement instances. Here’s an example that interacts using the Customer class defined earlier:
#Path("/customers")
public class CustomerResource {
#GET
#Path("{id}")
#Produces("application/xml")
public Customer getCustomer(#PathParam("id") int id) {
Customer cust = findCustomer(id);
return cust;
}
#POST
#Consumes("application/xml")
public void createCustomer(Customer cust) {
...
}
}
As you can see, once you’ve applied JAXB annotations to your Java classes, it is very easy to exchange XML documents between your client and web services. The built-in JAXB handlers will handle any JAXB-annotated class for the application/xml, text/xml, or application/*+xml media types. By default, they will also manage the creation and initialization of JAXBContext instances. Because the creation of JAXBContext instances can be expensive, JAX-RS implementations usually cache them after they are first initialized.
Managing your own JAXBContexts with ContextResolvers
If you are already familiar with JAXB, you’ll know that many times you need to configure your JAXBContext instances a certain way to get the output you desire. The JAX-RS built-in JAXB provider allows you to plug in your own JAXBContext instances. The way it works is that you have to implement a factory-like interface called javax.ws.rs.ext.ContextResolver to override the default JAXBContext creation:
public interface ContextResolver<T> {
T getContext(Class<?> type);
}
ContextResolvers are pluggable factories that create objects of a specific type, for a certain Java type, and for a specific media type. To plug in your own JAXBContext, you will have to implement this interface. Here’s an example of creating a specific JAXBContext for our Customer class:
#Provider
#Produces("application/xml")
public class CustomerResolver
implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public CustomerResolver() {
this.ctx = ...; // initialize it the way you want
}
public JAXBContext getContext(Class<?> type) {
if (type.equals(Customer.class)) {
return ctx;
} else {
return null;
}
}
}
JAXB Provider
A JAXB provider is an implementation of the Java Architecture for XML Binding (JSR-222) specification. This specification was created through the Java Community Process. It was originally lead by Sun Microsystems, but is now lead by Oracle. The expert group had members from several object-to-XML technologies (XMLBeans, EMF, TopLink OX, etc) as well as several individuals. A JAXB implementation is required to pass the Test Compatibility Kit (TCK). Below are links to a couple of JAXB providers:
https://jaxb.java.net/
http://www.eclipse.org/eclipselink/moxy.php
ContextResolver
JAXB is the default object-to-XML provider in JAX-RS. By default it will create a JAXBContext based on the parameter/return type of the JAX-RS annotated method (i.e. annotated with #GET). Then it will pull in all referenced classes to produce metadata as well. Sometimes this doesn't produce all the required metadata and you need to provide the JAXBContext yourself. This can be done with a ContextResolver.
JAXB Handler
I'm not familiar with this term.
JAXB is the acronym for "Java Architecture for XML Binding", a specification defining ways to convert between XML documents and Java object trees, originally created by Sun Microsystems. The valid spec, version 2.0, was completed in 2006.
An implementation according to the JAXB specification is a JAXB provider.
The specification contains some hints, what a plausible implementation might contain. For instance: "The JAXBContext class is the entry point for a Java application into the
JAXB framework." It maintains information about the classes to expect during (un)marshalling. It is created either from one or more packages or from a list of classes. (The process of context resolution may follow hints in the annotation.)
The term "JAXB handler" (as it is used in the quoted text) refers to the code associated with a JAXBContext class that investigates a Java class, introspecting fields and methods and annotations, thus creating a database of all information contained within the Java code.