Saving object as variable inside activiti - spring-mvc

We are revamping a big enterprise application which has more business workflows. We are using activiti bpm with spring MVC. Currently we are saving the required variables for workflow inside execution individually. My idea is to create object for each workflow and save the object as variable inside activiti execution instead of individual variables.
For example for the job application workflow I will have JobRequest object which have all the requested details like approvers, interviewers, candidate profiles, current status, etc., I will save this object as variable inside activiti. Whenever I need I will just get the object back and show the needed info on the web page. It will be hassle free than maintaining all those information on separate tables and getting the reference alone from activiti.
Is this good approach?
Still I have some concerns on my approach.
If suppose later we add additional fields to the Class. Then how to
handle the history object variables. (In the above example we are
adding additional field under JobRequest.class).
In our current approach if some values really needs to be verified I
can connect to the activiti database and able to see. Because the
variables are saved individually.
Any valuable suggestion?

Related

User Defined Workflows Implementation

As part of our product requirements, we need to support a dynamic workflow configuration that will be set by the product's administrations.
Below is an example from Monday's system of this concept.
Meaning that the user can define the custom flow of event --> conditions / branches --> actions that will set the workflow.
Need to support events that are based on schedule and also on system configurations changes (an object changed it's state)
What is the best way to implement this on the back-end side? what module/tool should be used in order to execute the workflows?
We thought of the following design:
Create a workflow object for the whole workflow tree saving it as a hierarchical JSON object that contains the defined user hierarchy of the different objects (event, conditions, actions) and storing it in the database.
Use Apache Workflow as an orchestrator and create DAG dynamically based on the defined workflows and update them accordingly.
Is there a better tool to implement the following design? (saw some posts relating to this, but with no answer: 1, 2)
Thanks!

Reason to integrate Spring Web-flow with Spring MVC

Why(In what scenarios) do we need to integrate Spring Webflow with Spring MVC? Both these frameworks are used to create web-app and I do not see any point why we would integrate them. I would appreciate if someone could clarify me about it.
This is really late but I don't see a satisfactory answer to this question and would like to share an approach I had tried in a recent project which I feel is better than the spring web flow approach which is strictly tied down to spring views and unnecessarily adds to the already existing xml load . I created a SPA(Single Page Application) using angular js with Spring MVC. In angular js I did not use routers or state, rather I created a div within the controller like below
On the server side to capture all possible transitions from one frame(I am referring to a particular screen in the SPA) to another I created a tree of rules using MVEL . So in the database I had a structure which stored a tree of rules for every frame . The data in the MVEL expressions were being set by the various services each action invoked. Thus on any action the following steps were followed.
1) Validate the action.
2) Invoke various services.
3) Capture the data from these services and merge it with the existing data of the user.
4) Feed this captured data into collection of rules for each frame along with the details of the current frame.
5) Run the rules of the tree w.r.t to current frame and fetch its output.
6) If there is only one transition then that is the final transition. If there are 2 transitions and one is default then ignore the default transition and use the other transition.
7) Return the template name of the transition to the angular controller and set the value of the page variable in the scope of the controller.
Using this approach all my services had to do was store data in different data fields w.r.t a particular action. All the complex if-else conditions for Web Flows or any complex process definitions(like the one defined in Spring-Web Flow) were not required. The MVEL rule engine managed all that and since it was all in the database it could be changed without needing a server re-start.
I believe this generic approach with MVEL is a flexible approach which comprehensively handles the problem of a convoluted flow without making the application code a mess or adding additional unnecessary xml files.
We combine both. Web Flow for the multi-step activities, where it doesn't make sense to jump into the middle of a process, and plain-MVC Controllers for the single-step activities. Things you might bookmark individually.
For example, an appointment-scheduling application, "find my appointment" might be a single Controller that accepts identifying information. "Make a new appointment" is a flow, with multiple steps of selecting a location, date, time, confirm the appointment, etc.
If your application have complex Flow pages, events which need to be defined as Finite state machine then use Webflow. It would be justified to use webflow for website where you buy Insurance, Flight Tickets. Web Flow conditions are like:
There is a clear start and an end point.
The user must go through a set of screens in a specific order.
The changes are not finalized until the last step.
Once complete it shouldn't be possible to repeat a transaction accidentally

