Is there a way to use Spring web flow to store flow data into persistent storage instead of sticking it to http session - spring-webflow

Is there a way to use Spring web flow to store flow data into persistent storage instead of sticking it to http session. I'm looking to find a way to store web flow data in some persistent storage. Each time request comes spring loads the flow data and when response is sent back flow data is stored back and later retrieved when request comes back again. Reason for this is my application is running in multiple data centers and support transactions around 500tps and I don't want to manage session data across different data centers.

I think what you are looking for are implementations of FlowExecutionListenerAdapter
Out of the box SWF supports HibernateFlowExecutionListener and JpaFlowExecutionListener. If you want to use another db store you'd have to implement your own FlowExecutionListenerAdapter.
see the swf config here: Spring Web Flow and Spring MVC URL 404 to see how it is initalized
Note: interface ends with 'Adapter' impl classes end with 'Listener'

Related

Microservice to Microservice Architecure using gRPC : .NET Core

So I've this Microservice architecture where there is an ApiGateway, 2 microservices i.e., Configurations. API and API-1. The Configuration. API is mainly responsible to parse the JSON request and
access the DB and update Status tables, also to fetch required data, it even adds up more values to the JSON request and send it to the API-1. API-1 is responsible to just generate report based on the json passed.
Yes I can merge the configurations. API to the API-1 and make it a single service/container but the requirement is not to merge and create two different components i.e., 1 component purely based on
fetching the data, updating the status while the other just to generate the reports.
So here are some questions:
: Should I use gRPC for the configuration.API or is there a better way to achieve this.
Thank you.
RPC is a synchronous communication so you have to come up with strong reason to use it in service to service communication. it brings the fast and performant communication on the table but also coupling to the services. if you insist use rpc it is better to use MASSTRANSIT to implement the rpc in less coupled way. however in most cases the asynchronous event-base communication is recommended to avoid coupling (in that case look at CAP theory, SAGA, circuit breaker ).
since you said
but the requirement is not to merege and create two different
components
and that is your reason and also base on the fact
also to fetch requried data, it even adds up more values to the JSON
request and send it to the API-1
i think the second one makes scenes more. how ever i cant understand why you change the database position since you said the configuration service is responsible for that.
if your report service needs request huge data to generate report you have to think about the design. there is no more profile on you domain so there cannot be an absolute answer to this. but consider data reduce from insertion or request or some sort of pre-calculation if you could and also caching responses.

Session state access in Web API across domains

