Integrating a RxJava in springboot application using Observable we are able to get the data from the service. But I have a doubt in using toBlocking() method, because I've read many forum postings saying it has issues in production server. See my below code,
Sample Code with toBlocking():
userService.getUsers()
.subscribeOn(Schedulers.io())
.toBlocking()
.single();
I want to change the above to get the user object instead of Observable object.
For example:
User user = new User();
userService.getUsers().subscribe(u ->user = u );
Here a variable user is declared globally in the class it work fine, but inside method it shows an error.
You probably want something like blockingFirst:
final User user = userService
.getUsers()
.blockingFirst()
I'd encourage you to think about if this is the right thing to do, though (do you really need to block and jump out of the reactive world for this use case?. As #akarnokd said, read Getting Started)
Related
I am trying to get a specific Member object from a Guild by using the following:
event.getGuild().getMember(user)
Here, user is the User object of the user I want to get the Member object from. I have also tried using the .getMemberById, using the userID instead. However, in both cases I get a null-pointer exception.
I am sure that both my User object and userID are correct, because when adding a breakpoint it does show these, but it doesn't retrieve the Member, this stays null. Am I approaching this wrong?
I have also tried putting the following in my main file where I start the bot:
JDABuilder builder = JDABuilder.createDefault(BOT_TOKEN);
builder.enableIntents(GatewayIntent.GUILD_MEMBERS);
On the Discord developer portal I have enabled both the 'Privileged Gateway Intents' options.
The documentation of Guild#getMember tells you to see also Guild#retrieveMember which can be used to load members that are not cached.
If you have an event with a getMember() or retrieveMember() method, that should be used instead. Otherwise you can do this:
guild.retrieveMember(user).queue(member -> {
... use member here
});
Other alternatives are outlined in the JDA wiki here: Gateway Intents and Member Cache Policy
Most of these retrieval methods DO NOT require the privileged intent GUILD_MEMBERS. It is only required if you want to interact with the entire member list of a server, through methods like loadMembers or findMembers for example.
Please bear with me, i dont usually use spring and havent used newer versions of java (I say newer I mean anything past prob 1.4)
Anyway, I have an issue where I have to do rest calls to do a search using multiple parallel requests. Ive been looking around online and I see you can use CompletableFuture.
So I created my method to get the objects I need form the rest call like:
#Async
public CompletableFuture<QueryObject[]> queryObjects(String url)
{
QueryObject[] objects= restTemplate.getForObject(url, QueryObject[].class);
return CompletableFuture.completedFuture(objects);
}
Now I need to call that with something like:
CompletableFuture<QueryObject> page1 = QueryController.queryObjects("http://myrest.com/ids=[abc, def, ghi]);
CompletableFuture<QueryObject> page2 = QueryController.queryObjects("http://myrest.com/ids=[jkl, mno, pqr]);
The problem I have is that the call needs to only do three ids at a time and there could be a list of variable number ids. So I parse the idlist and create a query string like above. The problem with that I am having is that while I can call the queries I dont have separate objects that I can then call CompletableFuture.allOf on.
Can anyone tell me the way to do this? Ive been at it for a while now and Im not getting any further than where I am now.
Happy to provide more info if the above isnt sufficient
You are not getting any benefit of using the CompletableFuture in a way you're using it right now.
The restTemplate method you're using is a synchronous method, so it has to finish and return a result, before proceeding. Because of that wrapping the final result in a CompletableFuture doesn't cause it to be executed asynchronously (neither in parallel). You just wrap a response, that you have already retrieved.
If you want to benefit from the async execution, then you can use for example the AsyncRestTemplate or the WebClient .
A simplified code example:
public ListenableFuture<ResponseEntity<QueryObject[]>> queryForObjects(String url) {
return asyncRestTemplate.getForEntity(url, QueryObject[].class);
}
public List<QueryObject> queryForList(String[] elements) {
return Arrays.stream(elements)
.map(element -> queryForObjects("http://myrest.com/ids=[" + element + "]"))
.map(future -> future.completable().join())
.filter(Objects::nonNull)
.map(HttpEntity::getBody)
.flatMap(Arrays::stream)
.collect(Collectors.toList());
}
In my project, I want method A,B use database1, and all other methods use database2.
Now I write like this in controller
DataSourceHolder.putDataSource("db1");
String code = methodA();//for get some
DataSourceHolder.putDataSource("db2");
methodC(code);
...
DataSourceHolder.putDataSource("db1");
methodB(code);//for set some
DataSourceHolder.putDataSource("db2");
In most cases, it runs normally. But while many people visit my webset, it may use wrong dataSource. Some data can not be saved or updated.
I'm new to scala, but have some experience using the play framework in Java. I've added the SecureSocial authentication library, which defines a SecuredACtion, and it seems to be working correctly. However, I'm having trouble understanding the expected content within the custom action in scala code.
Here's my controllers class. Ideally, "index" would simply redirect the authenticated request to "unprotectedIndex" somehow, but that doesn't seem to be possible. So if not, next best thing is simply to serve the file directly from inside of the secured action, but that's also not working.
What is missing from my code?
object Application extends Controller with securesocial.core.SecureSocial {
// this doesn't compile, but it's a long scala exception that I don't know how to fix.
def index = SecuredAction { implicit request =>
Assets.at("/public", "index.html").apply(request)
}
def unprotectedIndex = Assets.at("/public", "index.html")
}
It seems like it's expecting a SimpleResult but getting a Future[SimpleResult] - this feels like it shouldn't be complicated, but what am I missing?
It seems like you are using play framework 2.2. There were some changes and most methods return Future[SimpleResult] instead of just Result or SimpleResult. You can check if you are able to do like this: def index = SecuredAction.async {...} (but I'm almost sure you can't).
You can use this approach to make it work correctly:
import scala.concurrent.Await
import scala.concurrent.duration._
def index = SecuredAction { implicit request =>
Await.result(Assets.at("/public", "index.html").apply(request), 5 seconds) //you can specify you maximum wait time here
}
EDIT
Even one more thing to simplify:
Await.result(unprotectedIndex(request), 5 seconds)
So you can call your unprotectedIndex from your index Action
So, just by looking at syntax highlighting in my IDE I have been able to get something that seems to compile and work but looks deeply wrong to me.
I changed it to this:
def index = SecuredAction { implicit request =>
Assets.at("/public", "index.html").apply(request).value.get.get
}
Is that the correct way to do this? It looks really weird to me, am I just not familiar with the idioms?
I have been wrestling with this problem for a while. I would like to use the same Stripes ActionBean for show and update actions. However, I have not been able to figure out how to do this in a clean way that allows reliable binding, validation, and verification of object ownership by the current user.
For example, lets say our action bean takes a postingId. The posting belongs to a user, which is logged in. We might have something like this:
#UrlBinding("/posting/{postingId}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
Now, for the show action, we could define:
private int postingId; // assume the parameter in #UrlBinding above was renamed
private Posting posting;
And now use #After(stages = LifecycleStage.BindingAndValidation) to fetch the Posting. Our #After function can verify that the currently logged in user owns the posting. We must use #After, not #Before, because the postingId won't have been bound to the parameter before hand.
However, for an update function, you want to bind the Posting object to the Posting variable using #Before, not #After, so that the returned form entries get applied on top of the existing Posting object, instead of onto an empty stub.
A custom TypeConverter<T> would work well here, but because the session isn't available from the TypeConverter interface, its difficult to validate ownership of the object during binding.
The only solution I can see is to use two separate action beans, one for show, and one for update. If you do this however, the <stripes:form> tag and its downstream tags won't correctly populate the values of the form, because the beanclass or action tags must map back to the same ActionBean.
As far as I can see, the Stripes model only holds together when manipulating simple (none POJO) parameters. In any other case, you seem to run into a catch-22 of binding your object from your data store and overwriting it with updates sent from the client.
I've got to be missing something. What is the best practice from experienced Stripes users?
In my opinion, authorisation is orthogonal to object hydration. By this, I mean that you should separate the concerns of object hydration (in this case, using a postingId and turning it into a Posting) away from determining whether a user has authorisation to perform operations on that object (like show, update, delete, etc.,).
For object hydration, I use a TypeConverter<T>, and I hydrate the object without regard to the session user. Then inside my ActionBean I have a guard around the setter, thus...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}
where accessible(posting) looks something like this...
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}
Then your show() event method would look like this...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}
Separately, when I use Stripes I often have multiple events (like "show", or "update") within the same Stripes ActionBean. For me it makes sense to group operations (verbs) around a related noun.
Using clean URLs, your ActionBean annotations would look like this...
#UrlBinding("/posting/{$event}/{posting}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
...where {$event} is the name of your event method (i.e. "show" or "update"). Note that I am using {posting}, and not {postingId}.
For completeness, here is what your update() event method might look like...
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}