Exchange Integration via Microsoft Graph API
Archibus Extension for Microsoft Exchange
✓ Microsoft Exchange (Online)
- Microsoft announced that they are no longer making feature updates to Exchange Web Services (EWS) in Exchange Online, and they advise developers to move to Microsoft Graph.
- From October 1, 2026, Microsoft will start blocking EWS requests to Exchange Online. Note that this doesn't apply to Microsoft Exchange (On-premise).
Overview
This covers the configuration and high level processing flow of Microsoft Exchange (Online) Integration for the Reservations Application via Graph API.
Configuration in Entra ID
The following sections describe how to set up Microsoft Entra ID for integrating Archibus Reservations with Exchange Online via Graph API.
Archibus uses certificate based-authentication to retrieve a token from Entra ID. The public key is uploaded to Entra ID, the private key is made available to the application.
You can use a self-signed certificate or an official certificate generated by a Certificate Authority.
Create a self-signed certificate
The steps below indicate how to create a self-signed certificate using OpenSSL. As a minimum, consider using a 2048-bit certificate based on SHA-256. Using a 4096-bit certificate is recommended.
- Generate a new keypair. This will prompt to enter certificate details. Note you don’t have to use a valid hostname for the common name of the certificate. You can use a name like ‘WebCentral Oauth’.
openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 4000 -out cert.pem
- Review certificate contents.
openssl x509 -text -noout -in cert.pem
- Convert to pfx. This will prompt to enter a password.
openssl pkcs12 -inkey key.pem -in cert.pem -export -out cert.pfx
- Review pfx contents.
openssl pkcs12 -in C:\temp\oauth\cert.pfx -noout -info
Convert keystore from JKS to PKCS#12 format
For Exchange integration via Exchange Web Services (EWS), Archibus uses a java keystore (JKS) file. If you are switching from EWS to Graph API and need to keep using the same certificate, you can convert the JKS to PKCS#12 using java keytool. You need the keystore password.
keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype pkcs12
Create the app registration in Entra ID
This step-by-step guide shows how to configure the Office 365 tenant for allowing the connection from the ARCHIBUS Extension for Exchange via Graph API, after you obtained the certificate.
- Sign in to the Entra ID Portal at https://entra.microsoft.com/ with an admin account.
- Navigate to Identity > App Registrations > New registration.

- Enter a name for the app registration.
- For supported account types, keep the single tenant option. Leave the redirect URL empty.
- Select Register.

- Copy the values for Application (client) ID and Directory (tenant) ID. These need to be entered in reservations.properties later.

- Navigate to Manage > API permissions in the App registration menu.

- Remove the User.Read permission if it is present.
- Select Add a permission > Microsoft Graph > Application permissions.

- Select the following permissions:
- Calendars.ReadWrite
- Mail.ReadWrite. Note: this permission is only needed for the resource mailbox. It is used for monitoring meetings linked to reservations in rooms without a mailbox. See the final step of this guide for options to allow this permission only for the resource mailbox.
- Select Add permissions.
- Check that the correct permissions are listed and select Grant admin consent.

- Select yes on the confirmation popup.

- Confirm that the admin consent status is marked Granted for the selected permissions.

- Navigate to Manage > Certificates & secrets > Certificates > Upload certificate.

-
Browse to the public key of the certificate on your computer and select it. Then select Add. Note: you can use a self-signed certificate or a certificate generated by a Certificate Authority.

