How to use wamp with JSR 356? - websocket

JSR 356 supports subprotocols and I found an exemple of use in javaee7-samples.
#ServerEndpoint(value="/endpoint",
subprotocols="mySubprotocol")
public class MyEndpoint {
#OnMessage
public String echoText(String text) {
System.out.println(text);
return text;
}
}
But I can not find documentation on supported subprotocols. Is there any implementation of wamp (wamp.ws/spec) for the JSR 356 ? And how to use it ?

There is at least one implementation of wamp in Java (jWamp). You will find more details about it here: http://wamp.ws/implementations/ and here: https://github.com/ghetolay/jwamp.
The problem is, that this implementation is not stable yet and it's only compatible with Jetty.
You can also try to implement it by Your own.

Related

SpringBoot log4j AppenderSkeleton The method append(LoggingEvent) must override or implement a supertype method

I'm trying to create a custom appender using log4j after looking at the given example -
Link:- How to create my own Appender in log4j?
I did as follows:-
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class MyCustomAppender extends AppenderSkeleton
{
private MailServiceImpl mail = new MailServiceImpl();
#Override
public void close() {
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
mail.sendMail(event.toString());
}
}
It gives me error because of the overridden methods - The method append(LoggingEvent) of type MyCustomAppender must override or implement a supertype method. I tried to search for solution but found none. And nobody seem to have faced the problem. Where am I going wrong? Please help me.
I believe you are looking for a solution for Log4j2 but the stackoverflow page you are linking to is over 3 years old ( might be an older version of Log4j )
Looking at javadoc of older version it does show AppenderSkeleton could be used to override the appender() method however you mention you get a compile error
The method append(LoggingEvent) of type MyCustomAppender must override
or implement a supertype method
This is because there is no such method to override in Log4j2
Please provide version of what Log4j you are using, meanwhile have a look at this answer incase you are using Log4j2

Convert Spring Cloud Stream to use reactive cloud function

Currently I have Spring Boot application which is something like this.
#Component
#EnableBinding(Source::class)
class EmailMessageProducer(private val source: Source) {
suspend fun send(textMessage: TextMessage) {
source.output().send(
MessageBuilder.withPayload(textMessage).setHeader("service", "test").build()
)
}
}
I would like to use Spring Cloud Function here using reactive pattern.
Furthermore, is my current solution non blocking? I am asking this because this is my first time using Kotlin coroutine in this context.
Java solution works for me as well since I am just trying to understand the concept here.
What you're looking for is a reactive Supplier (e.g., Supplier<Flux>).
In your case it would look something like this:
#SpringBootApplication
public class SomeApplication {
#Bean
public Supplier<Flux<Message<String>>> messageProducer() {
return () -> Flux.just(MessageBuilder.withPayload(textMessage).setHeader("service", "test").build());
}
}
Provide spring.cloud.function.definition=messageProducer property and this is pretty much it.
Obviously the above example produced a finite stream with a single item, but feel free to modify the returned flux. In fact we discuss this in more details here.

Reading multiple entity scan packages in spring boot application

