use of com.zimbra.cs.fb.ExchangeFreeBusyProvider.ServerInfo in project zm-mailbox by Zimbra.
the class ExchangeEWSFreeBusyProvider method getFreeBusyForHost.
public List<FreeBusy> getFreeBusyForHost(String host, ArrayList<Request> req) throws IOException {
int fb_interval = LC.exchange_free_busy_interval_min.intValueWithinRange(5, 1444);
List<FreeBusyResponseType> results = null;
ArrayList<FreeBusy> ret = new ArrayList<FreeBusy>();
Request r = req.get(0);
long start = Request.offsetInterval(req.get(0).start, fb_interval);
ServerInfo serverInfo = (ServerInfo) r.data;
if (serverInfo == null) {
ZimbraLog.fb.warn("no exchange server info for user " + r.email);
return ret;
}
if (!serverInfo.enabled)
return ret;
ArrayOfMailboxData attendees = new ArrayOfMailboxData();
for (Request request : req) {
EmailAddress email = new EmailAddress();
email.setAddress(request.email);
MailboxData mailbox = new MailboxData();
mailbox.setEmail(email);
mailbox.setAttendeeType(MeetingAttendeeType.REQUIRED);
attendees.getMailboxData().add(mailbox);
}
try {
Duration duration = new Duration();
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
GregorianCalendar gregorianCalStart = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
gregorianCalStart.setTimeInMillis(start);
duration.setStartTime(datatypeFactory.newXMLGregorianCalendar(gregorianCalStart));
GregorianCalendar gregorianCalEnd = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
gregorianCalEnd.setTimeInMillis(req.get(0).end);
duration.setEndTime(datatypeFactory.newXMLGregorianCalendar(gregorianCalEnd));
FreeBusyViewOptionsType availabilityOpts = new FreeBusyViewOptionsType();
availabilityOpts.setMergedFreeBusyIntervalInMinutes(fb_interval);
// Request for highest hierarchy view. The rest hierarchy will be Detailed->FreeBusy->MergedOnly->None
availabilityOpts.getRequestedView().add("DetailedMerged");
availabilityOpts.setTimeWindow(duration);
GetUserAvailabilityRequestType availabilityRequest = new GetUserAvailabilityRequestType();
// TODO: check if we need to set request timezone
SerializableTimeZone timezone = new SerializableTimeZone();
timezone.setBias(0);
SerializableTimeZoneTime standardTime = new SerializableTimeZoneTime();
standardTime.setTime("00:00:00");
standardTime.setDayOrder((short) 1);
standardTime.setDayOfWeek(DayOfWeekType.SUNDAY);
timezone.setStandardTime(standardTime);
timezone.setDaylightTime(standardTime);
availabilityRequest.setTimeZone(timezone);
availabilityRequest.setFreeBusyViewOptions(availabilityOpts);
availabilityRequest.setMailboxDataArray(attendees);
RequestServerVersion serverVersion = new RequestServerVersion();
serverVersion.setVersion(ExchangeVersionType.EXCHANGE_2010_SP_1);
Holder<GetUserAvailabilityResponseType> availabilityResponse = new Holder<GetUserAvailabilityResponseType>();
Holder<ServerVersionInfo> gfversionInfo = new Holder<ServerVersionInfo>();
TimeZoneDefinitionType tzdt = new TimeZoneDefinitionType();
tzdt.setId("Greenwich Standard Time");
TimeZoneContextType tzct = new TimeZoneContextType();
tzct.setTimeZoneDefinition(tzdt);
service.getUserAvailability(availabilityRequest, tzct, serverVersion, availabilityResponse, gfversionInfo);
results = availabilityResponse.value.getFreeBusyResponseArray().getFreeBusyResponse();
} catch (DatatypeConfigurationException dce) {
ZimbraLog.fb.warn("getFreeBusyForHost DatatypeConfiguration failure", dce);
return getEmptyList(req);
} catch (Exception e) {
ZimbraLog.fb.warn("getFreeBusyForHost failure", e);
return getEmptyList(req);
}
for (Request re : req) {
int i = 0;
long startTime = req.get(0).start;
long endTime = req.get(0).end;
for (FreeBusyResponseType attendeeAvailability : results) {
if (attendeeAvailability.getFreeBusyView() != null) {
String fbResponseViewType = attendeeAvailability.getFreeBusyView().getFreeBusyViewType().get(0);
String emailAddress = attendees.getMailboxData().get(i).getEmail().getAddress();
ZimbraLog.fb.debug("For user :%s free busy response type received is : %s", emailAddress, fbResponseViewType);
if (re.email == emailAddress) {
if (ResponseClassType.ERROR == attendeeAvailability.getResponseMessage().getResponseClass()) {
ZimbraLog.fb.debug("Unable to fetch free busy for %s error code %s :: %s", emailAddress, attendeeAvailability.getResponseMessage().getResponseCode(), attendeeAvailability.getResponseMessage().getMessageText());
FreeBusy npFreeBusy = FreeBusy.nodataFreeBusy(emailAddress, startTime, endTime);
ret.add(npFreeBusy);
if (attendeeAvailability.getResponseMessage().getResponseCode().equals(ResponseCodeType.ERROR_NO_FREE_BUSY_ACCESS)) {
npFreeBusy.mList.getHead().hasPermission = false;
}
ZimbraLog.fb.info("Error in response. continuing to next one sending nodata as response");
i++;
continue;
}
String fb = attendeeAvailability.getFreeBusyView().getMergedFreeBusy();
ZimbraLog.fb.info("Merged view Free Busy info received for user:%s is %s: ", emailAddress, fb);
ArrayList<FreeBusy> userIntervals = new ArrayList<FreeBusy>();
if (fb == null) {
ZimbraLog.fb.warn("Merged view Free Busy info not avaiable for the user");
// Avoid NPE.
fb = "";
} else {
userIntervals.add(new ExchangeFreeBusyProvider.ExchangeUserFreeBusy(fb, re.email, fb_interval, startTime, endTime));
ret.addAll(userIntervals);
}
// Parsing Detailed fb view response
if ("DetailedMerged".equals(fbResponseViewType) || "FreeBusyMerged".equals(fbResponseViewType)) {
parseDetailedFreeBusyResponse(emailAddress, startTime, endTime, attendeeAvailability, userIntervals);
ret.addAll(userIntervals);
} else {
// No FreeBusy view information available. returning nodata freebusy in response
ZimbraLog.fb.debug("No Free Busy view info avaiable for [%s], free busy view type from response : %s", emailAddress, fbResponseViewType);
ret.add(FreeBusy.nodataFreeBusy(emailAddress, startTime, endTime));
}
}
i++;
}
}
}
return ret;
}
use of com.zimbra.cs.fb.ExchangeFreeBusyProvider.ServerInfo in project zm-mailbox by Zimbra.
the class ExchangeEWSFreeBusyProvider method addFreeBusyRequest.
@Override
public void addFreeBusyRequest(Request req) throws FreeBusyUserNotFoundException {
ServerInfo info = null;
for (ExchangeUserResolver resolver : sRESOLVERS) {
String email = req.email;
if (req.requestor != null)
email = req.requestor.getName();
info = resolver.getServerInfo(email);
if (info != null) {
if (!info.enabled)
throw new FreeBusyUserNotFoundException();
if (null == service) {
try {
initService(info);
} catch (MalformedURLException e) {
ZimbraLog.fb.warn("failed to initialize provider", e);
}
}
break;
}
}
if (info == null)
throw new FreeBusyUserNotFoundException();
addRequest(info, req);
}
use of com.zimbra.cs.fb.ExchangeFreeBusyProvider.ServerInfo in project zm-mailbox by Zimbra.
the class ExchangeEWSFreeBusyProvider method handleMailboxChange.
@Override
public boolean handleMailboxChange(String accountId) {
ZimbraLog.fb.debug("Entering handleMailboxChange() for account : " + accountId);
String email = getEmailAddress(accountId);
ServerInfo serverInfo = getServerInfo(email);
if (email == null || !serverInfo.enabled) {
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
// no retry
return true;
}
FreeBusy fb;
try {
fb = getFreeBusy(accountId, FreeBusyQuery.CALENDAR_FOLDER_ALL);
} catch (ServiceException se) {
ZimbraLog.fb.warn("can't get freebusy for account " + accountId, se);
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
// retry the request if it's receivers fault.
return !se.isReceiversFault();
}
if (email == null || fb == null) {
ZimbraLog.fb.warn("account not found / incorrect / wrong host: " + accountId);
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
// no retry
return true;
}
if (serverInfo == null || serverInfo.org == null || serverInfo.cn == null) {
ZimbraLog.fb.warn("no exchange server info for user " + email);
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
// no retry
return true;
}
if (null == service) {
try {
if (!initService(serverInfo)) {
ZimbraLog.fb.error("failed to initialize exchange service object " + serverInfo.url);
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
return true;
}
} catch (MalformedURLException e) {
ZimbraLog.fb.error("exception while trying to initialize exchange service object " + serverInfo.url);
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
return true;
}
}
ExchangeEWSMessage msg = new ExchangeEWSMessage(serverInfo.org, serverInfo.cn, email);
try {
FolderType publicFolderRoot = (FolderType) bindFolder(DistinguishedFolderIdNameType.PUBLICFOLDERSROOT, DefaultShapeNamesType.ALL_PROPERTIES);
if (publicFolderRoot == null) {
ZimbraLog.fb.error("Could not find the public root folder on exchange");
return true;
}
List<BaseFolderType> resultsNonIpm = findFolderByProp(publicFolderRoot.getParentFolderId(), UnindexedFieldURIType.FOLDER_DISPLAY_NAME, "NON_IPM_SUBTREE");
if (resultsNonIpm != null && resultsNonIpm.size() > 0) {
FolderType folderNonIPM = (FolderType) resultsNonIpm.get(0);
List<BaseFolderType> resultSchedulePlus = findFolderByProp(folderNonIPM.getFolderId(), UnindexedFieldURIType.FOLDER_DISPLAY_NAME, "SCHEDULE+ FREE BUSY");
if (resultSchedulePlus != null && resultSchedulePlus.size() > 0) {
FolderType folderSchedulePlus = (FolderType) resultSchedulePlus.get(0);
List<BaseFolderType> resultFBFolder = findFolderByPartialProp(folderSchedulePlus.getFolderId(), UnindexedFieldURIType.FOLDER_DISPLAY_NAME, // TODO: check here for partial name
serverInfo.org);
// search
if (resultFBFolder != null && resultFBFolder.size() > 0) {
FolderType folderFB = (FolderType) resultFBFolder.get(0);
List<ItemType> resultMessage = findItemByProp(folderFB.getFolderId(), UnindexedFieldURIType.ITEM_SUBJECT, "USER-/CN=RECIPIENTS/CN=" + getForeignPrincipal(accountId), DefaultShapeNamesType.ALL_PROPERTIES);
if (resultMessage != null && resultMessage.size() > 0) {
// edit message
ItemType itemMessage = resultMessage.get(0);
Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> props = msg.GetFreeBusyProperties(fb);
final NonEmptyArrayOfItemChangeDescriptionsType cdExPropArr = new NonEmptyArrayOfItemChangeDescriptionsType();
for (PathToExtendedFieldType pathExProp : props.keySet()) {
ItemType itemEmptyMessage = new ItemType();
SetItemFieldType sifItem = new SetItemFieldType();
sifItem.setPath(new JAXBElement<PathToExtendedFieldType>(new QName("http://schemas.microsoft.com/exchange/services/2006/types", "Path"), PathToExtendedFieldType.class, pathExProp));
ExtendedPropertyType exProp = new ExtendedPropertyType();
exProp.setExtendedFieldURI(pathExProp);
if (pathExProp.getPropertyType() == MapiPropertyTypeType.APPLICATION_TIME_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.BINARY_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.CLSID_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.CURRENCY_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.DOUBLE_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.FLOAT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.INTEGER_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.LONG_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.OBJECT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.SHORT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.STRING_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.SYSTEM_TIME_ARRAY) {
exProp.setValues(props.get(pathExProp));
} else {
if (props.get(pathExProp).getValue().size() > 0) {
exProp.setValue(props.get(pathExProp).getValue().get(0));
}
}
itemEmptyMessage.getExtendedProperty().add(exProp);
sifItem.setItem(itemEmptyMessage);
cdExPropArr.getAppendToItemFieldOrSetItemFieldOrDeleteItemField().add(sifItem);
}
UpdateItemType updateItemRequest = new UpdateItemType();
updateItemRequest.setMessageDisposition(MessageDispositionType.SAVE_ONLY);
updateItemRequest.setConflictResolution(ConflictResolutionType.ALWAYS_OVERWRITE);
RequestServerVersion serverVersion = new RequestServerVersion();
serverVersion.setVersion(ExchangeVersionType.EXCHANGE_2010_SP_1);
ItemChangeType itemExpropChange = new ItemChangeType();
itemExpropChange.setItemId(itemMessage.getItemId());
itemExpropChange.setUpdates(cdExPropArr);
final NonEmptyArrayOfItemChangesType ctExPropArr = new NonEmptyArrayOfItemChangesType();
ctExPropArr.getItemChange().add(itemExpropChange);
updateItemRequest.setItemChanges(ctExPropArr);
Holder<UpdateItemResponseType> updateItemResponse = new Holder<UpdateItemResponseType>();
Holder<ServerVersionInfo> gfversionInfo = new Holder<ServerVersionInfo>();
MailboxCultureType mct = new MailboxCultureType();
mct.setValue("EN");
TimeZoneDefinitionType tzdt = new TimeZoneDefinitionType();
tzdt.setId("Greenwich Standard Time");
TimeZoneContextType tzct = new TimeZoneContextType();
tzct.setTimeZoneDefinition(tzdt);
service.updateItem(updateItemRequest, mct, serverVersion, tzct, updateItemResponse, gfversionInfo);
ResponseMessageType updateItemResponseMessage = updateItemResponse.value.getResponseMessages().getCreateItemResponseMessageOrDeleteItemResponseMessageOrGetItemResponseMessage().get(0).getValue();
} else {
// create message
PostItemType itemMessage = new PostItemType();
itemMessage.setSubject("USER-/CN=RECIPIENTS/CN=" + getForeignPrincipal(accountId));
itemMessage.setItemClass("IPM.Post");
Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> props = msg.GetFreeBusyProperties(fb);
for (PathToExtendedFieldType pathExProp : props.keySet()) {
ExtendedPropertyType exProp = new ExtendedPropertyType();
exProp.setExtendedFieldURI(pathExProp);
if (pathExProp.getPropertyType() == MapiPropertyTypeType.APPLICATION_TIME_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.BINARY_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.CLSID_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.CURRENCY_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.DOUBLE_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.FLOAT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.INTEGER_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.LONG_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.OBJECT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.SHORT_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.STRING_ARRAY || pathExProp.getPropertyType() == MapiPropertyTypeType.SYSTEM_TIME_ARRAY) {
exProp.setValues(props.get(pathExProp));
} else {
if (props.get(pathExProp).getValue().size() > 0) {
exProp.setValue(props.get(pathExProp).getValue().get(0));
}
}
itemMessage.getExtendedProperty().add(exProp);
}
CreateItemType createItemRequest = new CreateItemType();
RequestServerVersion serverVersion = new RequestServerVersion();
serverVersion.setVersion(ExchangeVersionType.EXCHANGE_2010_SP_1);
createItemRequest.setMessageDisposition(MessageDispositionType.SAVE_ONLY);
TargetFolderIdType idTargetFolder = new TargetFolderIdType();
idTargetFolder.setFolderId(folderFB.getFolderId());
createItemRequest.setSavedItemFolderId(idTargetFolder);
NonEmptyArrayOfAllItemsType createItems = new NonEmptyArrayOfAllItemsType();
createItems.getItemOrMessageOrCalendarItem().add(itemMessage);
createItemRequest.setItems(createItems);
Holder<CreateItemResponseType> createItemResponse = new Holder<CreateItemResponseType>();
Holder<ServerVersionInfo> gfversionInfo = new Holder<ServerVersionInfo>();
MailboxCultureType mct = new MailboxCultureType();
mct.setValue("EN");
TimeZoneDefinitionType tzdt = new TimeZoneDefinitionType();
tzdt.setId("Greenwich Standard Time");
TimeZoneContextType tzct = new TimeZoneContextType();
tzct.setTimeZoneDefinition(tzdt);
service.createItem(createItemRequest, mct, serverVersion, tzct, createItemResponse, gfversionInfo);
ResponseMessageType createItemResponseMessage = createItemResponse.value.getResponseMessages().getCreateItemResponseMessageOrDeleteItemResponseMessageOrGetItemResponseMessage().get(0).getValue();
}
} else {
ZimbraLog.fb.error("Could not find the Exchange folder containing '" + serverInfo.org + "'. Make sure zimbraFreebusyExchangeUserOrg is configured correctly and it exists on Exchange");
}
} else {
ZimbraLog.fb.error("Could not find the Exchange folder 'SCHEDULE+ FREE BUSY'");
}
} else {
ZimbraLog.fb.error("Could not find the Exchange folder 'NON_IPM_SUBTREE'");
}
return true;
} catch (Exception e) {
ZimbraLog.fb.error("error communicating with " + serverInfo.url, e);
} finally {
ZimbraLog.fb.debug("Exiting handleMailboxChange() for account : " + accountId);
}
// retry
return false;
}
Aggregations