Multiple level of #Inject in a Jersey application - google-app-engine

I have a Jersey 2 application. A resource is using one of my service class using #Inject and all goes ok.
The binding configuration:
class MyApp extends ResourceConfig {
register(new AbstactBinder() {
#Override
protected void configure() {
bind(PrimaryService.class).to(PrimaryService.class);
}
});
}
The resource class:
#Path("/example");
class Resource {
#Inject
PrimaryService service;
#GET
public Response get() {
//Consume service class
}
}
Everything works as expected.
BUT what if I need another #Inject in the PrimaryService class?
I added the binding:
bind(PrimaryService.class).to(PrimaryService.class);
bind(SecondaryService.class).to(SecondaryService.class);
And, in the PrimaryService class, I have:
class PrimaryService {
#Inject
SecondaryService secondary;
public void someMethod() {
//Consume secondary
}
}
But, I have an exception telling me that dependency is usatisfied.
I'm using Jersey2 on Google AppEngine instance.

Related

Working with apache camel Bean in Quarkus framework

I am trying to use apache camel with Quarkus. Previously I was using the spring-boot framework to develop camel integration. So there are lots of questions that I am still trying to figure out w.r.t. Quarkus framework.
Regarding: Bean
In spring-boot I could do something like this
#Configuration
public class JABXContextConfig {
#Bean
Unmarshaller jaxbUnmarshaller() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(MyPOJO.class );
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return jaxbUnmarshaller;
}
}
and then I could inject it into the class using DI
#Component
public class MyRestServiceRoute extends RouteBuilder {
private final JaxbDataFormat jaxb;
#Autowired
public MyRestServiceRoute(JaxbDataFormat jaxb) throws Exception{
this.jaxb = jaxb;
}
....
}
QUESTION:
How can I do the same in the Quarkus framework?
P.S> I tried replacing #Configuration with #ApplicationScoped and #Bean with #Dependent but it's not working.
Thanks,
I recommend taking a read through the Quarkus CDI documentation:
https://quarkus.io/guides/cdi
https://quarkus.io/guides/cdi-reference
There's also a basic overview of using CDI to configure Camel:
https://camel.apache.org/camel-quarkus/latest/user-guide/bootstrap.html#_cdi
https://camel.apache.org/camel-quarkus/latest/user-guide/cdi.html
In your examples, #Bean could be replaced by a producer method like:
public class JaxbDataFormatProducer {
#ApplicationScoped
JaxbDataFormat jaxbDataFormat() {
return new JaxbDataFormat();
}
}
And the #Autowired constructor argument might look like this (If there’s only one constructor then there's actually no need for #Inject):
#ApplicationScoped
public class MyRestServiceRoute extends BaseRouteBuilder {
private final JaxbDataFormat jaxb;
#Inject
public MyRestServiceRoute(JaxbDataFormat jaxb) throws Exception{
super(properties);
this.jaxb = jaxb;
}
}

Need help connecting Websocket in spring to a database

I need help with connecting my WebSocket to my DB in spring boot.
I know that the DB access happens in the controller but I don't know how.
#Controller
public class ChatController {
#MessageMapping("/chat.register")
#SendTo("/topic/public")
public ChatMessage register(#Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
return chatMessage;
}
#MessageMapping("/chat.send")
#SendTo("/topic/public")
public ChatMessage sendMessage(#Payload ChatMessage chatMessage) {
return chatMessage;
}
}
Where would I connect to the DB
Its not a good idea to add a repository to your controller. A better approach is to add a service layer between controller and database.
#Controller
public class ChatController {
#Autowired
private Chatservice chatservice;
#MessageMapping("/chat.register")
#SendTo("/topic/public")
public ChatMessage register(#Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
chatservice.saveChatMessage(chatMessage); // save this too?
return chatMessage;
}
#MessageMapping("/chat.send")
#SendTo("/topic/public")
public ChatMessage sendMessage(#Payload ChatMessage chatMessage) {
chatservice.saveChatMessage(chatMessage);
return chatMessage;
}
}
#Service
private class ChatService {
#Autowired
private ChatRepository repository;
public void saveChatMessage(ChatMessage chatMessage) {
// do more business stuff here e.g. Mapping to Entity ....
repository.save(chatMessage);
}
}
public interface ChatRepository extends CrudRepository<ChatMessage, Long> {
}

Using Guice for Dependency Injection with GAE Basic Scaling Instance

