Send updates or progress in Spring Controller before response - spring

I have a form that allows users to upload CSV files which subsequently uses Superagent to make a POST call to a controller in the backend which parses through the file and executes batch inserts into our tables. I would like to implement a progress bar on the front-end side that listens for updates from the controller to show the progress of the parsing/inserts. On the front end I'm using React and currently making the call like this:
request.post('/api/uploadFile')
.send(csvFile)
.on('progress', function(e) {
console.log('Percentage done: ', e.percent);
})
.end((err, resp) => {
if (err) {
$("#loading").hide();
console.log("Error in file upload");
console.error(err);
alert("Failed to upload. " + err + "\n (" + err.status + ") " + resp.text);
}
else {
$("#loading").hide();
console.log(resp);
alert("Success. " + resp.text);
return resp;
}
});
}
The progress event listener automatically shows 100% as soon as I send the file, which is incorrect (the sending appears to be instant but it doesn't actually know how much is reached from the other end until there's a response). On the backend I have a controller like this:
#RequestMapping(value="/api/uploadFile", method=RequestMethod.POST)
public #ResponseBody ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file){
if (!checkCSV(file)) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body("Not CSV");
}
if (file.isEmpty()) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body("File is empty");
}
MySQLAccess db = new MySQLAccess();
File fileToParse = convertToFile(file);
/* Call helper function that parse CSV file & execute batch inserts & creates join tables */
return ResponseEntity.ok("File was uploaded.");
}
I would like to interleave progress status (which I can set) in my controller that would update the frontend regarding which step the file upload is at: the parsing/batch inserts/table creations, etc. I would like to do this because my app is currently deployed on Heroku and I keep hitting request timeouts because the file upload process takes around 1 minute, which is over the 30 second window Heroku sets for H12 request timeouts if it doesn't receive a single byte back to the client (I'm assuming if I'm sending back updates it might prevent these timeouts?). Does anyone have any suggestions on how to send updates from my controller to update the progress before the response is sent back?

Related

Make JDA Discord Bot send a random image

I'm currently working on a bot for my Discord server and I was wondering how to implement various image commands (for example, !cat, !meme) to make the bot send a random image each time the command is called.
Almost every bot I've seen has a feature like that but for some reason I can't seem to find a working way to do this in JDA. And any JDA example I found was either outdated or it simply didn't work, so I really hope someone can give me a hand here.
Here's a (very basic) example I already did, but the problem is that the pictures don't randomize with each call and just stay the same until I restart discord
public void sendCatImage() {
EmbedBuilder result= new EmbedBuilder();
result.setTitle("Here's a cat!");
result.setImage("http://thecatapi.com/api/images/get?format=src&type=png");
event.getChannel().sendMessage(result.build()).queue();
}
I'm using JDA Version 4.1.0_100, if it helps
Any help will be greatly appreciated!
Discord will cache the image based on the URL. You can append a random number as a query to prevent this:
public String randomize(String url) {
ThreadLocalRandom random = ThreadLocalRandom.current();
return url + "&" + random.nextInt() + "=" + random.nextInt();
}
...
result.setImage(randomize(url));
...
Furthermore, you can avoid discord updating the image by also uploading it alongside the embed. For that you first need to download the image and then upload it:
// Use same HTTP client that jda uses
OkHttpClient http = jda.getHttpClient();
// Make an HTTP request to download the image
Request request = new Request.Builder().url(imageUrl).build();
Response response = http.newCall(request).execute();
try {
InputStream body = response.body().byteStream();
result.setImage("attachment://image.png"); // Use same file name from attachment
channel.sendMessage(result.build())
.addFile(body, "image.png") // Specify file name as "image.png" for embed (this must be the same, its a reference which attachment belongs to which image in the embed)
.queue(m -> response.close(), error -> { // Send message and close response when done
response.close();
RestAction.getDefaultFailure().accept(error);
});
} catch (Throwable ex) {
// Something happened, close response just in case
response.close();
// Rethrow the throwable
if (ex instanceof Error) throw (Error) ex;
else throw (RuntimeException) ex;
}

How can I access data sent via AJAX on Node JS server?

