Manually setting up Spring WebSocket STOMP support - java

I'm trying to set up a STOMP WS endpoint using spring-websocket and spring-messaging. I am trying to do this manually: no application context is involved at all, and certainly no dispatcher. My goal is to wire up the appropriate Spring components in code inside a ServletContextListener, then register the wired up components directly with the javax.websocket.server.ServerContainer in my JSR 356 compatible container (Tomcat 7). At first, I would like to get this working with the "simple" broker built into spring-messaging; secondly, I would like to implement my own "broker" to directly integrate with an in-process ActiveMQ using the VM transport. This would be in contrast to the STOMP relay which spring-messaging also provides.
The Spring documentation states (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html):
"...Spring’s WebSocket support does not depend on Spring MVC. It is relatively simple to integrate a WebSocketHandler into other HTTP serving environments with the help of WebSocketHttpRequestHandler."
However, I am not finding it to be simple. Essentially, I started with:
public void contextInitialized(ServletContextEvent sce) {
ServerContainer websocketContainer = (ServerContainer) sce.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
???
websocketContainer.addEndpoint(???);
}
And ended up with an incoherent mess of assorted spring-websocket and spring-messaging constructor invocations which do not compile and are certainly not worth reproducing here.
I realize this is a bit vague, this is because I'm a bit lost! Has anyone done something like this, or has some general guidance to contribute?

Did you try sample application - tests for the stock portfolio. (This link is at the very end of the spring documentation link).
It says
Demonstrates 3 approaches to testing a Spring STOMP over WebSocket application:
Server-side controller tests that load the actual Spring configuration (context sub-package)
Server-side controller tests that test one controller at a time without loading any Spring configuration (standalone sub-package)
End-to-end, full integration tests using an embedded Tomcat and a simple STOMP Java client (tomcat sub-package)
See the Javadoc of the respective tests for more details.
Second option is probably what you need.

Related

Difference between an Express server and an embedded server in spring boot

I've started learning Spring Boot coming from a NodeJS/Express background and I'm wondering what's the difference between the server that we create ourselves in an express app that listens on a certain port, and the Tomcat server in a spring application also called a container ? Why can't we do the same in a spring boot application where we create the server ourselves ?
const app = express();
app.listen(3000, () => console.log("Server listening on port 3000"));
Welcome to the Spring Ecosystem. We hope you enjoy your stay!
My first bit of advice, forget everything you know about Express because Spring is very different. I have not used Express in a while, but I remember it had a very programmatic approach. While that is possible in Spring, the most popular approach is declarative with annotations. Or, if you are old and like old technology, you can configure everything with XML.
What's Tomcat? Tomcat is a implementation of various Jakarta EE (formally Java EE) specifications. Depending on the Spring Boot version, you may see packages that start with jakarta or javax. Tomcat implements, Jakarta Servlet, Server Pages, Expression Language, WebSocket, Annotations, and Authentications. You can read more about each specification here. Note: Spring Boot by itself does not necessary use all of these modules and mostly Spring has many abstraction layers on top of them anyway, so you rarely will work with Tomcat directly. Specifically, spring-boot-starter-tomcat is the Spring module that uses Tomcat, and is most often included as a transitive dependency through spring-boot-starter-web.
Now, to answer your question...
Spring Boot Web configures Tomcat for you. You can definitely override this behavior! One basic way is through configuration properties. Anything under server.tomcat. A good IDE should autocomplete and show you the options. You can also change the address and port of the Tomcat server with server.address and server.port. Another popular property developers change is server.error.whitelabel.enabled. They set it to false and provide their own error page. Here is a great example. By the way, Baeldung offers a lot of free Spring tutorials and guides. It is a great place to get started. They also offer paid courses with certifications.
FYI, you do not have to use Tomcat. Read more here.

Spring Webflux - Actuator - Netty thread metrics?

Small question regarding Netty metrics for a Spring Webflux + actuator project please.
In the Spring MVC world, combined with actuator, we have metrics such as:
tomcat_threads_busy_threads
tomcat_threads_current_threads
tomcat_threads_config_max_threads
jetty_threads_busy
jetty_threads_current
jetty_threads_config_max
Which helps a lot to get the overall status of the application.
However, in Webflux, it seems there is no equivalent.
I was expecting something like netty_threads_busy or something equivalent, but could not find anything related.
May I ask what would be the equivalent in Netty Webflux world please?
Thank you
The metrics expose by reactor-netty are not enabled by default in spring boot. There was a previous discussion on this github issue and the decision was not to enable these by default.
If you wanted to enable the netty server metrics in your own application, you can add the following bean to customise the Netty HttpServer.
#Bean
public NettyServerCustomizer nettyServerCustomizer(){
return httpServer -> httpServer.metrics(true, uriMappingFunction);
}
Caveat:
If you have path parameters in any of your URIs you should provide a uriMappingFunction that converts them to templated URIs ie. /user/1 -> /user/{id}. Failure to do so could lead to cardinality explosion in your MeterRegistry.
Enabling this feature also comes with the following recommendation:
It is strongly recommended applications to configure an upper limit for the number of the URI tags.
Reference Documentation
Java Doc

Dynamic Spring Boot-Integration configuration

I would like to migrate a multi-threaded application in JSE to Spring Integration but I have to clarify some points before. First of all, the application will have the following Spring integration components:
JMS to Transformer to router to TCPOut
TcpIn (to router) to Transformer to JMS
In this context, I have to load all the TCP connections dynamically from a configuration file. I saw a couple of example of this here in StackOverflow (based in the FTP sample). These samples could be enough for the first part but I am looking for how to do that in Spring Boot and what is the best (and elegant) way to create this type of configuration.
Finally, I have to access to each different context (this is maybe the most important) from a type of Swing monitor to start/stop manually this TCP connections. Is this possible? What do you suggest me to do?
All my current components are java based configuration (not DSL).
See my answers to this question and its follow-up for examples of how to dynamically create application contexts using Java Configuration.
Also, take a look at the new feature in the Java DSL for dynamically registering/removing integration flows with the context. The 1.2 version of the DSL, containing this feature, will be released shortly.
You can stop/start endpoints using JMX or a control bus, or programmatically.

Is it possible to add spring MVC (with embedded Jetty) to a spring integration component

I have examples of both working individually, now trying to merge so that I have both capabilities / entry points.
Not surpised it is confused about the application contexts to load.
I want to know if this is even possible and if so any examples?
I know it is doable with spring boot however not wanting to move to that just yet.
I am attempting the impossible?
"Spring MVC (with embedded Jetty)" usually means an HTTP endpoint running in its own JVM (I suppose you have a main method that starts Jetty). Once you have that started, you can integrate it as any other HTTP endpoint in Spring Integration.
If you want them both to run in the same JVM, that probably means you don't want to make use of HTTP as you can invoke methods directly on your #Controllers or #Services.
Or perhaps I'm missing something here... ?
I'd go for Spring Boot. Version 1.1.6 was just released. I'm currently also migrating an "old" SI application to be based upon Spring Boot. I suggest you give http://start.spring.io a try. Migration should not be too difficult.

DI in an EJB/MDB Application

I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html

Categories

Resources