I have Spring boot application
#SpringBootApplication
#EntityScan(basePackages = {"${scan.packages}"})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
While reading multiple entity scan packages from one property separated by comma like below?
scan.packages=com.mycompany.model.package1 ,
com.mycompany.model.package2
I got this exception :
java.lang.IllegalArgumentException: Unknown entity:
com.mycompany.model.package2.Myclass
You can scan multiple Entity like this
#EntityScan(basePackages= {"scan.packages1","scan.packages2"})
This should work
#EntityScan(basePackages = {"#{'${scan.packages}'.split(',')}"})
According to the EntityScan annotation javadoc there are three ways to define the packages where to scan for entities:
value, alias for basePackages: #EntityScan( {"scan.packages1","scan.packages2"})
basePackages, alias for value: #EntityScan(basePackages= {"scan.packages1","scan.packages2"}).
basePackagesClasses, the type safe version: #EntityScan(basePackages=E.class}.Where E was a marker interface just to underline the Entities. Please see the code bellow. It could also be an annotation.
interface E {
}
#Entity
public class Glass implements E {
// Typical code to be added here
}
Or as an annotation:
#Retention(RetentionPolicy.RUNTIME)
#interface E {
}
#Entity
#E
public class Glass implements E {
// Typical code to be added here
}
From my perspective I would choose either using directly value or basePackageClasses. If I can something easier to read I would do that, and I think that is what value does, while the basePackageClasses introduces the added benefit of type safety and I can see multiple reasons to go for that. It all depends on the context.
I hit the same problem and posted an issue on the Spring Boot issue tracker about it.
The answer was that
... As shown by #25436, #EntityScan did support property solution in 2.3 so, if we decide to reinstate support, we might want to consider how to handle multi-value properties.
So it appears some Spring Boot version did support it, but then the support was dropped again... for more info, check the Spring Boot issue linked in the quote.
try this :
#EntityScan(basePackages= {"${scan.packages1","scan.packages2}"})

How do a I setup mongodb messagestore in aggregator using annotation

I am trying to add an aggregator to my code.
Couple of problems I am facing.
1. How do I setup a messagestore using annotations only.
2. Is there any design of aggregator works ? basically some picture explaining the same.
#MessageEndpoint
public class Aggregator {
#Aggregator(inputChannel = "abcCH",outputChannel = "reply",sendPartialResultsOnExpiry = "true")
public APayload aggregatingMethod(List<APayload> items) {
return items.get(0);
}
#ReleaseStrategy
public boolean canRelease(List<Message<?>> messages){
return messages.size()>2;
}
#CorrelationStrategy
public String correlateBy(Message<AbcPayload> message) {
return (String) message.getHeaders().get(RECEIVED_MESSAGE_KEY);
}
}
In the Reference Manual we have a note:
Annotation configuration (#Aggregator and others) for the Aggregator component covers only simple use cases, where most default options are sufficient. If you need more control over those options using Annotation configuration, consider using a #Bean definition for the AggregatingMessageHandler and mark its #Bean method with #ServiceActivator:
And a bit below:
Starting with the version 4.2 the AggregatorFactoryBean is available, to simplify Java configuration for the AggregatingMessageHandler.
So, actually you should configure AggregatorFactoryBean as a #Bean and with the #ServiceActivator(inputChannel = "abcCH",outputChannel = "reply").
Also consider to use Spring Integration Java DSL to simplify your life with the Java Configuration.

How does Spring wire method parameters?

I have this Spring method which just maps a resource onto a .jsp :
#ResourceMapping(value = "display")
public String displayResult() {
return "mypage"
}
If I update the method to :
#ResourceMapping(value = "display")
public String displayResult(javax.portlet.ResourceResponse rr) {
rr.setContentType("text/html;charset=UTF-8");
return "mypage"
}
the variable rr is initialised but what Spring "magic" is occurring in the background to initialise the object javax.portlet.ResourceResponse ?
This is part of the Spring MVC framework. The default rules are explained in the section "Defining #RequestMapping handler methods" of the Spring documentation (Link for 3.2.x)
My guess is that you have a helper library on your classpath which extends the defaults for the annotation #ResourceMapping and the type ResourceResponse
As Aaron pointed out, there default rules for resolving arguments for handler methods explained in a link he provided.
However, making a handler method accept other types of parameters is achieved not by extending #ResourceMapping annotation, but by implementing new WebArgumentResolver prior to Spring 3.1 and HandlerMethodArgumentResolver from 3.1. See http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/method/support/HandlerMethodArgumentResolver.html
In your case, javax.portlet.ResourceResponse is probably directly supported by the Spring web mvc portlet framework, though I couldn't find a documentation for this. In your IDE, you can have a look at all classes implementing HandlerMethodArgumentResolver (or WebArgumentResolver)

Resources