- Confirm the certificate is added correctly and note the validity period.
- If you use use the resource mailbox but you want to restrict the Mail.ReadWrite permission to only that mailbox, you currently have 2 options.
- Create the primary app registration with only the Calendars.ReadWrite permission, and repeat the process to create a separate app registration for accessing the resource mailbox with Calendars.ReadWrite and Mail.ReadWrite permissions. Use the same certificate credential for both app registrations. Restrict access to specific mailboxes using Application Access Policies. Refer to Application Access Policies (legacy) | Microsoft for more information, but note this approach will become deprecated.
- Use RBAC for applications to add the Mail.ReadWrite permission for the resource mailbox to the primary app registration. Refer to Role Based Access Control for Applications in Exchange Online | Microsoft for more information.
Configuration in Archibus
The configuration for connecting the Archibus Reservations application to Exchange Online via Microsoft Graph API is defined in WEB-INF/config/context/applications/reservations.properties.
The link between individual room mailboxes in Exchange and rooms in Archibus is configured in the rm_config table in the Archibus database.
Setting up reservations.properties
The configuration file WEB-INF/config/context/applications/reservations.properties contains settings for different calendar integrations. This section identifies and explains the settings that apply for integration with Exchange Online via Graph API.
Step 1. Set your deployment option
Set one of the following deployment options in the reservations.configurationFile property. This property defines which integration is enabled.
- For Exchange integration via Graph API without the classic Archibus Outlook Plugin, set:
reservations.configurationFile=classpath:com/archibus/app/reservation/graph-integration-context.xml - For Exchange integration via Graph API combined with the classic Archibus Outlook Plugin, set:
reservations.configurationFile=classpath:com/archibus/app/reservation/graph-integration-context-remoting.xml
Step 2. Set the common properties for Exchange integration
The following properties are used for Exchange integration via Exchange Web Services as well. Their usage remains the same between integrating via EWS or via Graph API.
| Property | Description |
|---|---|
|
exchange.linkedDomains |
Email Domains on the connected Exchange in a comma-separated list. Archibus will only attempt to connect to Exchange for email addresses that match one of the specified domains. When the property is empty, Archibus will attempt to connect to Exchange for all email addresses, including external attendees. This speeds up retrieval of free/busy information and meeting creation by external users, when applicable. Note: listing all subdomains is not required. For example, if you have |
|
exchange.impersonateUsers |
Enable or disable impersonation of users in Exchange to create / update / cancel meetings. When disabled
|
|
exchange.organizerAccount |
Email address of the Reservations organizer account. This account will be the meeting organizer in Exchange when
|
|
exchange.resourceAccount |
Email address for the Reservations resource account. Required for automated processing of meeting updates from Exchange by the Archibus Exchange Listener for rooms without a mailbox. This account will be added to all meetings created in Exchange via Archibus for rooms without a mailbox. |
|
exchange.resourceFolders |
Comma-separated list of folders to monitor in the resource account mailbox. Monitoring the inbox is usually sufficient. If you cannot disable the option "Delete Invitations and Responses that have been updated" on the resource account, you can add also monitor the deleteditems folder. Only applies to monitoring of the resource account, for reservations in rooms without a mailbox. |
|
exchange.enableListener |
Set to true/false to enable/disable the listener that processes meeting updates from Exchange. The Exchange Listener runs as a scheduled workflow rule. For clustered environments, only one instance should have the listener enabled. |
|
exchange.projectId
|
Identifier of the project defined in afm-projects.xml for which the Exchange Listener will connect to Exchange. The default value |
|
exchange.proxyServer exchange.proxyPort |
Proxy settings to connect to Microsoft Exchange and Entra ID. |
Step 3. Set the specific properties for Exchange integration via Graph API
The following properties are specific to configuring Exchange integration via Graph API.
| Property | Description |
|---|---|
|
exchange.graph.tenantId |
Exchange tenant id to connect to. This identifies the target tenant in Exchange Online. Found in the app registration details on Microsoft Entra ID. |
|
exchange.graph.clientId |
Primary client id used for calendar access via Graph API. Found in the app registration details on Microsoft Entra ID. |
|
exchange.graph.clientIdForResourceAccount
|
Secondary client id for accessing the resource account, if applicable depending on configuration in Microsoft Entra ID. Optional. If not specified, the primary client id is used for accessing the resource account. |
|
exchange.graph.pfxPath |
Location of the PKCS#12 file used for authentication with Microsoft Entra ID. |
|
exchange.graph.pfxPassword |
Password for the PKCS#12 file used for authentication with Microsoft Entra ID. |
|
exchange.graph.sync.maxDaysAhead |
Maximum number of days ahead to sync a room calendar. When synchronization is (re)started for a room, Archibus sets the end of the synchronization range this number of days in the future. Archibus then synchronizes all events on the room calendar from today until the end of the synchronization range. The synchronization range is not modified until synchronization for the room is restarted. |
|
exchange.graph.sync.minDaysAhead
|
Minimum number of days ahead to sync a room calendar. When the end date of the synchronization range for a room is less than this number of days from today, Archibus restarts synchronization for that room. Default value: 3600 days (nearly 10 years). Combined with a maximum of 4000 days, this means Archibus will restart synchronization for a room every 400 days. |
|
exchange.listenerTimeLimit |
Limit a single listener run to a number of seconds. When the listener runs on a single server, set this to the default value -1, meaning no limit. When the Exchange Listener scheduled WFRs can run on multiple nodes, set this to a value smaller than the repeat interval to avoid running multiple listener instances simultaneously. For more information, see Exchange integration via MS Graph API | Running the listener in a distributed setup with Quartz scheduler | Microsoft. |
|
exchange.graph.scope |
Target scope for the tokens acquired from Microsoft Entra ID. Default value for public cloud: |
|
exchange.graph.authorityHost |
Microsoft Entra endpoint to acquire tokens from. Default value for public cloud: |
|
exchange.graph.endpoint |
Graph API endpoint, including version number. Default value for public cloud: |
Linking rooms in Exchange and Archibus
Prerequisite: create and configure room mailboxes in Exchange
Before linking a room in Exchange with Archibus, create the room in Exchange and set its calendar processing to AutoUpdate. Example powershell commands:
New-Mailbox -Name hq-17-127 -Room
Get-User hq-17-127 | Set-CalendarProcessing -AutomateProcessing AutoUpdate
More info about creating and configuring room mailboxes in Exchange is available at Exchange: Create Room Mailboxes.
Activate the link between a room in Exchange and in Archibus
The link between a room in Archibus and a room in Exchange is established by entering the room’s email address in the Room Mailbox field rm_config.mailbox_id in the Archibus database. You can enter it via the Archibus Web Central view specified below, via SmartClient, via data transfer, or directly via the database.
Web Central Task: Define Room Configurations
Task File: ab-rr-rm-config.axvw
Path: Workplace Services/Reservations/Background Data/Define Room Configurations
If the Exchange Listener is enabled, it will automatically start syncing the room calendar a few minutes after entering the email. Note the initial sync of a room calendar takes time and blocks syncing other room calendars.
Explanation of a room’s calendar sync state
After a room is linked with a room mailbox in Exchange, Archibus will track the synchronization status in the rm_config.calendar_sync_state field. For Graph API integration, this field contains a JSON object with the following properties.
| Property | Description |
|---|---|
|
mailbox_id |
Email address of the room in Exchange When Archibus reads the sync state from its database, it checks that the mailbox_id in the sync state matches the rm_config.mailbox_id. Otherwise Archibus restarts the sync. |
|
date_from |
Start date of the current sync range |
|
date_to |
End date of the current sync range |
|
delta_link |
Link to continue syncing later - returned by Graph API if there are no more pending events |
|
next_link |
Link to continue syncing immediately - returned by Graph API if more events are waiting to be synced, not returned in the last query |
|
last_error |
Date and time of the last error that occurred trying to sync this room. See |
Disable the link between a room in Exchange and in Archibus
If you want Archibus to stop syncing a specific room, clear the rm_config.mailbox_id field in the Archibus database. From the moment the field is cleared, Archibus will no longer include the room mailbox in any meetings created via Archibus for that room. And once the listener completes it current synchronization run, it will no longer sync that room’s calendar from Exchange.
Troubleshooting Graph API connectivity
Connectivity issues are normally logged at error or warn level in archibus.log. To log all messages exchanged between Archibus and Graph API, you can enable trace level logging for package com.archibus.app.reservation.graph.helpers in WEB-INF/config/context/logging/log4j2.xml.
<Logger name="com.archibus.app.reservation.graph.helpers" level="trace"/>
Or as a minimum, enable trace level logging for the 2 classes GraphServiceClientBuilder and GraphLoggingInterceptor in that package.
Scheduled Workflow Rules for monitoring meetings in Exchange
Archibus monitors meetings in Exchange via 2 scheduled WFRs: one for monitoring the resource account and one for monitoring room calendars.
Archibus queries Graph API every 5 minutes (300 seconds) by default. This is the repeat interval of the scheduled WFRs, so it can be customized. The start time of the WFR that monitors room calendars is 2 minutes after the WFR that monitors the resource account, so they don’t run at exactly the same time.
In the default configuration, only one server node should be running scheduled WFRs. The Graph API listener WFRs use an in-memory locking mechanism to avoid starting another instance when the previous instance has not completed yet. See
Exchange integration via MS Graph API | Running the listener in a distributed setup (below) if scheduled WFRs run on multiple nodes in your deployment.
Monitoring the resource account (for rooms without mailbox)
Rule ID: AbWorkplaceReservations-graphResourceAccountListener
High level processing flow
The WFR checks for items in the resource account inbox. It retrieves at most 250 messages in a single query. Messages are processed one by one. After processing all messages in a folder, the WFR proceeds with processing all messages in the next monitored folder. When all folders are processed, the WFR ends. Archibus restarts the WFR at the beginning of the next interval.
Error handling
When an error occurs while processing an item, the error is logged at info level in archibus.log, the item is skipped and processing continues with the next item.
When an error occurs while retrieving items to process, this error will end the WFR and Archibus will log it at error level in archibus.log. Archibus will restart the WFR the next interval.
Monitoring room calendars
Rule ID: AbWorkplaceReservations-graphRoomCalendarListener
High level processing flow
The WFR starts by checking which rooms are linked to a room mailbox and parses their sync state. Then it runs delta queries on the calendar folder of each room to sync changes. Archibus retrieves at most 100 events per room in every query. Every room calendar with changes is rechecked until no more changes are found. Once all rooms are synced, the WFR ends. Archibus restarts the WFR at the beginning of the next interval.
Batching of sync requests
Archibus combines up to 20 delta queries in a single Graph API batch request. This is the maximum number of queries that can be combined in a single batch request towards Graph API. Batching requests this way reduces the number of requests to Graph API.
Initial syncs and syncs from a next_link are processed via individual requests, because they are expected to return many events in a single query.
Note: the maximum page size of 100 events is set per room, regardless of whether the request is executed individually or as part of a batch. Thus the response for a batch request combining 20 rooms could theoretically contain up to 2000 events.
Error handling
When an error occurs on an initial sync or a sync using a next_link, the error is logged as a warning in archibus.log and the date and time of the error is written in the room’s sync state. Archibus will wait for at least 1 hour after such an error before trying to sync that room again.
When an error occurs on sync using a delta_link, the error is also logged and the date and time of the error is also written in the sync state. The sync is retried on the next run without additional delay.
Graph API can return a specific error code HTTP 420 Gone to indicate a delta link or next link is no longer valid. When this error is detected, Archibus restarts the sync for that room.
Running the listener in a distributed setup
In a setup where scheduled WFRs are executed on multiple nodes, a time limit should be configured for a single run of the listener to avoid running multiple listeners simultaneously. The time limit must be smaller than the repeat interval for the Graph API listener WFRs, so the listener will stop on one node before it starts on another node.
The time limit can be configured in reservations.properties, in the exchange.listenerTimeLimit property. The time limit is disabled using the value -1 by default, but for a distributed setup where the repeat interval of the scheduled WFRs is 300 seconds (5 minutes, the default), a valid setting for the time limit could be 240 seconds.
The listener for the resource account mailbox checks the time limit after processing each message.
The listener for room calendar monitoring checks the time limit after processing all events for a room returned in response to a single query and updating the sync state for that room. If the time limit is not exceeded, the listener proceeds with processing the events for the next room and updating its sync state before checking the time limit again.
