Jetty : websocket extended Custom Servlet - websocket

I am working on a Existing Jetty based WebSocket code .
In the existing code , in that servlet there are two methods implemented
1. public WebSocket doWebSocketConnect()
2.protected void doGet(HttpServletRequest request, HttpServletResponse response)
As these are callback methods
Could anybody please let me know what method is called first (I mean the method order )
Thanks in advance .

The WebSocketServlet in jetty-7, and jetty-8 (note: this has changed in jetty-9), has a few requirements for you.
The doWebSocketConnect(HttpServletRequest,String) needs to be implemented by you to create a WebSocket object (of your design) based on the information you can find in the HttpServletRequest. (such as host, paths, authentication, etc ...)
You can see an example of a Servlet in the test cases.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/helper/WebSocketCaptureServlet.java
This creates a CaptureSocket, stores it in the Servlet instance for tracking, and returns it.
The CaptureSocket just stores the incoming Messages so that the test cases can validate the expectations.
This isn't a particularly exciting Servlet/Socket impl.
An example of a few flavors of Echo sockets can also be found in the TestServer (also found in the test cases).
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/TestServer.java#n53

Related

Spring Boot - Camel - Tracking an exchange all the way through

We are trying to setup a very simple auditing database table for a very complex Spring Boot, Camel application with many routes (mostly internal routes using seda://)...the idea being we record in the database table each route's processing outcome. Then when issues arise we can login to the database, query the table and pinpoint exactly where the issue happened. I thought I could just use the exchange-id as the unique tracking identifier, but quickly learned that all the seda:// routes make new exchanges, or at least that's what I'm seeing (camel version 2.24.3). Frankly, I don't care what we use for the unique identifier...I can generate a UUID easily enough and the use the exchange.setProperty("id-unique", UUID).
I did manage to get something to work using the exchange.setProperty("id-exchange", exchange.getExchangeId()) and have it persist the unique identifier thru the routes...(I did read that certain pre-defined route prefixes such as jms:// will not persist exchange properties though). The thought being, the very first Processor places the exchangeId (unique-id) on the exchange properties, my tracking logic is in a processor that I can include as part of the Route's definition :
#Override
public void configure() throws Exception {
// EVENTS : Collect statistics from Camel events
this.getContext().getManagementStrategy().addEventNotifier(this.camelEventNotifier);
// INITIAL : ${body} exchange coming from a simple URL endpoint
// POST request with an XML Message...simulates an MQ
// message from Central MQ. The Web/UI service places the
// message onto the camel route using producerTemplate.
from("direct:" + Globals.ROUTEID_LBR_INTAKE_MQ)
.routeId(Globals.ROUTEID_LBR_INTAKE_MQ)
.description("Loss Backup Reports MQ XML inbound messages")
.autoStartup(false)
.process(processor)
.process(getTrackingProcessor())
.to("seda:" + Globals.ROUTEID_LBR_VALIDATION)
.end();
}
This Proof-of-Concept (POC) allowed me to at least get things tracking like we want...note multiple rows with the same unique identifier :
ID_ROW ID_EXCHANGE PROCESS_GROUP PROCESS_STEP RESULTS_STEP RESULTS_MESSAGE
1 ID-LIBP45P-322256M-1603188596161-4-6 Loss Backup Reports lbr-intake-mq add lbr-intake-mq
2 ID-LIBP45P-322256M-1603188596161-4-6 Loss Backup Reports lbr-validation add lbr-intake-mq
Thing is, this POC is proving to be rigid and difficult to record outcomes such as SUCCESS versus EXCEPTION.
My question is, has anyone done anything like this? And if so, how was it implemented? Or is there a fancy way in Camel to handle this that I just couldn't find on the web?
My other ideas were :
Set an old fashion Abstract TrackerProcessor class that all my tracked Processors extend. Then just have a handful of methods in there to create, update, etc... Each processor then just calls inherited methods to create and manage the audit entries. The advantage here being the exchange is readily available with all the data involved to store in the database table.
#Component
public abstract class ProcessorAbstractTracker implements Processor {
#Override
abstract public void process(Exchange exchange) throws Exception;
public void createTracker ( Exchange exchange ) {
}
public void updateTracker ( Exchange exchange, String theResultsMessage, String theResultsStep ) {
}
}
Set an #Autowired Bean that every tracked Camel Processor wires in and put the tracking logic in the bean. This seems to be simple and clean. My only concern/question here is how to scope the bean (maybe prototype)...since there would be many routes utilizing the bean concurrently, is there any chance we get mixed processing values...
#Autowired
ProcessorTracker tracker;
Other ideas?
tia, adym

How to write webSockets for Rest calls in Spring-boot?

I'm new to web socket programming. I have more than 10 methods annotated with #GetMapping, where the returned data is read from a MySQL database.
Can anyone help me to know how to write WebSockets.
My WebRestController.java looks like the below:
#CrossOrigin(origins = "http://localhost:4200", allowedHeaders="*")
#RestController
#RequestMapping("/api")
public class WebRestController {
#GetMapping("/summary")
public String Summary() { /* ... */}
#GetMapping("/erday")
public String Erday(String erday) { /* ... */}
#GetMapping("/count")
public String Count(#RequestParam Map<String,String> queryParam,
String date, String target) { /* ... */}
#GetMapping("/details")
public String Details(#RequestParam Map<String,String> queryParam,
String date, String target) { /* ... */}
#GetMapping("/devmawah")
public String DevMawah(#RequestParam Map<String,String> queryParam,
String date, String target) { /* ... */}
// ....
}
I tried before many times in internet to find the solution, but couldn't find it. All I found are examples for Chat applications, which have 2 endpoints to send and receive.
WebSockets are used for bi-directional communication, not really for REST style services (where HTTP is superior in my opinion). The core difference being that HTTP is fundamentally a request-reply protocol, which fits very well to REST whereas WebSocket is centred around messages. Of course, you can argue that request-reply is a specialisation of message-based communication.
There are several articles on this topic (google REST over WebSocket) and even some StackOverflow questions which detail the pros and cons, for example Is ReST over websockets possible?.
The only way that I know of which allows you to do something resembling REST over WebSocket without having to re-write the RestController is swagger-socket, but I would not recommend using it as the project seems to be inactive now and it seems to not have been used extensively.
Alternatively, you can replace your #RequestMapping or #GetMapping annotations with #MessageMapping annotations and model your API through messages (e.g. the client sends a "GET" message to a given destination, and you send back a message containing the resources).
I can say 99% of reasons that brings us to the idea of Rest Over Websocket is just because we are looking at the problems from wrong direction.
But I wrote such library because I am going to need it in another dummy project I will write later, and you can check it out.
Basically what it does is to scan your controllers, and create a websocket handler that can pass data to those controllers, depending on path, method, and inputs. But there is a lot more it handles internally to achieve this goal.
I havent started the docs yet, so, you can check the sample from website for now.
Well... Just my little contribution...
First you you should code your websocket handler (taking into account the potential size the payload). Then, you should create a config class to register your hander (I am thinking not in a stomp version).
In your handler, after you stablish the connection with the websocket server, you should have a custom component to hold the sessions (maybe a map of usernames and a session wrapper). This is useful, as you you could send messages not only through the ws connection but also through a rest api endpoint (you could hit an endpoint or using an scheduler tasks to periodically send messages to certain users upon certain conditions). Will post again a link later

Good idea using ControllerAdvice to perform REST authentication of a request?

In my current Spring Boot application i seem to hit a wall when trying to implement a REST request filter. My goal with the request filter was to read the header and body part and validate the incoming data and check if it meets the HMAC construction we are using.
So the request filter seemed not to work an alternative solutions is to use #ControllerAdvice.
Then the request validation can be implemented very easy. But i am not sure if it normally seen as an incorrect usage of the #ControllerAdvice annotation.
#ControllerAdvice
public class GenericWebControllerAdvice {
#ModelAttribute
public void authenticationFilter(#RequestHeader(value = "Authorization") String authHeader, #RequestBody String payload) {
// process authentication based on header info and body content
// calculate the hash and check if meets the security settings
// if the hash fails throw an exception that returns a http status code
}
}
Any comments on the solution or alternatives that are better?
No you should do the validation in the controller (ie method with #RequestMapping).
Spring supports JSR 303/349 bean validation. Thus if your request body is a POJO and you have the correct annotation Spring will automatically do the validation for you. There is a tutorial of that here:
http://www.leveluplunch.com/java/tutorials/017-validate-spring-rest-webservice-request/
As for request parameter validation (ie not bean validation) I have had to make my own transfer objects and exception handling. How you do global exception handling is covered in the Spring Reference guide but generally you extend and/or register a org.springframework.web.servlet.handler.SimpleMappingExceptionResolver. Ironically #ControllerAdvice can be used for exception handling but I find it better to extend and register an Exception Resolver. More info can be found here:
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers
Edit based on OP comments and edits:
If your doing authentication or some other request based validation/authorization its probably best to use an Interceptor. Reference doc. #ControllerAdvice will probably not work as the request handling is too far a long. That is you want something before databinding happens.

How does Spring MVC handle multiple users

I am using spring from more than 6 months. I am not able to understand this underlying mechanism related to the below scenario.
I have a spring web app. Now I autowired the model in controller. Based on url matching it calls respective method. all my methods are singleton.
Now when two users are opening app at same time spring is able to run them parallelly and give results to them. I didnt understand how can it do this. i mean as the bean is singleton it has to either the wait till the bean is not used or overwrite the data in the bean. But spring is working correctly. Can someone explain this behaviour with some analogy.
To explain my question clearly below is a piece of code:
My default controller is simple one:
#Autowired
private AppModel aModel;
public AppModel getModel(){
return aModel;
}
public void setModel(AppModel aModel){
this.aModel = aModel;
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView defaultGetter(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView(getViewName());
mav.addObject("model", aModel);
Runtime.getRuntime().gc();
return mav;
}
Also can some one tell me when two clients open the app will two seperate models get generated when i use #autowired . If only one model bean exists for all clients then say the request from client 1 came in and it take me 30 sec to get results back. Now if second client sends request in 3rd sec then will the first clients request gets overwritten?
I think I am getting confused. Can some one clarify how this magic is happening?
Thanks
Every web request generate a new thread as explained in this thread.
Spring manages different scopes (prototype, request, session, singleton). If two simultaneous requests access a singleton bean, then the bean must be stateless (or at least synchronized to avoid problems). If you access a bean in scope request, then a new instance will be generated per request. Spring manages this for you but you have to be careful and use the correct scope for your beans. Typically, your controller is a singleton but the AppModel has to be of scope request, otherwise you will have problems with two simultaneous requests. This thread could also help you.
About your last question "how this magic is happening?", the answer is "aspect/proxy". Spring create proxy classes. You can imagine that Spring will create a proxy to your AppModel class. As soon as you try to access it in the controller, Spring forwards the method call to the right instance.

Check preconditions in Controller or Service layer

I'm using Google's Preconditions class to validate user's input data.
But I'm worried about where is the best point of checking user's input data using Preconditions class.
First, I wrote validation check code in Controller like below:
#Controller
...
public void register(ProductInfo data) {
Preconditions.checkArgument(StringUtils.hasText(data.getName()),
"Empty name parameter.");
productService.register(data);
}
#Service
...
public void register(ProductInfo data) {
productDao.register(data);
}
But I thought that register method in Service layer would be using another Controller method like below:
#Controller
...
public void register(ProductInfo data) {
productService.register(data);
}
public void anotherRegister(ProductInfo data) {
productService.register(data);
}
#Service
...
public void register(ProductInfo data) {
Preconditions.checkArgument(StringUtils.hasText(data.getName()),
"Empty name parameter.");
productDao.register(data);
}
On the other hand, the method of service layer would be used in just one controller.
I was confused. Which is the better way of checking preconditions in controller or service?
Thanks in advance.
Ideally you would do it in both places. But you are confusing two different things:
Validation (with error handling)
Defensivie Programming (aka assertions, aka design by contract).
You absolutely should do validation in the controller and defensive programming in your service. And here is why.
You need to validate for forms and REST requests so that you can send a sensible error back to the client. This includes what fields are bad and then doing localization of the error messages, etc... (your current example would send me a horrible 500 error message with a stack trace if ProductInfo.name property was null).
Spring has a solution for validating objects in the controller.
Defensive programming is done in the service layer BUT NOT validation because you don't have access to locale to generate proper error messages. Some people do but Spring doesn't really help you there.
The other reason why validation is not done in the service layer is that the ORM already typically does this through the JSR Bean Validation spec (hibernate) but it doesn't generate sensible error messages.
One strategy people do is to create their own preconditions utils library that throws custom derived RuntimeExceptions instead of guava's (and commons lang) IllegalArgumentException and IllegalStateException and then try...catch the exceptions in the controller converting them to validation error messages.
There is no "better" way. If you think that the service is going to be used by multiple controllers (or other pieces of code), then it may well make sense to do the checks there. If it's important to your application to check invalid requests while they're still in the controller, it may well make sense to do the checks there. These two, as you have noticed, are not mutually exclusive. You might have to check twice to cover both scenarios.
Another possible solution: use Bean Validation (JSR-303) to put the checks (preconditions) onto the ProductInfo bean itself. That way you only specify the checks once, and anything that needs to can quickly validate the bean.
Preconditions, validations, whether simple or business should be handled at the filter layer or by interceptors, even before reaching the controller or service layer.
The danger if you check it in your controller layer, you are violating the single responsibility principle of a controller, whose sole purpose is to delegate request and response.
Putting preconditions in service layer is introducing cross cutting concerns to the core business.
Filter or inceptor is built for this purpose. Putting preconditions at the filter layer or in interceptors also allow you to “pick and match” rules you can place in the stack for each servlet request, thus not confining a particular rule to only one servlet request or introduce duplication.
I think in your special case you need to to check it on Service layer and return exception to Controller in case of data integrity error.
#controller
public class MyController{
#ExceptionHandler(MyDataIntegrityExcpetion.class)
public String handleException(MyDataIntegrityExcpetion ex, HttpServletRequest request) {
//do someting on exception or return some view.
}
}
It also depend on what you are doing in controller. whether you return View or just using #ResponseBody Annotation. Spring MVC has nice "out of the box" solution for input/dat validation I recommend you to check this libraries out.
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html

Resources