I have an application running on GAE (Basic Scaling) which uses Guice for dependency injection.
Guice Listener
public class GuiceListener extends GuiceServletContextListener {
private ServletContext servletContext = null;
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContext = servletContextEvent.getServletContext();
super.contextInitialized(servletContextEvent);
}
/**
* Function to create Guice Injector
*/
#Override
protected Injector getInjector() {
return Guice.createInjector(
new GuiceServletModule(),
new ServiceInjectionModule()
);
}
}
Guice Servlet Module
public class GuiceServletModule extends GuiceSystemServiceServletModule {
#Override
protected void configureServlets() {
super.configureServlets();
Logger.info("Guice configure servelet");
filter("/*").through(NamespaceFilterCustom.class);
Map<String, String> params = new HashMap<>();
params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.my.service.endpoint");
params.put("com.sun.jersey.api.json.POJOMappingFeature", "true");
//you can create your own filters to handle request and response differently
params.put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, GZIPContentEncodingFilter.class.getName());
params.put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, GZIPContentEncodingFilter.class.getName());
serve("/*").with(GuiceContainer.class, params);
}
}
Service Injection Module
public class ServiceInjectionModule extends AbstractModule {
#Override
protected void configure() {
bind(Service.class).to(ServiceImpl.class);
}
}
My endpoint class expects "Service" object to be injected. The application runs fine when used with GAE Auto Scaling. However the "Service" object is not getting injected when the application runs on GAE Basic Scaling. Null pointer exception is thrown when "Service" is accessed.

Change EndPoint details in CXF ServiceInfo

The environment CXF2.2.6 and Spring 2.5. On Startup JBOSS I need to read CXF properties and change End point details. From basic reading it gives me the idea that CXF Service Info class (org.apache.cxf.service.model.ServiceInfo) handle bindings,endpoints,messages,schemas and so on.
I can Extend CXFServlet and create my own custom servlet. Please advise me the way I can give my own details to Endpoint in startup and override what is given in Spring.xml
The below Spring bean should do what you wanted. Why do you want to override ServiceInfo class ? Any particular reason ?
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ServletContextAware;
public class CXFConfig implements InitializingBean{
#Autowired
Bus cxfBus;
#Override
public void afterPropertiesSet() throws Exception {
EndpointImpl endpoint = new EndpointImpl(cxfBus, new GdsAutomationServiceProviderImpl());
endpoint.setAddress("/public/api/service/v1");//WSDL URL
endpoint.setPublishedEndpointUrl(getEndPointAddress());
endpoint.publish();
}
public Bus getCxfBus() {
return cxfBus;
}
public void setCxfBus(Bus cxfBus) {
this.cxfBus = cxfBus;
}
public String getEndPointAddress() {
// Soap address location you need to define here
return "address"
}
#Override
public void setServletContext(ServletContext context) {
context.getServerInfo();
}
}

Migrating from CamelTestSupport to AbstractCamelTestNGSpringContextTests

I've been using Apache Camel since 3-4 months on Spring 4.0.7.RELEASE
I have several Camel 2.14.0 TestNG tests based on extending CamelTestSupport, in which I use some MockEndpoints.
I configured my routes by overriding the createRouteBuilder() method.
Now I would need also to inject some Spring beans in one of them, by #Autowired annotation.
By reading what is said at http://camel.apache.org/spring-testing.html, I understood that I've to extend AbstractCamelTestNGSpringContextTests now, which supports #Autowired, #DirtiesContext, and #ContextConfiguration.
While I understood that all MockEndpoints are no more accessible by getMockEndpoint() method, but by using #EndpointInject annotation, it is not clear to me is how I can express my routes, because createRouteBuilder() is not more available.
I saw that is possible to define producers and consumers by using annotations, but I cannot manage to understand how routes can be designed.
Many thanks to the community.
Alternatively to the solution given here, you may use the TestNG helper CamelSpringTestSupport in combination with AnnotationConfigApplicationContextif you want to initialize an annotated based Spring configuration context without the need of an additional XML Spring configuration file.
Camel configuration bean class using Spring annotations:
#Configuration
public class MyConfig extends SingleRouteCamelConfiguration {
#Bean
#Override
public RouteBuilder route() {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:test").to("mock:direct:end");
}
};
}
}
The TestNG test class extends CamelSpringTestSupport and the Spring configuration MyConfig is initialized with AnnotationConfigApplicationContext:
public class TestNGTest extends org.apache.camel.testng.CamelSpringTestSupport {
#EndpointInject(uri = "mock:direct:end")
protected MockEndpoint errorEndpoint;
#Produce(uri = "direct:test")
protected ProducerTemplate testProducer;
#Override
protected AbstractApplicationContext createApplicationContext() {
return new AnnotationConfigApplicationContext(MyConfig.class);
}
#DirtiesContext
#Test
public void testRoute() throws InterruptedException {
// use templates and endpoints
}
}

Resources