How to implement transaction in Spring Integration Mail Adapter for pop3 - java

We have been trying to implement transaction in Pop3 and came across the documentation of Transaction Synchronization in release 4.2.0.RELEASE
http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/mail.html#mail-tx-sync
But they are iterating through the folder mails to delete a particular message before committing the transaction.Is there any implicit way to delete the mails by id or does Spring Integration provide any sync factory to handle the email transaction internally.

Email is not transactional; the cited documentation shows the ability to synchronize some action when a transaction commits. But the action taken on a non-transactional resource is not really transactional.
Since the framework can't anticipate what a user might want to do, it provides nothing other than the hooks to enable such user actions.
The documentation simply shows one such action that might be taken another action might be to move the email to another folder (when using IMAP).

Related

Spring session lazy deserialization

I have the following situation, i have a microservice architecture with an api gateway and multiple downstream services, some of these have an independent session and this causes my system to throw expired session exception on random service calls.
Since we cannot rewrite these services from scratch we started by introducing hazelcast so that all services can share the same session.
the problem now is that when a service writes an object of a class that other services don't have in their classpath a deserialization exception is thrown.
to solve this i was thinking that if only the attributes that get accessed from a service get deserialized i could probably avoid the exception and everything should work fine.
Do you know if this is at all possible with spring session, or maybe can suggest another solution that would allow me solve the initial problem?
here is a sample project to reproduce my problem: https://github.com/deathcoder/hazelcast-shared-session
I believe I got what's happening: Spring-Session-Hazelcast by default store session updates locally until request completed & when request completed, before returning the response, send everything to the cluster using EntryProcessor. EntryProcessor requires object classes available on the member who stores that session record and since data is distributed, it's possible some other member stores a session created in another instance. According to what you're saying, not all nodes are identical, don't contain all classes & this causes serialization exception.
What you can do, you can use User Code Deployment feature to deploy those missing classes to other members: https://docs.hazelcast.org/docs/3.11/manual/html-single/index.html#member-user-code-deployment-beta
If you're changing object that you're storing in the session, you can set class-cache-mode to OFF to prevent not caching them but sending with each operation.
Please try & let me know if this solves your problem.
I would try to avoid sessions in the API layer in the first place. They scale poorly. And synchronizing sessions is even less scalable.
Try using access tokens instead, for example a JWT token. A token should contain enough user identity information to load the resources necessary to process the transaction (the resources can be cached).
As for the other state in the session - microservices are self-contained from the process perspective, so all intermediate results should be persisted to the database. But of course I don't know the details of your particular application, so this is just a general thought.

How to avoid concurrent access to payment link in my website