MVC3 + MongoDB Architecture: Store models directly to database?

I am currently developing a mvc3 application using mongodb. I am quite unsure on how i shall build the architecture. E.g. my app has a page used for managing the user profile for a registered user (like name, email, some attributes exposed inside enum-comboboxes). Hence i have a ManageProfileModel.cs with all properties to manage. What's the proper way to use the data with mongodb? Shall i store the ManageProfileModel data inside mongodb or do i have to add an additional layer containing domain classes like User.cs, Invoice.cs, ... and store these objects inside mongodb (these objects are being used in the models created)?
I am asking because a model for managing a user profile does not necessarily resemble a user (domain) object. My first approach is to store directly my (view)models inside mongodb. I am not sure if its that easy to get my (consistent) data at a later point.
Thanks!
I would store the models directly in Mongo as-is for most of your data. I'm sure you know this already, but Mongo focuses on denormalization, and so it's different than traditional relational databases that want you to normalize your data.
So for a profile, you might have a user, a set of invoices, a set of addresses etc. As you decide your data models, I would suggest the following:
Consider your UI. If you need user + profile + invoices, go ahead and make a document like that. Makes your life a lot easier.
Don't be afraid to have repeated information stored.
You will constantly be wondering if you should embed a document (adding addresses to user) or link to a document (put a list of references in an array referencing invoices). The rule I've heard that I think is good: If the data is constantly changing, make a link/reference. If it's immutable or slowly changing, embed it.
If your document will grow a lot over time, considering breaking it up. Mongo has to move your document in memory if it grows too big.

How to store the model of a application?

I am working on an StoryBoarding application,it is a slide based application in which the authors can put several components like image , sound , captions etc in each of the slide.A collection of slides will make a storyboard.This application will be deployed on a web server (sharepoint + IIS , and php+apache), and several users can collaborate with each other for authoring or reviewing the storyboard.In my application I also want to support auto save ,which will keep on storing the state of the storyboard.User can also save at any point of time by clicking the save button.
I am confused about how to store the state of the storyboard.
1)Presently I am doing this by passing all the storyboard data to a dot net web-service and then that service is storing images,caption etc in their respective tables into a database .
2)Another approach possible is to store the model of the application as a serialized object into the db , which will be more convenient since separating the components of the model (like images,captions etc..) will not be required and also restoring the state of the objects in the application will be easy .
I have two doubts about using approach 2 :-
i) I want the the saved storyboard to load quickly, for which I would like to support the partial so that lighter objects like caption can be loaded quickly but other heavier objects like image,video etc can be loaded on demand. Using approach 2 , do I have to send the whole data in one go or is there way to support partial loading ?
ii) How to implement the auto save feature when using approach 2, for every auto save do I have to send the whole serialized object again back to db or is there a way to send only the changed part of the model to be stored in db .
Please suggest which approach would be better to use for this application , and also answer afore mentioned doubts regarding using approach 2 .
If i would be working on such Application i will use Approach DIVIDE AND RULE, a design seprate logic to save and retrive each components like Images, sound etc, because it can easly handles any modification and enhancement in application,
Another thing is that it will take longer time to save, update and load data from backend if you use approach 2.
I am with approach 1.
Hopes that helps

Ways to store an object across multiple postbacks