I would like to make a simple contact form for my website. I know how to use ajax to send data, but I don't know how to access it on the Node JS server.
If I were to send my data using this code:
var request=new XMLHttpRequest();
request.open("POST","url");
request.send("{value:'10'}");
How can I access my value in the JSON object I pass to the server?
There are a lot of ways to do this.
For example you could create an endpoint on your server e.g. with express http://expressjs.com/. It might look like this
router.post('/your/url', function(req, res, data) {
var value = req.body.value;
// do cool things with value
res.send('cool');
});
You define a post endpoint which will handle your request. Using the request object you can access the JSON object from the request
I used request_.on("data", function(data_){}); to get my data.
If in my client JS I use request.send("my data");
I can access my data by adding a listener to the request_ object in my Node JS server function.
request_.on("data", function(data_){
console.log(data_);// my data
}
I can then slice up my data any way I want to and use it how I see fit. No need for Express.
Here's my client function that is called when the submit button on my contact form is pressed:
function clickSubmit(event_) {
var xmlhttprequest = new XMLHttpRequest();
xmlhttprequest.open("POST", "contact");
xmlhttprequest.send("email=" + html.email.value + "&name=" + html.name.value + "&message=" + html.message.value);
}
And here's my Node JS server function:
function handleRequest(request_, response_) {
switch(request_.url) {
case "/contact":
request_.on("data", function(data_) {
console.log("data: " + data_);// Outputs the string sent by AJAX.
});
break;
}
}

email read from EWS (exchange web service) server cannot process this request error c#

I have a task where i need to check the emails delivered to my mailbox and read them ,based on subject i have to do some task. But for demo purpose I have put only the basic functionality of just updating the email read status
The basic connection and creating service object everything is fine:
///////////
NetworkCredential credentials = new NetworkCredential(securelyStoredEmail, securelyStoredPassword);
ExchangeService _service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
_service.Credentials = credentials;
_service.AutodiscoverUrl("User1#contoso.com");
/////////////////////////
Here Everything works fine. However I will invoke the below method for every 60s using observable event of reactive linq. THis is to go and poll the my emailbox and read 100 emails for every 60 seconds.
Everything works fine till sometime. Sometimes when the control reaches the line of code inside parallel.foreach loop, it shows error message like 'server cannot process this request now. Please try later' something like this. THis error comes exactly at the line
var email = EmailMessage.Bind(_service, findItemsResult.Id, emailProps);
so for every 60 seconds, i will get this error sometimes.sometimes it works fine.
Below is the method which is executed for every 60seconds. Its like i try to read the emails from "myaccount.com" for every 60s and i vil get the error 'server cannot process'.
internal void GetEmailsFrommymailbox()
{
try
{
var view = new ItemView(100);
var userMailbox = new Mailbox(userMailbox);
var folderId = new FolderId(WellKnownFolderName.Inbox, userMailbox);
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
var findResults = _service.FindItems(folderId, sf, view);
var emailProps = new PropertySet(ItemSchema.MimeContent, ItemSchema.Body,
ItemSchema.InternetMessageHeaders);
Parallel.ForEach(findResults, findItemsResult =>
{
///////////// this is the line where i get error////////
var email = EmailMessage.Bind(_service, findItemsResult.Id, emailProps);
//// above is the place where i get error
var emailMatching = email;
try
{
email.IsRead = true;
email.Update(ConflictResolutionMode.AutoResolve);
}
catch (Exception emailreadFromBccException)
{
Logger.Warn(emailreadFromBccException + " Unable to update email read status");
}
});
}
}
Your getting that error because you being throttled https://msdn.microsoft.com/en-us/library/office/jj945066%28v=exchg.150%29.aspx and your being throttled because you code isn't very efficient.
Instead of doing
Parallel.ForEach(findResults, findItemsResult =>
{
///////////// this is the line where i get error////////
var email = EmailMessage.Bind(_service, findItemsResult.Id, emailProps);
You should use LoadPropertiesFromItems http://blogs.msdn.com/b/exchangedev/archive/2010/03/16/loading-properties-for-multiple-items-with-one-call-to-exchange-web-services.aspx . Which will reduce the number of call you need to make to the server.
I would also suggest you use Streaming notification https://msdn.microsoft.com/en-us/library/office/hh312849%28v=exchg.140%29.aspx?f=255&MSPPError=-2147217396 which will mean you won't need to poll the server every 60 seconds and just take an action when a new item arrives.
Cheers
Glen

spring websocket notification

Ok here i'm , i'm right now following the guides on spring site but i'm having problem on how to deliver a notification to only one user using WebSocket, i'm following this guide https://spring.io/guides/gs/messaging-stomp-websocket/ .
What I want is: i have 2 users, both of them subscribe to process1... User1 need to let the server process his pass...now i want that the server will deliver the notification only to User1...
#Controller
public class ProcessController {
#MessageMapping("/ProcessOwner/approve/{pass}")
#SendTo("")
public String notifica(#DestinationVariable String pass)throws Exception{
return "ok"+pass;
}
}
Now what should i write in the #SendTo field to deliver the answer only to user1 ? if ill write /Process/process1 both user1 and user2 will receive the message....
You ca use the sufix. It's send to every unique client.
When you subscribe in the js code:
client.connect('guest', 'guest', function(frame) {
var suffix = frame.headers['queue-suffix'];
client.subscribe("/queue/error" + suffix, function(msg) {
// handle error
});
client.subscribe("/queue/position-updates" + suffix, function(msg) {
// handle position update
});
});
On the server side you can use #ReplyToUser or the message template
String user = "fabrice";
String queue = "/queue/position-updates";
this.messagingTemplate.convertAndSendToUser(user, queue, position);
See more here: http://assets.spring.io/wp/WebSocketBlogPost.html (section: Sending Messages To a Single User)

How to load image list from REST API using angularJS

I have searched in this forum for quiet a bit and here's my problem -
I have a ng-repeat in my html which takes in a list of messages(Json object).
Each message JSON has a sender email address - e.g. abc#gmail.com
Now, I have to get the email address from the message and form another REST API request to fetch their images for e.g. - http://<>:8080/getImage/abc#gmail.com (email address dynamic)
So in my code, I'll have a ng-repeat and a ng-src pointing to the image REST URL
If there's no image in server, it returns a 404 and displays a broken image on the UI. How do I handle it? On the other hand, if I make a http request to determine if there's a success message and on failure return a default image, then the whole thing goes through an endless loop. I'll try to create a fiddle and include it for better explanation.
Use the error block to handle such behavior:
function($http) {
var restUrl = 'getImage/abc';
return {
fetchImage: function(imageId) {
var self = this;
return $http.get(restUrl + '/' + imageId).
success(function(data) {
return self.imageUrl = data;
}).
error(function(data) {
return self.imageUrl = "pathToDefaultImage";
});
},
...

Resources