I am using mysql InnoDB and struts2 for developing my website. When a user want to use a product, he will be send an invoice to his inbox and with that link he can pay the money.
The problem I have to solve is: when a user opens the link in two sessions and tries to pay for both, I have to allow only one transaction. And if allowed transaction gets a problem like browser closure or some other issue, things will go into deadlock condition. I have to avoid this and allow the next transactions.
Please suggest me how to achieve this?
I think you will have to add a life time for each session to prevent deadlocks (just like in the one being used by bank's sites) and you can do that using unique sessionids. All the sessions have fix life time. Once the time is over the session is expired.
In that case if one session is active you can deny all the attempts to that session. If browser closes in between the session, session will automatically expire after its life time. Now if the payment was not done due to any reason i.e. session expire or browser closed, User can simply re-click on the link and restart the process.
Hope it helps,

Force OSGi service be reloaded

Assume I have 2 OSGi services. One of them is memory cache of DB records. Another service is set of CRUD operations on these DB records. During modification I would like to rebuild existing cache. How one service can force another be MODIFIED? Something like to send org.osgi.framework.ServiceEvent.MODIFIED event.
(please note that it is simplified example of real business case and I don't really place cache as a service)
UPDATE to make question more clear - I need exactly same function as ServiceRegistration#setProperties provides. Unfortunately ServiceRegistration should not leave bound of Bundle.
Why do you want to solve this using services?
Simply send an event using EventAdmin from the CRUD bundle that says that data is modified. So the cache can listen to these events and act accordingly. The advantage of the eventing solution is that the crud service does not really have to know there is a cache it just sends the event to whoever is interested.
Please, please don't try to do this.
Only the provider bundle for the service knows what implementation is behind it... that is why only the provider has access to the registration details.
The cache provider should detect for itself whether the underlying data has changed, and refresh the cache appropriately. No other bundle(s) can do this because they have no idea where the cache provider gets its data, they can only see the public service interface.

Is there a way to explicitly commit and rollback transaction after several client&server submit

Environment: The application is using Spring Framework 2.5.6.SEC01 and iBatis 2.3.4.726. It is MVC design.
Here's the scenario:
Input/update data from the client
Press Update button to submit
Process the data and execute DML (insert, update, delete)
Back the result to client and display the data
However, upon the page loaded, I need to call the API via Javascript (i have no control with the API, just need to pass the required parameter and check the result if SUCCESS or ERROR)
If API returns SUCCESS, nothing to do. But it returns ERROR, I give alert message to inform the user.
I have View(client), Service and Data Access Layers. When the client do the submit (scenario #2), it enters the Service to process the data and automatically start Transaction (scenario #3). Automatically execute the commit upon exit to Service and back to client to show the data (scenario #4).
Problem: How can I suspend the transaction not to execute the commit, then back to client to call API via Javascript. When API returns SUCCESS, execute commit via Ajax (or other way) or in the other hand, rollback it.
Any guidance on the right direction is appreciated.
If I understand correctly, you want to start a database transaction, insert data (without comitting), keeping the connection and the transaction open, return to the client, and based on some javascript result, do a commit.
This feels like a strange design where the client can actually keep a connection open, making your application extremely vulnerable for (D)DOS attacks or client problems in general.
I would try really hard to remodel it as follows:
Upon submit, call the javascript you need to confirm the commit/save action
When the javascript succeeds, do the submit to your own server
Do normal Connection/Transaction handling within the DAO, not exposing transactions to the client.
This is quicker, more robust and also probably less code.

How do I get user information within a stateless session bean

I'm working on an existing j2ee app and am required to remove some vendor specific method calls from the code.
The daos behind a session facade make calls into the ejb container to get the user's id and password - in order to connect to the database. The user id and password part of the initialContext used to connect to the server.
I am able to get the userid using sessionContext.getCallerPrincipal()
Is there anyway to get to the SECURITY_CREDENTIALS used on the server connection or, is there a way to pass information from the server connection into the ejbs (they are all stateless session beans).
This is a large app with both a rich-client and web front end, and in a perfect world I'd be happy to go back and re-architect the entire solution to use J2EE security etc - but unfortunately, that is not realistic.
I can't give you a generic solution, but this is what has worked for us. We have the app server connect to LDAP as a specific user that has the ability to request credentials for other users. Then we have some generic security code that we can use to request a users credentials from inside the session beans, based on the users identity from their initial login (just as you are doing it via getCallerPrincipal()).
We also place the users identity in a thread local variable, so that classes down the call chain from the EJB do not have to be "container aware". They simply access the identity from the thread local and use the security classes to look up user profile information. This also makes it easy to change the implementation for testing, or even something other than LDAP lookups.
Other conveniences we created were a JDBCServiceLocator that retrieves connections with user/password for the current user. So the developer does not have to explicitly code the security lookups at all.
Normally the Java EE security model will not allow the retrieval of the user password, for security reasons. But it depends on the implementation. Some vendors provide methods to retrieve this kind of information, but if you rely on such implementations, be aware that the portability of the application will be compromised.
One common approach is to write a servlet filter to intercept the login request and save a copy of the credentials, to be used later. If your application doesn't use the Java EE security infrastructure, this could be easily implemented. That's because some vendors prevent you from filtering an authentication servlet.
Robin,
Sounds like what I was planning. I figured I'd make a call right after a successful server connection to load the credentials into a threadLocal variable on my connection class. I was hoping there was an easier way - but I guess not.

Categories

Resources