Global Resource Object in Spring - java

I'm just getting into Spring (and Java), and despite quite a bit of research, I can't seem to even express the terminology for what I'm trying to do. I'll just explain the task, and hopefully someone can point me to the right Spring terms.
I'm writing a Spring-WS application that will act as middleware between two APIs. It receives a SOAP request, does some business logic, calls out to an external XML API, and returns a SOAP response. The external API is weird, though. I have to perform "service discovery" (make some API calls to determine the valid endpoints -- a parameter in the XML request) under a variety of situations (more than X hours since last request, more than Y requests since last discovery, etc.).
My thought was that I could have a class/bean/whatever (not sure of best terminology) that could handle all this service discovery stuff in the background. Then, the request handlers can query this "thing" to get a valid endpoint without needing to perform their own discovery and slow down request processing. (Service discovery only needs to be re-performed rarely, so it would be impactful to do it for every request.)
I thought I had found the answer with singleton beans, but every resource says those shouldn't have state and concurrency will be a problem -- both of which kill the idea.
How can I create an instance of "something" that can:
1) Wake up at a defined interval and run a method (i.e. to check if Service discovery needs to be performed after X hours and if so do it).
2) Provide something like a getter method that can return some strings.
3) Provide a way in #2 to execute a method in the background without delaying return (basically detect that an instance property exceeds a value and execute -- or I suppose, issue a request to execute -- an instance method).
I have experience with multi-threaded programming, and I have no problem using threads and mutexes. I'm just not sure that's the proper way to go in Spring.

Singletons ideally shouldn't have state because of multithreading issues. However, it sounds like what you're describing is essentially a periodic query that returns an object describing the results of the discovery mechanism, and you're implementing a cache. Here's what I'd suggest:
Create an immutable (value) object MyEndpointDiscoveryResults to hold the discovery results (e.g., endpoint address(es) or whatever other information is relevant to the SOAP consumers).
Create a singleton Spring bean MyEndpointDiscoveryService.
On the discovery service, save an AtomicReference<MyEndpointDiscoveryResults> (or even just a plain volatile variable). This will ensure that all threads see updated results, while limiting them to a single, atomically updated field containing an immutable object limits the scope of the concurrency interactions.
Use #Scheduled or another mechanism to run the appropriate discovery protocol. When there's an update, construct the entire result object, then save it into the updated field.

Related

Recommended approach when restoring a Spring State Machine instance

