Skip to main content

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'
info

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:

ProjectConfiguration.java
public record ProjectConfiguration(String projectDocRef, String subProjectDocRef) {}
CustomClientFactory.java
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}}
ParamsRemarks
grant_typeuse "password" to instruct TMT to issue the access and refresh token
IDP_BASE_URLlink to IDP
REALM_NAMErealm name of the desired tenant
CLIENT_IDclient id to authenticate
SECRETsecret to authenticate
USERNAMEusername in TMT app provided
PASSWORDpassword 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>
info

"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}}
ParamsRemarks
grant_typeUse "refresh_token" to instruct TMT to issue a new refresh token
IDP_BASE_URLlink to IDP
REALM_NAMErealm name of the desired tenant
CLIENT_IDclient id to authenticate
SECRETsecret to authenticate
refresh_tokenyour 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"
}