ErrorIrresolvableConflict while creating an event - active-directory

I am getting a lot of errors related to ErrorIrresolvableConflict response code when trying to create an event
Stack Trace - at Microsoft.OData.ProxyExtensions.DataServiceContextWrapper.<SaveChangesAsync>d__5e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Office365CalendarProviderBL.<>c__DisplayClass7_0.<<CreateCalendarEvent>b__0>d.MoveNext() - Inner Exception - Microsoft.OData.Client.DataServiceRequestException: An error occurred while processing this request. ---> Microsoft.OData.Client.DataServiceClientException: {"error":{"code":"ErrorIrresolvableConflict","message":"The send or update operation could not be performed because the change key passed in the request does not match the current change key for the item."}}
--- End of inner exception stack trace ---
at Microsoft.OData.Client.SaveResult.HandleResponse()
at Microsoft.OData.Client.BaseSaveResult.EndRequest()
at Microsoft.OData.Client.DataServiceContext.EndSaveChanges(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.OData.ProxyExtensions.DataServiceContextWrapper.<SaveChangesAsync>d__5e.MoveNext()
I am getting this message with this exception - The send or update operation could not be performed because the change key passed in the request does not match the current change key for the item.
Please explain what is a change key and how it works ?
I am getting these exceptions only from yesterday and hasn't changed any code. Do I need to update anything at my end or am I missing anything ?
I am using V1 DLL - https://api.office.com/discovery/v1.0/me/
ProxyExtension Version - 23
Code:-
// In this method, we are populating event properties later used to create event on calendar. Please verify if I am missing any important property here
private Event CreateCalEventObj(CalendarMeetingBL meeting, string location, meetingAdditionalDataBL data)
{
Event calEvent = new Event();
try
{
calEvent.Subject = WEB.HttpUtility.HtmlDecode(meeting.MeetingName);
calEvent.ShowAs = FreeBusyStatus.Busy;
if (meeting.EventAlarmInMinutes == -1)
meeting.EventAlarmInMinutes = null;
calEvent.Reminder = meeting.EventAlarmInMinutes;
calEvent.Start = meeting.StartTime;
calEvent.End = meeting.EndTime;
calEvent.StartTimeZone = meeting.TimeZoneString;
calEvent.EndTimeZone = meeting.TimeZoneString;
if (!string.IsNullOrEmpty(location) && location.Length <= 500)
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(location.Replace("\n", " ")))
};
}
else if (!string.IsNullOrEmpty(data.Phone))
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = "Phone: " + CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(data.Phone))
};
}
else if (!string.IsNullOrEmpty(data.MobileNumber))
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = "Mobile: " + CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(data.MobileNumber))
};
}
calEvent.Body = new ItemBody()
{
Content = CommonBL.RevertLineBreakPlaceHolder((WEB.HttpUtility.HtmlDecode(meeting.MeetingDetails.Replace(#"\\\", "\\"))))
};
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert logging here");
calEvent = null;
}
return calEvent;
}
// In this method we are creating event on calendar.
private string CreateCalendarEvent(CalendarMeetingBL meeting, List<ParticipantBL> invitees, string username, string calendarId, OutlookServicesClient service, string location, meetingAdditionalDataBL data, string meetingId = "-1")
{
var taskCreateMeeting = Task<string>.Run(
async () =>
{
Event calEvent = CreateCalEventObj(meeting, location, data);
if (calEvent != null)
{
try
{
//Add invitees to the event
foreach (ParticipantBL inviteeItem in invitees)
{
if (!inviteeItem.IsAdditional)
{
calEvent.Attendees.Add(new Attendee()
{
EmailAddress = new EmailAddress()
{
Address = inviteeItem.Email.Replace("'", "'"),
Name = inviteeItem.Name
},
Type = AttendeeType.Required,
Status = new ResponseStatus()
{
Response = ResponseType.Accepted,
Time = DateTime.Now
}
});
}
}
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog(meeting.MeetingId, username, "Locally User ID is Meeting id AND email is username - Scheduling Logging Exception 3 - Stack Trace - " + ex.StackTrace + " - Inner Exception - " + ex.InnerException + " - meetingObjValues - " + meetingObjValues + " - meetingAdditionalDataObjValues - " + meetingAdditionalDataObjValues + " - username - " + username + " - calendarId - " + calendarId + " - location - " + location + " - meetingId - " + meetingId, meeting.MeetingId);
return "-1";
}
try
{
var providerDefault = (String.IsNullOrEmpty(calendarId) ? service.Me.Events : service.Me.Calendars[calendarId].Events);
await providerDefault.AddEventAsync(calEvent); // We are getting Exception here but Event is created in calendar
return calEvent.Id; // Event object is not updated after exception
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert exception logging here");
return "-1";
}
}
else
return "-1";
}
);
Task.WaitAll(taskCreateMeeting);
string id = taskCreateMeeting.Result;
return id;
}
The exception we are getting is of type Microsoft.OData.Client.DataServiceRequestException but it is not caught under the dedicated catch block
catch (Microsoft.OData.Client.DataServiceRequestException ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert logging here");
return "-1";
}
Let me know if anything else is required
Thanks in Advance.

This is not directly related to OData - we have seen the same thing with EWS. We just found the underlying race condition inside of Exchange code that was causing this and one of our devs just checked in a fix for this. As such, it should start rolling out in production soon.
There is nothing wrong with your code that would be causing this for a new item.

Related

How to resolve MetadataAPI giving 'System.CalloutException: IO Exception: Read timed out' error on setting recordType to lookupfield value

I am using metadata API to add picklist value('custom') in a field.I have a record type (AAM_T) created which has to be associated with value I have added to picklist, but as on running :
service.updateMetadata( new MetadataService.Metadata[] { recordType });
causing an error 'System.CalloutException: IO Exception: Read timed out'.
MetadataService.PickListValue objPickListValue = new MetadataService.PickListValue();
objPickListValue.fullName = 'custom';
objPickListValue.default_x = false;
MetadataService.RecordType recordType = (MetadataService.RecordType)
service.readMetadata('RecordType',
new String[] { 'Account.AAM_T'}).getRecords()[0];
MetadataService.RecordTypePicklistValue[] recordPickListType = recordType.picklistValues;
if(recordPickListType.size() > 0){
for(MetadataService.RecordTypePicklistValue rpk : recordPickListType) {
if(rpk.picklist == picklistToUpdate){
rpk.values.add(objPickListValue);
break;
}
}
try{
service.updateMetadata( new MetadataService.Metadata[] { recordType });
} catch(Exception ex){
system.debug('###getStackTraceString : '+ex.getStackTraceString());
//Result: System.CalloutException: IO Exception: Read timed out -- null
system.debug('###getMessage : '+ex.getTypeName()
+ ': ' + ex.getMessage() + ' -- ' + ex.getCause());
}
}
You can try this like any other webservice. worked to me
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.timeout_x=120000;

JavaMail Check GMail INBOX is taking too long to connect and answer back

I have a process that must check the INBOX on GMail for a failure message, it's working except for the problem of the time it takes to connect and check the message, it takes about 1 minute, that is too much time.
My code:
public static SendResult sendingSuccess(final String email) {
SendResult result = new SendResult();
try {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imap.com", "993");
props.setProperty("mail.imap.connectiontimeout", "5000");
props.setProperty("mail.imap.timeout", "5000");
Session session = Session.getDefaultInstance(props);
Store store = session.getStore("imaps");
store.connect("imap.googlemail.com", 993, GMAIL_USER, GMAIL_PASSWORD);
// Select and open folder
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
// What to search for
SearchTerm searchTerm = new SearchTerm() {
private static final long serialVersionUID = -7187666524976851520L;
public boolean match(Message message) {
try {
String content = getContent(message);
boolean daemon = (message.getFrom()[0].toString()).contains("mailer-daemon#googlemail.com");
boolean failure = message.getSubject().contains("Failure");
boolean foundWarning = content.contains(email);
if (daemon && failure && foundWarning) {
return true;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
};
// Fetch unseen messages from inbox folder
Message[] messages = inbox.search(searchTerm);
// If there is no message then it's OK
result.setStatus(messages.length == 0);
result.setMessage(result.isStatus() ? "No failure message found for " + email : "Failure message found for " + email);
// Flag message as DELETED
for (Message message : messages) {
message.setFlag(Flags.Flag.DELETED, true);
}
// disconnect and close
inbox.close(false);
store.close();
} catch (Exception ex) {
result.setMessage(ex.getMessage());
ex.printStackTrace();
}
return result;
}
When I run this code to query the failure message it takes more than 1 minute to return the result to me.
======= Checking Gmail account for message failure! =====
Start...: 09:00:33
Finish..: 09:01:01
Result..: SendResult [status=true, message=No failure found for wrong.user#gmxexexex.net]
Is there any way to reduce this time?
The problem is most likely because you've written your own search term. JavaMail doesn't know how to translate your search term into an IMAP SEARCH request so it executes the search on the client, which requires downloading all the messages to the client to search there. Try this instead:
SearchTerm searchTerm = new AndTerm(new SearchTerm[] {
new FromStringTerm("mailer-daemon#googlemail.com"),
new SubjectTerm("Failure"),
new BodyTerm(email)
});
That will allow the search to be done by the IMAP server.

Re-index items in DSpace 6.2 after updating through REST

We are trying to build an application to provide bulk editing of item metadata ingested in DSpace, using the REST API. The update operations are being reflected in the DSpace UI. However the metadata remains unchanged in Solr, unless we run index-discovery. Since we intend to work with a large amount of data, running index-discovery everytime a metadata is edited, would be expensive. Could someone suggest a workaround/solution for this?
You could trigger an item update in the Java class of the REST endpoint.
For example:
In method addItemMetadata of java class org.dspace.rest.ItemsResource which represents the /items REST endpoint you could add the following line after the item metadata has been changed:
itemService.update(context, dspaceItem);
This line of code triggers an index update for that specific item.
This is what the complete addItemMetadata method will look like after the above change:
#POST
#Path("/{item_id}/metadata")
#Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response addItemMetadata(#PathParam("item_id") String itemId, List<org.dspace.rest.common.MetadataEntry> metadata,
#QueryParam("userIP") String user_ip, #QueryParam("userAgent") String user_agent,
#QueryParam("xforwardedfor") String xforwardedfor, #Context HttpHeaders headers, #Context HttpServletRequest request)
throws WebApplicationException
{
log.info("Adding metadata to item(id=" + itemId + ").");
org.dspace.core.Context context = null;
try
{
context = createContext();
org.dspace.content.Item dspaceItem = findItem(context, itemId, org.dspace.core.Constants.WRITE);
writeStats(dspaceItem, UsageEvent.Action.UPDATE, user_ip, user_agent, xforwardedfor, headers, request, context);
for (MetadataEntry entry : metadata)
{
// TODO Test with Java split
String data[] = mySplit(entry.getKey()); // Done by my split, because of java split was not function.
if ((data.length >= 2) && (data.length <= 3))
{
itemService.addMetadata(context, dspaceItem, data[0], data[1], data[2], entry.getLanguage(), entry.getValue());
}
}
itemService.update(context, dspaceItem);
context.complete();
}
catch (SQLException e)
{
processException("Could not write metadata to item(id=" + itemId + "), SQLException. Message: " + e, context);
}
catch (ContextException e)
{
processException("Could not write metadata to item(id=" + itemId + "), ContextException. Message: " + e.getMessage(),
context);
} catch (AuthorizeException e) {
processException("Could not update item(id=" + itemId + "), AuthorizeException. Message: " + e.getMessage(),
context);
} finally
{
processFinally(context);
}
log.info("Metadata to item(id=" + itemId + ") were successfully added.");
return Response.status(Status.OK).build();
}

Set field Accessibility to Custom Salesforce Lead field from Java code

I am working around with Salesforce and force.com API and metadata API, version 36.
I can create a custom field in a Lead object but by default I can see it's hidden and this means I cannot create a new Lead with these custom fields because it returns a bad request (400 status code).
Is there any way by Code to set the custom field Visible?
public boolean createCustomExtTextField(String name, LoginResult metadataLoginResult, int length) {
boolean success = false;
CustomField cs = new CustomField();
cs.setFullName("Lead."+name+"__c");
cs.setLabel("Custom"+name+"Field");
cs.setType(FieldType.LongTextArea);
cs.setLength(length);
cs.setVisibleLines(50); // max 50
try {
MetadataConnection metadataConnection = createMetadataConnection(metadataLoginResult);
SaveResult[] results = metadataConnection.createMetadata(new Metadata[] { cs });
for (SaveResult r : results) {
if (r.isSuccess()) {
success = true;
} else {
System.out.println("Errors were encountered while creating " + r.getFullName());
for (com.sforce.soap.metadata.Error e : r.getErrors()) {
System.out.println("Error message: " + e.getMessage());
System.out.println("Status code: " + e.getStatusCode());
}
}
}
} catch (ConnectionException e) {
e.printStackTrace();
}
return success;
}
I am googling a lot and don't find something that actually helped. So, any hints are welcomed. Thank you.
Finally found a solution to this. I final one for me was to make all custom fields REQUIRED.
CustomField cs = new CustomField();
cs.setFullName("Lead.YourCompanyName" + name + "__c");
cs.setLabel("YourCompanyName" + name);
cs.setRequired(true);
...
com.sforce.soap.enterprise.LoginResult metadataLoginResult = operations.loginToMetadata(username, password, "https://login.salesforce.com/services/Soap/c/36.0");
...
private boolean createFieldInMetadata(LoginResult metadataLoginResult, CustomField cs) {
boolean success = false;
try {
MetadataConnection metadataConnection = createMetadataConnection(metadataLoginResult);
SaveResult[] results = metadataConnection.createMetadata(new Metadata[] { cs });
for (SaveResult r : results) {
if (r.isSuccess()) {
success = true;
} else {
System.out.println("Errors were encountered while creating " + r.getFullName());
for (com.sforce.soap.metadata.Error e : r.getErrors()) {
System.out.println("Error message: " + e.getMessage());
System.out.println("Status code: " + e.getStatusCode());
}
}
}
} catch (Exception e) {
}
return success;
}
And so it will appear in the page layout. Very important to know, a required field cannot have just an empty value set, it must be something. So if not all custom fields are required in your logic and you wanna avoid the entire process of unzipping page layout and zipping it back (however it may be done) just add "N/A" or any char at choice to the required by code but not your project custom fields.
I managed to make the custom Field Level Security visible for "Admin" profile but not Field Accessability to visible. The latter is untested.

Get Unread emails from Google API

I'm trying to get the count of unread email using google API, but not able. ANy help is highly appreciated. I'm not getting any error, but the count doesnt match the actual number shown in gmail.
try
{
String serviceAccountEmail = "xxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\Projects\xxx\xyz\API Project-xxxxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = "xxx#gmail.com",
Scopes = new[] { Google.Apis.Gmail.v1.GmailService.Scope.GmailReadonly }
}.FromCertificate(certificate));
var gmailservice = new Google.Apis.Gmail.v1.GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GoogleApi3",
});
try
{
List<Message> lst = ListMessages(gmailservice, "xxx#gmail.com", "IN:INBOX IS:UNREAD");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}
catch (Exception ex)
{
}
Just do: labels.get(id="INBOX") and it has those types of stats (how many messages in that label, how many are unread, and same for threads).
https://developers.google.com/gmail/api/v1/reference/users/labels/get
You can use the ListMessages method from the API example (included for completeness) for searching:
private static List<Message> ListMessages(GmailService service, String userId, String query)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.Q = query;
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
You can use this search method to find unread messages, for example like this:
List<Message> unreadMessageIDs = ListMessages(service, "me", "is:unread");
The q parameter (query) can be all kinds of stuff (it is the same as the gmail search bar on the top of the web interface), as documented here: https://support.google.com/mail/answer/7190?hl=en.
Note that you only a few parameters of the Message objects are set. If you want to retreive the messages you'll have to use GetMessage method from the api:
public static Message GetMessage(GmailService service, String userId, String messageId)
{
try
{
return service.Users.Messages.Get(userId, messageId).Execute();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
return null;
}
I agree that the API is not straight forward and misses a lot of functionality.
Solution for .Net:
// Get UNREAD messages
public void getUnreadEmails(GmailService service)
{
UsersResource.MessagesResource.ListRequest Req_messages = service.Users.Messages.List("me");
// Filter by labels
Req_messages.LabelIds = new List<String>() { "INBOX", "UNREAD" };
// Get message list
IList<Message> messages = Req_messages.Execute().Messages;
if ((messages != null) && (messages.Count > 0))
{
foreach (Message List_msg in messages)
{
// Get message content
UsersResource.MessagesResource.GetRequest MsgReq = service.Users.Messages.Get("me", List_msg.Id);
Message msg = MsgReq.Execute();
Console.WriteLine(msg.Snippet);
Console.WriteLine("----------------------");
}
}
Console.Read();
}

Resources