Accessing the TMT API
Before requesting TMT access, please ensure you have the following Demo tenant information Note: If you're using a different tenant, configuration values may vary. Please consult your TMT Administrator for accurate details.
TMT_BASE_URL: https://demo.a12-tmt.com/api
UAA_BASE_URL: https://demo.a12-tmt.com
IDP_BASE_URL: https://keycloak.a12-tmt.com/
REALM_NAME: demo
CLIENT_ID: uaa-auth-client
SECRET: please contact to TMT Administrator
USERNAME: your username
PASSWORD: your password
TMT offers flexibility in backend communication. You can either:
- Leverage the Data Services Client library offered by TMT.
- Implement your own custom communication solution.
Data services client
Data services Client allows you to connect to TMT server from any Java application without requiring manual HTTP communication coding. It also takes care of authentication, and renew the token for you.
How to setup Data service Client in your Java project
1. Import dependencies
Please use the correspoding version of Data Services Client and UAA Rest Client
implementation 'com.mgmtp.a12.dataservices:dataservices-client:37.0.1'
implementation 'com.mgmtp.a12.uaa:uaa-rest-client:8.0.2'
Access to the Data Services Client library is restricted to mgm and its partners. Other users must contact the TMT administrator to obtain the library.
2. Set up ClientFactory
Create a custom ClientFactory to add custom headers "Project-Id" and "Subproject-Id". These two headers are neccessary to send along every request when you are working in a project, see ProjectPermission to know more
Prepare these classes:
public record ProjectConfiguration(String projectDocRef, String subProjectDocRef) {}
public class CustomClientFactory {
private final RestRpcOperationsClient rpcOperationsClient;
private final RestDocumentClient restDocumentClient;
private final RestAttachmentClient restAttachmentAttachmentClient;
private CustomClientFactory(UAARestClientProperties uaaRestClientProperties, ClientConfiguration clientConfiguration, ProjectConfiguration projectConfiguration) {
ClientHttpRequestInterceptor headerInterceptor = (request, body, execution) -> {
request.getHeaders().add("Project-Id", projectConfiguration.projectDocRef());
if (StringUtils.isNotBlank(projectConfiguration.getSubProjectDocRef())) {
request.getHeaders().add("Subproject-Id", projectConfiguration.subProjectDocRef());
}
return execution.execute(request, body);
};
UAARestClientFactory uaaRestClientFactory = UAARestClientFactoryBuilder
.withConfiguration(uaaRestClientProperties)
.withInterceptors(headerInterceptor)
.withErrorHandlers(new ResponseErrorHandler[]{new DataServicesErrorHandler()})
.build();
RestPostConnector postConnector = uaaRestClientFactory.getPostConnector();
RestGetConnector getConnector = uaaRestClientFactory.getGetConnector();
RestDeleteConnector deleteConnector = uaaRestClientFactory.getDeleteConnector();
String baseUrl = clientConfiguration.getBaseUrl();
this.rpcOperationsClient = new RestRpcOperationsClient(baseUrl, postConnector);
this.restDocumentClient = new RestDocumentClient(baseUrl, getConnector);
this.restAttachmentClient = new RestAttachmentClient(baseUrl, getConnector, deleteConnector, postConnector);
}
static CustomClientFactory withConfigurations(UAARestClientProperties uaaRestClientProperties, ClientConfiguration clientConfiguration, ProjectConfiguration projectConfiguration) {
return new CustomClientFactory(uaaRestClientProperties, clientConfiguration, projectConfiguration);
}
public RestRpcOperationsClient getRpcOperationsClient() {
return rpcOperationsClient;
}
public RestDocumentClient getRestDocumentClient() {
return restDocumentClient;
}
public RestClient getRestAttachmentClient() {
return restAttachmentClient;
}
}
From CustomClientFactory instance, you can get provided clients to communicate with TMT server
UAARestClientProperties uaaRestClientProperties = new UAARestClientProperties();
uaaRestClientProperties.setAuthenticationType(AuthenticationType.OAUTH2);
UAARestClientAuthenticationProperties authConfiguration = new UAARestClientAuthenticationProperties();
authConfiguration.setUsername(USERNAME);
authConfiguration.setPassword(PASSWORD);
Oauth2Properties oauth2Properties = new Oauth2Properties();
Oauth2Properties.ConfidentialClientProperties confidentialClient = new Oauth2Properties.ConfidentialClientProperties();
confidentialClient.setClientSecret(SECRET);
confidentialClient.setIdpBase(new UrlProperty(IDP_BASE_URL));
confidentialClient.setRealmName(REALM_NAME);
confidentialClient.setClientId(CLIENT_ID);
confidentialClient.setLoginRelative(new UrlProperty("token"));
oauth2Properties.setConfidentialClient(confidentialClient);
authConfiguration.setOauth2(oauth2Properties);
uaaRestClientProperties.setAuthenticationConfiguration(authConfiguration);
uaaRestClientProperties.setUaaBase(new UrlProperty(UAA_BASE_URL));
uaaRestClientProperties.setAuthorizationHeaderName("Authorization");
ClientConfiguration clientConfiguration = new ClientConfiguration(TMT_BASE_URL);
String projectDocRef = "Project-dm/42";
String subProjectDocRef = "Project-dm/444"; // Leave empty in case of parent project
ProjectConfiguration projectConfiguration = new ProjectConfiguration(projectDocRef, subProjectDocRef);
CustomClientFactory clientFactory = CustomClientFactory.withConfigurations(uaaRestClientProperties, clientConfiguration, projectConfiguration);
rpcOperationsClient = clientFactory.getRpcOperationsClient();
restDocumentClient = clientFactory.getRestDocumentClient();
restAttachmentClient = clientFactory.getRestAttachmentClient();
You can then use the clients rpcOperationsClient, restDocumentClient and restAttachmentClient to communicate with TMT Backend via its built-in methods
Manual integration
If you prefer not to use our client library, you can manually set up communication with the TMT system. The following section outlines the authentication process
Authentication
For those who want to do the communication with TMT server by themselves (i.e. from Node application, ...)
1. Obtain JWT from keycloak
Make a POST request to keycloak to obtain access token and refresh token
POST {{IDP_BASE_URL}}/realms/{{REALM_NAME}}/protocol/openid-connect/token
Body request:
Content-Type: application/x-www-form-urlencoded
Parameter:
- grant_type=password
- client_id={{CLIENT_ID}}
- client_secret={{SECRET}}
- username={{USERNAME}}
- password={{PASSWORD}}
Params | Remarks |
---|---|
grant_type | use "password" to instruct TMT to issue the access and refresh token |
IDP_BASE_URL | link to IDP |
REALM_NAME | realm name of the desired tenant |
CLIENT_ID | client id to authenticate |
SECRET | secret to authenticate |
USERNAME | username in TMT app provided |
PASSWORD | password in TMT app provided |
Example: Obtain the access token
POST https://keycloak.q12-tmt.com/realms/demo/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=password
&client_id=uaa-auth-client
&client_secret=your-client-secret
&username=test.account
&password=Abcd1234!
Response
{
"access_token": "your-access-token",
"expires_in": 300,
"refresh_expires_in": 864000,
"refresh_token": "your-refresh-token",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "5eae5c8b-9b99-4a7d-b73d-b81964e98ff8",
"scope": "tenantId profile email"
}
Once you obtain the access_token, set it in the request header.
Authorization: BEARER <your-access-token>
"In the response above, you'll also receive the refresh token along with the expiration times for both the access and refresh tokens. This information can be used to manage the token renewal process effectively."
2. Prepare Project-Id and Subproject-id headers
These headers are required if you try to access the resources of a project (or sub project)
In case project, sub project id can be empty.
These ids are easily gotten from the TMT web app for a single project (sub project).
For example, if you want to access to project P_1. The below header is required:
Project-Id: P_1
3. Call TMT api with above headers
POST https://demo.q12-tmt.com/api/v2/rpc
Content-Type: application/json
Authorization: BEARER <your-access-token>
Project-Id: P_1
{
"jsonrpc": "2.0",
"id": "requestId123",
"method": "SOME_OPERATION",
"params": {
// params body
}
}
Refresh access token
When the access_token is going to be expired, you can call this api to obtain a new one
POST {{IDP_BASE_URL}}/realms/{{REALM_NAME}}/protocol/openid-connect/token
Body request:
Content-Type: application/x-www-form-urlencoded
Parameter:
- grant_type=refresh_token
- client_id={{CLIENT_ID}}
- client_secret={{SECRET}}
- refresh_token={{refresh_token}}
Params | Remarks |
---|---|
grant_type | Use "refresh_token" to instruct TMT to issue a new refresh token |
IDP_BASE_URL | link to IDP |
REALM_NAME | realm name of the desired tenant |
CLIENT_ID | client id to authenticate |
SECRET | secret to authenticate |
refresh_token | your refresh token |
Example: Obtain the refresh token
POST https://keycloak.q12-tmt.com/realms/demo/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&client_id=uaa-auth-client
&client_secret=your-client-secret
&refresh_token=your-refresh-token
Response
{
"access_token": "your-access-token",
"expires_in": 300,
"refresh_expires_in": 863473,
"refresh_token": "your-refresh-token",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "c5c046da-c181-4516-b242-3bb3fac41d52",
"scope": "tenantId profile email"
}