I am planning to use Spring State Machine to control an execution workflow. The system is expected to receive requests from multiple users and each user may be assigned to multiple workflows. My initial idea was to have one instance of SM per workflow and every time an user perform a step in the workflow, I would use its identifier to restore the machine from a persistent storage, input the new event and store the updated SM.
I've read around that initialising a SM is an expensive operation and some people recommend having a single instance of it, but "rehydrate" that instance with some data. My understanding is that this would be more effective, but I think it would become a "blocking" operation, in other words, one workflow would need to wait for the previous one to be finished/released before-hand. Since I'm newbie on this topic, can anyone shed some light on the best alternatives for my use case and perhaps pieces of code to illustrate the differences? (PS: I'm using v2.4.0)
I was first implementing the "rehydrate" mechanism because as you said, it made sense and was also used in the "persist" example of spring-statemachine.
Howewer, running performance tests against my API showed that using a single instance fails when using the StateMachine as an #Autowired Bean with the prototype scope as it is described in that example. What happens is that simultaneous requests against my API override that Statemachine Bean and the first request fails as the statemachine changes when writing back to the DB (i used redis).
So now I actually build a fresh statemachine everytime a request comes in and rehydrate that object:
public String getStatesGuest(HttpServletRequest httpServletRequest) throws Exception {
StateMachine<States, Events> stateMachine = stateMachineConfig.stateMachine();
resetStateMachineFromStore(httpServletRequest.getSession().getId(), stateMachine);
return convertToJson(buildGetStateResponse(stateMachine));
}
It still is very performant, I was testing with around 30 reqs/s and still got a median of 12ms. (Docker with 2 Cores for spring boot, 1 Core for redis).

Need cache per request capability in Java

I am developing REST APIs using Java Spring framework.
When calling these APIs, I have a need to check for permissions, where I will need to make a call to the DB to get the permission data. The thing is, there are multiple areas checking for permission in a single request, and I do not want to make multiple calls to the DB, so I intent to cache the permission data just for that single request.
I have tried creating a request scoped bean, which works, but not for all cases. There are times where the request scoped bean cannot be created, for example when running a scheduled code using #Scheduled annotation, simply because it is not a request. Another case is when checking for permissions using WebSecurityConfigurerAdapter, the bean is also not yet created at that time.
So, I looked into another possible solution, which is this: https://github.com/rinoto/spring-request-cache. If I use this solution, I will need to remove the cache from threadLocal every time an operation is complete. I am not very comfortable of using this solution since I'm not an expert in Java, and I've read that it is not recommended to use threadLocal as cache.
What's the best way to achieve my goal? My ask is simple, cache some data only for that request. Is there any library that supports it?
I find it hard to believe that my ask is not a normal use case, or is it not a normal use case?
You can use ThreadLocal as a cache in this case. No need to clear. As per the documentation
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the {#code ThreadLocal} instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).
eg: ThreadLocal<Map<String, Object>> THREAD_LOCAL_DATA = ThreadLocal.withInitial(HashMap::new)

How to determine whether an EJB call is from a remote or local client

I have an interesting problem.
We have a number of EJB's that are called both by local code (via local interface) and by client code (via remote interface).
The code runs on Weblogic 12c servers and use RMI for method invocations.
The system is in development already for many years, and along others implements browser functionality around user defined cursors (a kind of handle for a result set). There are already many calls to obtain such a cursor for various data types.
When the cursor is obtained it is used subsequently to request the underlying data (another call).
In our case we want to know whether the call is done from local code or from a remote client. We want to know this so we can preload the first n items, and thus reduce the number of calls to our server. Each call has an overhead of about 20ms, which we want to avoid.
The remote client code is generic (the cursor is wrapped in a kind of list) and could easily be adjusted to handle the preloaded data.
The local callers also call these EJB methods to obtain a cursor, but usually use other functionality to handle the cursor (wrapping in iterators, joins, etc). So they would become a lot more complex if they had to handle the preloading (and they often do not need it).
So we want to make an interceptor to do preloading of data in the cursor, but only if the call is made from a remote client. So far we could not find a way of doing so.
I tried RemoteServer.getClientHost() but it always throws the exception there is no connection.
I searched if the SessionContext could be extended with a field/value to be set by the caller to identify the remote client, but could find anything about doing this. (We have a homemade wrapper for the service interface which could be extended of inserting such information in a context).
So the question is:
Is there a generic way to find out in an EJB interceptor that the origin of the call was from a different system
If the remote client uses any kind of authentication there should be some info in the security context about the principal which can be used to differentiate. Otherwise, before finding a better solution new Throwable().getStackTrace() returns an array of all callers. There must be a method upstream that could tell if the call is local or it's been done via remote call.

Strategies for exposing user identification from a REST endpoint back to the data-access/repository layer

The background: there is a requirement to attach auditing data to persisted entities, basically creation-timestamp + user ID and last-update-timestamp + user ID.
I'm not keen on passing the user ID as a method parameter through all layers/components. So I need to somehow pass user identifcation (derived from HTTP headers, the details are unimportant) through a REST endpoint (using RESTEasy, but that's probably not important, either) back to the data access/repository layer.
I've thought of using ThreadLocal but it feels a little hackish and might fail in a non-blocking IO environment. Maybe I'm wrong about that, not sure.
I also have a vague idea that AOP could help, though I'm not well-versed in AOP so not sure.
Any strategies appreciated, with or without code.
You can use entity lifecycle callback methods for your requirement: #PrePersist, #PostPersist, #PreUpdate, #PostUpdate.
It is one of the auditing strategies mentioned here.
It turns out that Spring's SecurityContextHolder is a reasonable place to do this (don't ask why the application isn't already integrating "properly" with Spring Security). It's basically the ThreadLocal option but with some nice interface around it.
The tradeoff is that you need to be acutely aware of the thread-bound nature of this solution. A controller that somehow uses other thread to do the work that needs the user context, will need to take some steps to make sure those threads can get it since they don't, by default, inherit the ThreadLocal. There is a mode you can set on SecurityContextHolder that will use inheritance of the ThreadLocal in any newly created threads, but that does not help if a thread pool is used (since threads won't be created by the request thread but rather pulled from the pool). Even then, most thread pools provide a way for the client thread to do "something" when obtaining and releasing threads, so it's possible to pass the security context on that way.

Proxy Design Pattern : Disadvantages

I was going through one of the Articles on Proxy pattern.
Read the Comments After the Explanation
In this article there are few downsides mentioned for Proxy Patterns, but I am not able to understand:
1) The downside here is 'magic' could be happening that an extender is unaware of (a 'black-box' problem). Please explain the magic.
2) A proxy can mask the life-cycle and state of a volatile resource from its client. A client may call the proxy not realizing that the resource is currently unavailable... in this case the proxy has to either block until a resource is available again, or it must produce some kind of error. In Java terms it would have to be an unchecked exception, since the Proxy must comply with the interface of the original object. Also the client may not be aware that the resource it is calling now is not the same resource it called a second ago; if there is any state on the resource then the client may be confused that the state appears to have been forgotten.
Please explain.
3) if a proxy is used to represent a remote resource in the local process, this can disguise the fact that remote communication is involved. As we know, remote invocation is completely different from local invocation, and our programs should not treat it as if it were the same. It is better if the proxy declares somehow that it is a proxy for a remote resource, rather than a local resource. Then clients would have be able to choose only local resources, or to modify their behavior when using a remote resource.
Would you please help me in understanding three point above related to the downsides of Proxy?
That makes 3 different questions. I'll answer the third one. You'd better edit your question to a single one, and ask each of the two others in a separate question.
When dealing with communication with a remote server, the proxy pattern is often used (by RMI, for example). You get a reference to an object from some factory, and what you get is in fact a stub (a proxy) which, for every method you call, serilaizes the arguments of the method, sends them to a server, waits for the response, and returns the result.
The proxy makes that almost transparent, but not being aware that all this happens behind the scenes can make you code things very inefficiently.
Take this example for example:
if (account.getBalance() > 0 && account.getBalance() < MAX) {
transferAmount(account.getBalance() / 2);
}
Now imagine that account is a proxy to a remote object. Each time getBalance() is called, a remote network call is made, which can potentially lead to an exception, or even return a different value each time, making this simple code snippet extremely inefficient.

Categories

Resources