My team and I coded a mail component to be used by other teams in our application. This component is designed to allow them to download emails using custom search conditions. The one that is being used at the moment is a mail search between a range of dates from Gmail accounts using IMAP protocol. It was working properly until April 4th 2016 6:00AM GMT+1, only downloading email within the range. However, since 8:00AM GMT+1, the response from the server suddenly changed and it started returning the whole INBOX folder!
Repeating the initial tests, we discovered that we were receiving the whole INBOX folder instead of those within the range. After some research down to the IMAP request, it seemed that Gmail changed the amount of emails returned under certain conditions:
When the "start date" SearchTerm had a ComparisonTerm.GT term, or
When the "end date" SearchTerm had a ComparisonTerm.LE term
In both cases, Gmail's IMAP server returns all the emails in the folder. On the contrary, as an example, Yahoo's IMAP server just returns those emails which match the given condition.
We opened a ticket to them, asking if there was any change in their response, but they answered that they did not change anything. Of course, there is no way to prove it (we still don't have the time machine).
As we had a great impact with this unexpected behaviour, we decided to investigate further, and we created a simple mail client to download mail using different condition combinations from different IMAP servers.
Starting from this link's program, we added the functionality to check with other, but changing the library to meet our javax.mail version 1.5.5. Therefore, we avoid different implementation behaviours.
The code is attached below:
package gmail;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.AndTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.SearchTerm;
public class JavaMailTest {
public static void main(String[] args) {
JavaMailTest testClient=new JavaMailTest();
//Yahoo
//SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GE,ComparisonTerm.LT);
//Gmail
//SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GE,ComparisonTerm.LT);
//Yahoo
//SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GE,ComparisonTerm.LE);
//Gmail
//SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GE,ComparisonTerm.LE);
//Yahoo
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GT,ComparisonTerm.LT);
//Gmail
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GT,ComparisonTerm.LT);
//Yahoo
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
testClient.performTest(testClient.getYahooImapProps(),ComparisonTerm.GT,ComparisonTerm.LE);
//Gmail
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
testClient.performTest(testClient.getGmailImapProps(),ComparisonTerm.GT,ComparisonTerm.LE);
}
public int performTest(Properties props, int startTermCondition, int endTermCondition)
{
try {
Session session = Session.getDefaultInstance(props, null);
Message[] totalMessages = null;
Store store = session.getStore(props.getProperty("protocol"));
store.connect(props.getProperty("mail.imap.host"), props.getProperty("account"), props.getProperty("pass"));
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_ONLY);
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd");
Date startDate = ft.parse("2016-04-03");
Date endDate = ft.parse("2016-04-07");
System.out.println("Testing email account: <"+props.getProperty("account")+"> with startDate: <" + startDate + "> (ComparisonTerm."+
getConditionText(startTermCondition)+") and endDate: <" + endDate+"> (ComparisonTerm."+getConditionText(endTermCondition)+")");
Message[] messages = inbox.getMessages();
if (messages != null && messages.length > 0) {
SearchTerm startDateTearm =
new ReceivedDateTerm(startTermCondition, startDate);
SearchTerm endDateTerm =
new ReceivedDateTerm(endTermCondition, endDate);
SearchTerm andTerm = new AndTerm(startDateTearm, endDateTerm);
totalMessages = inbox.search(andTerm);
if(totalMessages.length > 0){
System.out.println("Found "+totalMessages.length+" matching messages (Total messages in folder: "+messages.length+")");
}
/*for (int i = 0; i < totalMessages.length; i++) {
System.out.println(totalMessages[i].getReceivedDate() + " --> Mail Subject:- " + totalMessages[i].getSubject());
}*/
//First message
int currentMessage=0;
System.out.println("First Message: "+totalMessages[currentMessage].getReceivedDate() + " --> Mail Subject: " + totalMessages[currentMessage].getSubject().substring(0, 5));
//Last message
currentMessage=totalMessages.length-1;
System.out.println("Last Message: "+totalMessages[currentMessage].getReceivedDate() + " --> Mail Subject: " + totalMessages[currentMessage].getSubject().substring(0, 5));
}
inbox.close(true);
store.close();
return totalMessages.length;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public static String getConditionText(int condition)
{
String returnValue="";
switch (condition) {
case ComparisonTerm.EQ:
returnValue="EQ";
break;
case ComparisonTerm.GE:
returnValue="GE";
break;
case ComparisonTerm.GT:
returnValue="GT";
break;
case ComparisonTerm.LE:
returnValue="LE";
break;
case ComparisonTerm.LT:
returnValue="LT";
break;
case ComparisonTerm.NE:
returnValue="NE";
break;
default:
returnValue="Error";
break;
}
return returnValue;
}
public Properties getYahooImapProps()
{
Properties props = new Properties();
//Yahoo
String imapServer="imap.mail.yahoo.com";
String imapPort="993";
String account="********#yahoo.es";
String pass="*********";
props.setProperty("mail.imap.host", imapServer);
props.setProperty("mail.imap.port", imapPort);
props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imap.auth", "true");
props.setProperty("account", account);
props.setProperty("pass", pass);
props.setProperty("protocol", "imaps");
return props;
}
public Properties getGmailImapProps()
{
Properties props = new Properties();
//Gmail
String imapServer="imap.gmail.com";
String imapPort="143";
String account="******#gmail.com";
String pass="********";
props.setProperty("mail.imap.host", imapServer);
props.setProperty("mail.imap.port", imapPort);
/*props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imap.auth", "true");*/
props.setProperty("account", account);
props.setProperty("pass", pass);
props.setProperty("protocol", "imap");
return props;
}
}
To make the program output clearer, I added the request right before the first method output:
//SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
Testing email account: <*********#yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT)
Found 5 matching messages (Total messages in folder: 78)
First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso
Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter
//SEARCH SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
Testing email account: <*********#gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT)
Found 92 matching messages (Total messages in folder: 20138)
First Message: Sun Apr 03 04:08:47 CEST 2016 --> Mail Subject: Tu es
Last Message: Wed Apr 06 22:12:45 CEST 2016 --> Mail Subject: ¿Quie
//SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
Testing email account: <*********#yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE)
Found 5 matching messages (Total messages in folder: 78)
First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso
Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter
//SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
Testing email account: <*********#gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GE) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE)
Found 20138 matching messages (Total messages in folder: 20138)
First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail
Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
Testing email account: <*********#yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT)
Found 5 matching messages (Total messages in folder: 78)
First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso
Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 BEFORE 7-Apr-2016 ALL
Testing email account: <*********#gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LT)
Found 20138 matching messages (Total messages in folder: 20138)
First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail
Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
Testing email account: <*********#yahoo.es> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE)
Found 5 matching messages (Total messages in folder: 78)
First Message: Mon Apr 04 23:14:22 CEST 2016 --> Mail Subject: Aviso
Last Message: Tue Apr 05 00:48:00 CEST 2016 --> Mail Subject: Alter
//SEARCH NOT ON 3-Apr-2016 SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
Testing email account: <*********#gmail.com> with startDate: <Sun Apr 03 00:00:00 CEST 2016> (ComparisonTerm.GT) and endDate: <Thu Apr 07 00:00:00 CEST 2016> (ComparisonTerm.LE)
Found 20138 matching messages (Total messages in folder: 20138)
First Message: Sat Sep 04 13:23:35 CEST 2004 --> Mail Subject: Gmail
Last Message: Tue Apr 19 10:09:06 CEST 2016 --> Mail Subject: El re
From this result we can say the following:
Yahoo returns the proper amount of emails, considering the given Java conditions.
Javamail's request is probably too ambiguous.
#Gmail: given the bunch of conditions in some requests... why you just decide to return the whole folder?
Why is there a different response for the same request?
Who is returning mails right?
Aren't protocols designed to standarise things instead of making it even worse?
We also tried with an Outlook account, with the same result as Gmail.
It sure looks like a bug in Gmail to me. I was able to reproduce it myself. I'm really surprised if Outlook.com has the same bug.
Why do you think the request is ambiguous? The IMAP spec is pretty clear.
A few notes...
Are you sure you're using JavaMail 1.5.5? The SEARCH commands you're showing reflect a JavaMail bug from before 1.5.3.
You should change Session.getDefaultInstance to Session.getInstance.
You don't need the socket factory properties; just set "mail.imap.ssl" to "true" instead.
#BillShannon
I think #popilla20k sees the request ambiguous because when he makes a request with a "GT" AND "LE" searchTerm (andTerm), it is decomposed, for example, as:
//SEARCH SINCE 3-Apr-2016 OR BEFORE 7-Apr-2016 ON 7-Apr-2016 ALL
I must say I've seen a change in Google's behaviour on April 6. Days before, I retrieved all mails that satisfied the condition with "GT" AND "LE" searchTerm. After April 6, I see the same behaviour showed by #popilla20k (using javamail 1.5.5)
Even so, I think the clause OR BEFORE invalids the first one. Does it should be AND clause, isn't? Anyway, days before April 6 the same requests were answered differently than nowadays.
Thanks.
Related
I am trying to create a lambda funciton through serverless framewrok and want to expose a REST endpoint that will list all the s3 buckets in a region mentioned if the lambda gets triggered through api gateway call.
I successfully created a REST api with hard coded values as mentioned below -
SUCCESS SCENARIO
lambda code:
#RestController
public class LanguageResource {
#RequestMapping(path = "/languages", method = RequestMethod.GET)
public List<Language> listLambdaLanguages() {
return Arrays.asList(new Language("node"), new Language("java"), new Language("python"));
}
}
SAM.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda with spring boot.
Resources:
LambdaSpringBootFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.test.lambda.LambdaHandler::handleRequest
Runtime: java8
CodeUri: target/spring-boot-lambda-1.0.0-SNAPSHOT.jar
MemorySize: 1512
Role: arn:aws:iam::XXXXXX:role/rol-lambda-servicenow
# Policies: AWSLambdaBasicExecutionRole
Timeout: 60
Events:
GetResource:
Type: Api
Properties:
Path: /{proxy+}
Method: any
Outputs:
LambdaSpringBootApi:
Description: URL for application
Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Stage/languages'
Export:
Name: LambdaSpringBootApi
endpoint:
/languages
output:
Mon Aug 31 14:13:55 UTC 2020 : Endpoint request body after transformations: {"resource":"/{proxy+}","path":"/languages","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":{"proxy":"languages"},"stageVariables":null,"requestContext":{"resourceId":"b04re4","resourcePath":"/{proxy+}","httpMethod":"GET","extendedRequestId":"SI3RfEFWDoEFltg=","requestTime":"31/Aug/2020:14:13:55 +0000","path":"/{proxy+}","accountId":"XXXXXX","protocol":"HTTP/1.1","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestTimeEpoch":1598883235028,"requestId":"caa5dcc6-60ca-4a35-9a6b-a0f3c2a2555a","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"arn:aws:sts::XXXXXX:assumed-role/rol-mgt-dta-administrators/aniruddha.ghosh","apiKeyId":"test-invoke-api-key-id","userAgent":"aws-internal/3 aws-sdk-java/1.11.829 Linux/4.9.217-0.1.ac.205.84.332.metal1. [TRUNCATED]
Mon Aug 31 14:13:55 UTC 2020 : Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:XXXXXX:function:ssc-mgt-dta-servicenow-la-LambdaSpringBootFunction-DI8EHLE9ME1U/invocations
Mon Aug 31 14:14:05 UTC 2020 : Received response. Status: 200, Integration latency: 10595 ms
Mon Aug 31 14:14:05 UTC 2020 : Endpoint response headers: {Date=Mon, 31 Aug 2020 14:14:05 GMT, Content-Type=application/json, Content-Length=188, Connection=keep-alive, x-amzn-RequestId=1338096f-3eec-4bf4-bd0f-9873250b4e8b, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5f4d05a3-789c6e282a4f7f92e19a77ff;sampled=0}
Mon Aug 31 14:14:05 UTC 2020 : Endpoint response body before transformations: **{"statusCode":200,"multiValueHeaders":{"Content-Type":["application/json; charset=UTF-8"]},"body":"[{\"name\":\"node\"},{\"name\":\"java\"},{\"name\":\"python\"}]","isBase64Encoded":false}**
Mon Aug 31 14:14:05 UTC 2020 : Method response body after transformations: [{"name":"node"},{"name":"java"},{"name":"python"}]
Mon Aug 31 14:14:05 UTC 2020 : Method response headers: {Content-Type=application/json; charset=UTF-8, X-Amzn-Trace-Id=Root=1-5f4d05a3-789c6e282a4f7f92e19a77ff;Sampled=0}
Mon Aug 31 14:14:05 UTC 2020 : Successfully completed execution
Mon Aug 31 14:14:05 UTC 2020 : Method completed with status: 200
However, when i try to list s3 buckets what i understood that i need to use aws s3 SDK and while used it as mentioned below it is throwing me gateway timeout error with no specific details. I am very new into these things that is why need help
FAILURE SCENARIO
lambda code:
#RequestMapping(path = "/languages", method = RequestMethod.GET)
public ListBucketsResponse listLambdaLanguages() {
Region region = Region.EU_WEST_1;
S3Client s3 = S3Client.builder().region(region).build();
ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
ListBucketsResponse listBucketsResponse = s3.listBuckets(listBucketsRequest);
listBucketsResponse.buckets().stream().forEach(x -> System.out.println(x.name()));
return listBucketsResponse;
}
SAM.yml
endpoint:
/languages
Output:
Mon Aug 31 14:17:40 UTC 2020 : Endpoint request body after transformations: {"resource":"/{proxy+}","path":"/languages","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":{"proxy":"languages"},"stageVariables":null,"requestContext":{"resourceId":"2n2pvy","resourcePath":"/{proxy+}","httpMethod":"GET","extendedRequestId":"SI30xFwRDoEFRPA=","requestTime":"31/Aug/2020:14:17:40 +0000","path":"/{proxy+}","accountId":"XXXXXX","protocol":"HTTP/1.1","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestTimeEpoch":1598883460839,"requestId":"df87b0f3-57de-45f8-9c11-d64000be3d61","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"arn:aws:sts::XXXXXX:assumed-role/rol-mgt-dta-administrators/aniruddha.ghosh","apiKeyId":"test-invoke-api-key-id","userAgent":"aws-internal/3 aws-sdk-java/1.11.829 Linux/4.9.217-0.1.ac.205.84.332.metal1. [TRUNCATED]
Mon Aug 31 14:17:40 UTC 2020 : Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:XXXXXX:function:ssc-mgt-dta-servicenow-la-LambdaSpringBootFunction-U14LQ9SEJQ4I/invocations
Mon Aug 31 14:17:57 UTC 2020 : Received response. Status: 200, Integration latency: 16221 ms
Mon Aug 31 14:17:57 UTC 2020 : Endpoint response headers: {Date=Mon, 31 Aug 2020 14:17:57 GMT, Content-Type=application/json, Content-Length=143, Connection=keep-alive, x-amzn-RequestId=1c9e34f3-fa10-4db0-b825-5e40e3ac9e94, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5f4d0684-a47151cdb1421b4494698ebf;sampled=0}
Mon Aug 31 14:17:57 UTC 2020 : Endpoint response body before transformations: {"statusCode":502,"multiValueHeaders":{"Content-Type":["application/json"]},"body":"{\"message\":\"Gateway timeout\"}","isBase64Encoded":false}
Mon Aug 31 14:17:57 UTC 2020 : Method response body after transformations: {"message":"Gateway timeout"}
Mon Aug 31 14:17:57 UTC 2020 : Method response headers: {Content-Type=application/json, X-Amzn-Trace-Id=Root=1-5f4d0684-a47151cdb1421b4494698ebf;Sampled=0}
Mon Aug 31 14:17:57 UTC 2020 : Successfully completed execution
Mon Aug 31 14:17:57 UTC 2020 : Method completed with status: 502
Note:
this role rol-lambda-servicenow has full access on s3
Your lambda does not have permission to do that so it's blocked. You can read more here https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html
Also try to go to CloudWatch log groups in your AWS console. Logs should tell you clearly about that problem
Here's the story:
Sending a request from SOAPUI (5.2.1) gives me either correct response or, in case of invalid parameters, the error in form of xml.
Looking at SoapUI log this is what i see:
Wed Jan 18 16:32:39 EST 2017:DEBUG:Attempt 1 to execute request
Wed Jan 18 16:32:39 EST 2017:DEBUG:Sending request: POST/XBC/services/TranslateGeometryService HTTP/1.1
Wed Jan 18 16:32:48 EST 2017:DEBUG:Receiving response: HTTP/1.1 401 Unauthorized
Wed Jan 18 16:32:48 EST 2017:DEBUG:Connection can be kept alive for 10000 MILLISECONDS
Wed Jan 18 16:32:48 EST 2017:DEBUG:Target requested authentication
Wed Jan 18 16:32:48 EST 2017:DEBUG:Authorization challenge processed
Wed Jan 18 16:32:48 EST 2017:DEBUG:Authentication scope: BASIC 'Spring Security Application'#mywebservice:80
Wed Jan 18 16:32:48 EST 2017:INFO:mywebservice:80 requires authentication with the realm 'Spring Security Application'
Wed Jan 18 16:32:48 EST 2017:DEBUG:Found credentials
Wed Jan 18 16:32:48 EST 2017:DEBUG:Attempt 2 to execute request
Wed Jan 18 16:32:48 EST 2017:DEBUG:Sending request: POST/XBC/services/TranslateGeometryService HTTP/1.1
Wed Jan 18 16:33:14 EST 2017:DEBUG:Receiving response: HTTP/1.1 500 Internal Server Error
Wed Jan 18 16:33:14 EST 2017:DEBUG:Connection shut down
Wed Jan 18 16:33:14 EST 2017:INFO:Got response for [TranslateGeometrySoap11.getLocationFromTramPoleTrackOffset:Request 1] in 35794ms (312 bytes)
(Note that those 312 bytes come after error 500 and connection shut down messages)
Response window, at the same time, in SOAPUI shows this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">Error: No Track exists with Track Code: CHS-CSK-UP-TW</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
This is perfect and works as i expect it to work.
Now for my problem that is seriously driving me mad.
When i attempt to send exactly the same request from my java code that is supposed to return the error above, i receive IOException that says:
Server returned HTTP response code: 500 for URL: http://mywebservice/XBC/services/TranslateGeometryService
So, pretty much same as what SOAPUI shows in its log.
But...
No matter what i do in my code i cannot get that message in faultstring that SOAPUI displays: "No Track exists with Track Code: CHS-CSK-UP-TW".
How is SOAPUI doing it after it receives error 500? Or, more importantly - how do i get it in JAVA after receiving error 500?
Tried playing with SoapFaultException class and SoapFault, but i could not find anything more anywhere.
Thanks to anyone who tries to answer this question.
Cheers,
Pierre
The next code in Java handler uses SOAPMessageContext TO detect SOAP fault and extract fault string from SOAPBody:
public bool handleFault(SOAPMessageContext context)
{
try {
if (context.getMessage().getSOAPBody().hasFault()) {
SOAPFault fa = context.getMessage().getSOAPBody().getFault();
System.err.println(fa.getFaultCode());
System.err.println(fa.getFaultString());
}
return true;
} catch (SOAPException ex) {
System.err.println("Fault parsing Exception:" + ex.getMessage());
return true;
}
return false;
}
I am trying to send multiple mails using JAVA Mail -
When I add a single Recipient -
message.addRecipient(Message.RecipientType.TO, new InternetAddress(“abc#xyz.com”));
It works fine, but not when I add multiple email addresses -
Here is the code
message.addRecipient(Message.RecipientType.TO, new InternetAddress(“abc#xyz.com”));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(“def#xyz.com"));
message.addRecipient(Message.RecipientType.CC, new InternetAddress(“ghi#xyz.com"));
message.addRecipient(Message.RecipientType.CC, new InternetAddress(“jkl#xyz.com"));
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(“mno#xyz.com"));
The mail is sent and received, but when I check the email of abc#xyz.com I can't see that the email has also been sent to def#xyz.com or vise versa. Neither I can see CC in the list.
Mail details from abc#xyz.com
from: xyz#xyz.com
to: abc#xyz.com
date: Thu, Sep 8, 2016 at 4:38 PM
subject: Test
Mail details from def#xyz.com
from: xyz#xyz.com
to: def#xyz.com
date: Thu, Sep 8, 2016 at 4:38 PM
subject: Test
Mail details from ghi#xyz.com
from: xyz#xyz.com
to: ghi#xyz.com
date: Thu, Sep 8, 2016 at 4:38 PM
subject: Test
Mail details from jkl#xyz.com
from: xyz#xyz.com
to: jkl#xyz.com
date: Thu, Sep 8, 2016 at 4:38 PM
subject: Test
I tried changing the logic a little, but same result -
message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(“abc#xyz.com, def#xyz.com"));
message.addRecipient(Message.RecipientType.CC, InternetAddress.parse(“ghi#xyz.com, jkl#xyz.com”));
message.addRecipient(Message.RecipientType.BCC, InternetAddress.parse(“mno#xyz.com"));
I am expecting to see the details as -
from: xyz#xyz.com
to: abc#xyz.com, def#xyz.com
cc: ghi#xyz.com, jkl#xyz.com
date: Thu, Sep 8, 2016 at 4:38 PM
subject: Test
You should try:
Address[] toArray = new Address[] {InternetAddress.parse("abc#xyz.com"),
InternetAddress.parse("def#xyz.com")};
message.addRecipients(Message.RecipientType.TO, toArray);
To prevent any mistakes and surprises, I would recommend to use setRecipients(Message.RecipientType type, Address[] addresses) as next:
message.setRecipients(
Message.RecipientType.TO,
new Address[]{new InternetAddress("abc#xyz.com"), new InternetAddress("def#xyz.com")}
);
Twitter4j search returns results with many fields.
ex:
StatusJSONImpl{createdAt=Fri Jan 09 19:56:31 IST 2015, id=553558441482924033, text='Avast Free Antivirus 2015 [Download]: Avast Free Antivirus 2015 [Download] by AVAST Software s.r.o. Platform:… http://t.co/0zLPutC1PU', source='dlvr.it', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=0, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=0, isPossiblySensitive=false, isoLanguageCode='en', lang='en', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[URLEntityJSONImpl{url='http://t.co/0zLPutC1PU', expandedURL='http://amzn.to/1q69X9Z', displayURL='amzn.to/1q69X9Z'}], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=UserJSONImpl{id=2792966010, name='Jessica', screenName='JessicaN372', location='US', description='Jessica', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/508946722307846144/E5Bi70E8_normal.jpeg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/508946722307846144/E5Bi70E8_normal.jpeg', url='null', isProtected=false, followersCount=128, status=null, profileBackgroundColor='C0DEED', profileTextColor='333333', profileLinkColor='0084B4', profileSidebarFillColor='DDEEF6', profileSidebarBorderColor='C0DEED', profileUseBackgroundImage=true, showAllInlineMedia=false, friendsCount=0, createdAt=Sat Sep 06 08:13:33 IST 2014, favouritesCount=0, utcOffset=-1, timeZone='null', profileBackgroundImageUrl='http://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundImageUrlHttps='https://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundTiled=false, lang='en', statusesCount=148653, isGeoEnabled=false, isVerified=false, translator=false, listedCount=2, isFollowRequestSent=false}}
Where I only require text and links.
How to request only certain fields
It's not possible to request certain fields as the Twitter Search API doesn't provide this functionality.
Instead you will need to extract what you are interested in from the Status yourself.
In your case you can use status.getText() and status.getUrlEntities() to get what you want.
I have followed this tutorial http://www.javacodegeeks.com/2012/03/twitter-api-on-your-java-application.html and did the exact same thing. But I am getting an error which is shown below. Am I missing something? Should I be setting some permissions in any file? I have checked in many places but still couldn't fix this. Please help
Exception in thread "main" 401:Authentication credentials
(https://dev.twitter.com/docs/auth) were missing or incorrect. Ensure that you have set
valid conumer key/secret, access token/secret, and the system clock in in sync.
error - Not authorized
request - /1/statuses/user_timeline.json?
TwitterException{exceptionCode=[ced778ef-115a04e4], statusCode=401, retryAfter=-1,
rateLimitStatus=RateLimitStatusJSONImpl{remainingHits=145, hourlyLimit=150,
resetTimeInSeconds=1362901, secondsUntilReset=1235, resetTime=Sun Mar 10 13:15:51 IST
2013}, featureSpecificRateLimitStatus=null, version=2.2.5}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:185)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:65)
at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:85)
at twitter4j.TwitterImpl.get(TwitterImpl.java:1895)
at twitter4j.TwitterImpl.getUserTimeline(TwitterImpl.java:254)
at com.jdwb.twitterapi.tweet.main(tweet.java:33)
public class tweet {
public static void main(String[] args) throws TwitterException {
Twitter twitter = new TwitterFactory().getInstance();
ResponseList < Status > a = twitter.getUserTimeline(new Paging(1, 5));
for (Status b: a) {
System.out.println(b.getText());
}
}
}
-------------------------Properties file-------------
debug=true
oauth.consumerKey=***************
oauth.consumerSecret=***********
oauth.accessToken=*******************
oauth.accessTokenSecret=***********************
[Sun Mar 10 14:41:26 IST 2013]status: 401 Unauthorized
[Sun Mar 10 14:41:26 IST 2013]x-ratelimit-remaining: 143
[Sun Mar 10 14:41:26 IST 2013]content-encoding: gzip
[Sun Mar 10 14:41:26 IST 2013]date: Sun, 10 Mar 2013 09:11:26 GMT
[Sun Mar 10 14:41:26 IST 2013]x-ratelimit-reset: 1362908664
[Sun Mar 10 14:41:26 IST 2013]x-transaction: 58f6c286bb1aa6de
[Sun Mar 10 14:41:26 IST 2013]pragma: no-cache
[Sun Mar 10 14:41:26 IST 2013]cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
[Sun Mar 10 14:41:26 IST 2013]{"request":"\/1\/statuses\/user_timeline.json?include_rts=true&include_entities=true&include_my_retweet=1&count=5&page=1","error":"Not authorized"}
Exception in thread "main" 401:Authentication credentials
(https://dev.twitter.com/docs/auth) were missing or incorrect. Ensure that you have
set valid conumer key/secret, access token/secret, and the system clock in in sync.
error - Not authorized
I presume that you have not got your authorization set up correctly
have a look here for how to set up the properties file.
you need to sign up to the twitter dev to get your API keys so that you can fill in the information that you need.