For the sake of argument assume that I have a webform that allows a user to edit order details. User can perform the following functions:
Change shipping/payment details (all simple text/dropdowns)
Add/Remove/Edit products in the order - this is done with a grid
Add/Remove attachments
Products and attachments are stored in separate DB tables with foreign key to the order.
Entity Framework (4.0) is used as ORM.
I want to allow the users to make whatever changes they want to the order and only when they hit 'Save' do I want to commit the changes to the database. This is not a problem with textboxes/checkboxes etc. as I can just rely on ViewState to get the required information. However the grid is presenting a much larger problem for me as I can't figure out a nice and easy way to persist the changes the user made without committing the changes to the database. Storing the Order object tree in Session/ViewState is not really an option I'd like to go with as the objects could get very large.
So the question is - how can I go about preserving the changes the user made until ready to 'Save'.
Quick note - I have searched SO to try to find a solution, however all I found were suggestions to use Session and/or ViewState - both of which I would rather not use due to potential size of my object trees
If you have control over the schema of the database and the other applications that utilize order data, you could add a flag or status column to the orders table that differentiates between temporary and finalized orders. Then, you can simply store your intermediate changes to the database. There are other benefits as well; for example, a user that had a browser crash could return to the application and be able to resume the order process.
I think sticking to the database for storing data is the only reliable way to persist data, even temporary data. Using session state, control state, cookies, temporary files, etc., can introduce a lot of things that can go wrong, especially if your application resides in a web farm.
If using the Session is not your preferred solution, which is probably wise, the best possible solution would be to create your own temporary database tables (or as others have mentioned, add a temporary flag to your existing database tables) and persist the data there, storing a single identifier in the Session (or in a cookie) for later retrieval.
First, you may want to segregate your specific state management implementation into it's own class so that you don't have to replicate it throughout your systems.
Second, you may want to consider a hybrid approach - use session state (or cache) for a short time to avoid unnecessary trips to a DB or other external store. After some amount of inactivity, write the cached state out to disk or DB. The simplest way to do this, is to serialize your objects to text (using either serialization or a library like proto-buffers). This helps allow you to avoid creating redundant or duplicate data structure to capture the in-progress data relationally. If you don't need to query the content of this data - it's a reasonable approach.
As an aside, in the database world, the problem you describe is called a long running transaction. You essentially want to avoid making changes to the data until you reach a user-defined commit point. There are techniques you can use in the database layer, like hypothetical views and instead-of triggers to encapsulate the behavior that you aren't actually committing the change. The data is in the DB (in the real tables), but is only visible to the user operating on it. This is probably a more complicated implementation than you may be willing to undertake, and requires intrusive changes to your persistence layer and data model - but allows the application to be ignorant of the issue.
Have you considered storing the information in a JavaScript object and then sending that information to your server once the user hits save?
Use domain events to capture the users actions and then replay those actions over the snapshot of the order model ( effectively the current state of the order before the user started changing it).
Store each change as a series of events e.g. UserChangedShippingAddress, UserAlteredLineItem, UserDeletedLineItem, UserAddedLineItem.
These events can be saved after each postback and only need a link to the related order. Rebuilding the current state of the order is then as simple as replaying the events over the currently stored order objects.
When the user clicks save, you can replay the events and persist the updated order model to the database.
You are using the database - no session or viewstate is required therefore you can significantly reduce page-weight and server memory load at the expense of some page performance ( if you choose to rebuild the model on each postback ).
Maintenance is incredibly simple as due to the ease with which you can implement domain object, automated testing is easily used to ensure the system behaves as you expect it to (while also documenting your intentions for other developers).
Because you are leveraging the database, the solution scales well across multiple web servers.
Using this approach does not require any alterations to your existing domain model, therefore the impact on existing code is minimal. Biggest downside is getting your head around the concept of domain events and how they are used and abused =)
This is effectively the same approach as described by Freddy Rios, with a little more detail about how and some nice keyword for you to search with =)
http://jasondentler.com/blog/2009/11/simple-domain-events/ and http://www.udidahan.com/2009/06/14/domain-events-salvation/ are some good background reading about domain events. You may also want to read up on event sourcing as this is essentially what you would be doing ( snapshot object, record events, replay events, snapshot object again).
how about serializing your Domain object (contents of your grid/shopping cart) to JSON and storing it in a hidden variable ? Scottgu has a nice article on how to serialize objects to JSON. Scalable across a server farm and guess it would not add much payload to your page. May be you can write your own JSON serializer to do a "compact serialization" (you would not need product name,product ID, SKU id, etc, may be you can just "serialize" productID and quantity)
Have you considered using a User Profile? .Net comes with SqlProfileProvider right out of the box. This would allow you to, for each user, grab their profile and save the temporary data as a variable off in the profile. Unfortunately, I think this does require your "Order" to be serializable, but I believe all of the options except Session thus far would require the same.
The advantage of this is it would persist through crashes, sessions, server down time, etc and it's fairly easy to set up. Here's a site that runs through an example. Once you set it up, you may also find it useful for storing other user information such as preferences, favorites, watched items, etc.
You should be able to create a temp file and serialize the object to that, then save only the temp file name to the viewstate. Once they successfully save the record back to the database then you could remove the temp file.
Single server: serialize to the filesystem. This also allows you to let the user resume later.
Multiple server: serialize it but store the serialized value in the db.
This is something that's for that specific user, so when you persist it to the db you don't really need all the relational stuff for it.
Alternatively, if the set of data is v. large and the amount of changes is usually small, you can store the history of changes done by the user instead. With this you can also show the change history + support undo.
2 approaches - create a complex AJAX application that stores everything on the client and only submits the entire package of changes to the server. I did this once a few years ago with moderate success. The applicaiton is not something I would want to maintain though. You have a hard time syncing your client code with your server code and passing fields that are added/deleted/changed is nightmarish.
2nd approach is to store changes in the data base in a temp table or "pending" mode. Advantage is your code is more maintainable. Disadvantage is you have to have a way to clean up abandonded changes due to session timeout, power failures, other crashes. I would take this approach for any new development. You can have separate tables for "pending" and "committed" changes that opens up a whole new level of features you can add. What if? What changed? etc.
I would go for viewstate, regardless of what you've said before. If you only store the stuff you need, like { id: XX, numberOfProducts: 3 }, and ditch every item that is not selected by the user at this point; the viewstate size will hardly be an issue as long as you aren't storing the whole object tree.
When storing attachments, put them in a temporary storing location, and reference the filename in your viewstate. You can have a scheduled task that cleans the temp folder for every file that was last saved over 1 day ago or something.
This is basically the approach we use for storing information when users are adding floorplan information and attachments in our backend.
Are the end-users internal or external clients? If your clients are internal users, it may be worthwhile to look at an alternate set of technologies. Instead of webforms, consider using a platform like Silverlight and implementing a rich GUI there.
You could then store complex business objects within the applet, provide persistant "in progress" edit tracking across multiple sessions via offline storage and easily integrate with back-end services that providing saving / processing of the finalised order. All whilst maintaining access via the web (albeit closing out most *nix clients).
Alternatives include Adobe Flex or AJAX, depending on resources and needs.
How large do you consider large? If you are talking sessions-state (so it doesn't go back/fore to the actual user, like view-state) then state is often a pretty good option. Everything except the in-process state provider uses serialization, but you can influence how it is serialized. For example, I would tend to create a local model that represents just the state I care about (plus any id/rowversion information) for that operation (rather than the full domain entities, which may have extra overhead).
To reduce the serialization overhead further, I would consider using something like protobuf-net; this can be used as the implementation for ISerializable, allowing very light-weight serialized objects (generally much smaller than BinaryFormatter, XmlSerializer, etc), that are cheap to reconstruct at page requests.
When the page is finally saved, I would update my domain entities from the local model and submit the changes.
For info, to use a protobuf-net attributed object with the state serializers (typically BinaryFormatter), you can use:
// a simple, sessions-state friendly light-weight UI model object
[ProtoContract]
public class MyType {
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set;}
[ProtoMember(3)]
public double Value {get;set;}
// etc
void ISerializable.GetObjectData(
SerializationInfo info,StreamingContext context)
{
Serializer.Serialize(info, this);
}
public MyType() {} // default constructor
protected MyType(SerializationInfo info, StreamingContext context)
{
Serializer.Merge(info, this);
}
}

Resources