I have a ASP.Net API implementation, where to store and access the data / variables across consecutive calls, I am using a session state object as shown below and it can be successfully accessed in the multiple calls to separate calls by a browser:
// Access the current session object
var blSession = HttpContext.Current.Session;
// create the BL object using the user id
BL accessBL = new BL(userID);
// Store the Bl object in the session object dictionary
blSession["UserBL"] = accessBL;
I have to enable the following setting in the Global.asax, for the Session object to be accessible:
protected void Application_PostAuthorizeRequest()
{
// Enable session state in the web api post authorization
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
Issue comes in when the WebAPI shown above has to be accessed via another ASP.Net MVC client, which is separately hosted on a different machine, at that time same consecutive calls do not maintain the state as shown above and thus it leads to an exception, since the consecutive calls rely on session data to proceed.
I have seen a similar issue when I seen the similar issue when I use the Fiddler Debugger, as it gets hosted as a web proxy, so consecutive calls through that too fails, since it does not maintain the state. In my understanding, issue is due to setting the Cookie across domain, which doesn't seem to work across domains due to security reason
I know a workaround is to use an application wide variable like Cache, but please suggest if you have a way to get the SessionState work. Let me know if you need more details.
If you have not setup an alternative way to do SessionState, then the default behavior is to do it InMemory on the server. This is why you are seeing issues when the request is handled by a different ASP.NET server.
Web API calls are meant to be stateless. That is, they should not perform like a classic ASP.NET application that relies on the framework to store user specific information in Session variables across HTTP requests. For each call, pass in a user-specific identifier or token that you can then use to lookup information stored in your backend. You can store this information in your database or a distributed cache like MemCache for faster retrieval.

How can i send a object from Asp.net MVC controller to Asp.Net WebForm without using Session?

Actually i want to send a object from controller action to webform load method.
I don't like to use Session or QueryString.
As I understand your question, you want to use some object that you create in the MVC request in a later Webforms request.
In addition to using a Session variable or the QueryString, you can also store the object data in a cookie and retrieve it in the WebForm.
Each of the options has its advantages:
Session-variable: Object can be stored as is, no need to reload, e.g. from database. Decreases scalability because server memory is used per user.
Query String: data is visible, only viable for short strings.
Cookie: data is stored on the client and can be tampered with. Transferred between server and client several times. Size restrictions apply. Cookies might be disabled.
Handling a huge amount of data:
In the comments you mention that the data is huge. Therefore, I'd suggest to store the data once it is generated on the MVC part, e.g. in the database (or even the file system) and just transfer the id that is needed to retrieve the data on the Webforms end via one of the methods above. You might also need to erase the prepared data once they have been used or after some time in order to clean up left-over data.
Recreating the data in the Webform:
If you do not want to store the data in some kind of cache (database, file, server cache) and if you can recreate the data in the Webforms request (obviously you are able to create the huge amount of data in the MVC request), you can also choose to transfer only that bit of data to the Webform that is required to recreate the data. Bad in sense of performance, but good in that the user is always presented up-to-date information and you don't have to clean the cache if the data is not needed anymore.
In order to be able to share the functionality to create the data between the MVC controller and the Webform, you should move that to a dedicated class that is used in both web front ends.
If both the pages are in different domains -
From the MVC controller action make a HttpWebRequest to the webform page, in the Request body of HttpWebRequest send the data you want to send. On the retrieving side you can use Request object and read the data.
If both the pages are in same domain -
You can use Cache (server side), Cookies (client side), Hiddenfields (for Form Post from MVC controller to ASPX Page)

Use Spring Web Flow without state on the server

I'm reading the Spring Web Flow chapter in the book Pro Spring MVC. Unfortunately there's no explicit information, where the state during a flow execution is persisted. I assume it is saved in the JVM Heap and associated with the session.
Now HTTP is a stateless protocol (REST...) and I'd like to use Spring Web Flow without saving state on the server (besides the one and only state that a session might be authenticated).
One strategy is to send all parameters of the entire flow with every HTTP request of the flow (hidden input) and thus accumulating all necessary parameters until the flow has finished.
The overhead of re-validating parameters can be avoided with signatures over already validated parameters.
Do you know, whether it might be possible to use Spring Web Flow in this way? Has anybody already done this?
Update: Why?
Persisting state is not only a violation of the principles of HTTP as a stateless protocol but has practical problems too:
If the user browses with multiple browser tabs then this can lead to inconsistent state, race conditions or data loss.
Storing state on the server makes load balancing over several servers more complicate.
Testing and debugging becomes more complicate, because requests can not be tested or analyzed in isolation but only in the context of previous requests.
Cookies must be enabled to correlate servers sessions to requests.
The server needs to synchronize access to the server-side state.
The url of a request that also depends on server state does not contain all information necessary to bookmark the state inside a flow or to make sense of it in a bug report.
I've not yet looked at the details of Web Flow but I'm confident that one could have the same programming experience and still keep all information in the request parameters.
Update: I've now learned that my requested style of flow handling has a name: Continuations. The term continuation is more common in functional programming but it's apparently not uncommon to adapt the idea to HTTP interactions.
You might be interested in checking my bean flow FSM project (restflow):
https://github.com/alfonso-presa/restflow
Although it doesn't use Spring WebFlow, I think it may help answering the spirit of the question, as it allows the implementation of a stateless server orchestrated flow. I started this project because I wanted to make almost the same as you with spring WebFlow but I found it was not possible as state is stored in session (and also REST/json serialization is not built in).
It's main purpose is making an state-machine (just like WebFlow does) but with it's state stored in a bean, which you can persist in a distributed store, or easily sign or encrypt and send back to the client as continuation for next requests.
I hope you find it useful.
edit: I created a showcase project here: https://github.com/alfonso-presa/restflow-spring-web-sample

HttpSession Session ID different to FlexSession ID

I have a Flex application which is served via a JSP page. In this page I output the session ID using HttpSession when the page is loaded:
System.out.println("Session ID: " + session.getId());
In a very simple remote object hosted in BlazeDS (called from the flex application using an AMF Channel and standard RemoteObject functionality) I also output the session ID but this time using FlexSession (which as I understand is supposed to wrap around HttpSession).
System.out.println("FlexSession ID: " + FlexContext.getFlexSession().getId());
I would expect both IDs to be the same but this is not the case. The session IDs differ which is causing problems as there is data stored in the HttpSession which I need to be able to access from my remote objects within BlazeDS.
I've exhausted the reading material on BlazeDS and FlexClient/FlexSession/FlexContext but can't see why the FlexSession is not being linked to the HttpSession. Any pointers greatly appreciated.
I feel I must be missing something fundemental here, am I accessing the
I do not think that it is related to the FlashPlayer..is more related to the concept of FlexSession and how BlazeDS/LCDS works. For example you can have an active session even when not using the http channels - when using NIO/RTMP you are bypassing the application server and the http protocol. So it make sense to have an abstract class FlexSession with various implementations.
However when using BlazeDS FlexSession will wrap an HttpSession object internally, and removeAttribute/getAttribute/setAttribute are in fact calling the the same methods from the HttpSession object..so you can access all the data from the HttpSession. If not please provide more details.
However, it will not work when using RTMP channels(which exists only in LCDS by the way), you need to change your design in this case.
Thanks to both answers above I finally found the root cause and thought I'd share it on here.
The reason for differing session IDs was to do with the use of SSL for authentication and the use of AMF Channel rather than Secure AMF. Using the channel for the first time caused a new session to be created (hence the different ID) as the existing session related to the secure version of the site.
Silly configuration mistake but worth passing on - make sure that if using SSL that you're also using Secure AMF connecting to the secure endpoint rather than standard AMF or you'll run into the same session ID problems I faced.
Unfortunately this is just how the Flash player works. I have seen this same behavior many times.
The best solution I found was to establish the HTTP session and pass back the session ID. On the client side, you can then pass the session ID to the Flex application. You then send that ID from Flash to the server and use it to look up the existing session or establish a second session.
You will need to do something like this though, I have not been able to find a way to reliably get Flash to use the same session.

Resources