cancel
Showing results for 
Search instead for 
Did you mean: 

Register custom content model using REST API

nenad982
Champ on-the-rise
Champ on-the-rise

Hello,

we are working with Alfresco v6.1 and we have to register a new custom content model using only remote access to the repository (no access to Repository/Data Dictionary/Models in Share, no access to Model Manager in Share or registration using Spring bean is possible).

We created a custom content model and we tried to use the:

POST api/cmm/upload

web script which was used by Model Manager feature in Admin Console from Share but we have a problem because we have <mandatory-aspects> tag in the model:

https://issues.alfresco.com/jira/browse/MNT-18953

Does anybody know how we can upload and register new custom content model using only remote API (CMIS API, REST)?

Thank you...

2 REPLIES 2

abhinavmishra14
World-Class Innovator
World-Class Innovator

This is not ideally the use case always and it is preffered approach to deploy the models programatically via spring beans.

But there is a workaroud for your use case, You can upload your models to Data Dictionary/Models folder using upload (/api/upload) REST API. 

You need to find the nodeRef of the Models folder via search which will be used for uploading the file via upload api.

Here is an example to get the nodeRef of Models folder using an ootb approach (However its up to you to choose how to get the nodeRef):

GET: http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/browser/root/Data Dictionary/Models?cmisselector=object
This will return a json response containing the metadata of Models folder which will have the nodeRef. You can parse the json and get the nodeRef from there. Here is the snippet of metadata you would be parsing.
 
"alfcmis:nodeRef": {
            "id": "alfcmis:nodeRef",
            "localName": "nodeRef",
            "displayName": "Alfresco Node Ref",
            "queryName": "alfcmis:nodeRef",
            "type": "id",
            "cardinality": "single",
            "value": "workspace://SpacesStore/a9a9f477-5c57-11dc-ad6c-5136d620963c"
        }
Now you got the nodeRef of the Models folder, you can fire upload api to upload the file to Data Dictionary/Models folder.
 
POST127.0.0.1:8080/alfresco/service/api/upload 
 
RequiredParams: filedata and destination
 
Here filedata param holds the actual file and destination holds the nodeRef. 
 
Example: 
filedata : example-model.xml
destination : workspace://SpacesStore/a9a9f477-5c57-11dc-ad6c-5136d620963c
 
For more details on upload api see here: https://docs.alfresco.com/5.0/references/RESTful-UploadUploadPost.html (document links to version 5.0, but it works in all versions). 
 
Once model xml file is uploaded in Models folder, it will be inactive by default , You would need to activate it. 
 
 
Pass the POST request with following params:
 
Required params:
 
t= /admin/admin-repoconsole
repo-cmd = activate model example-model.xml 

Note, for this request you would need to pass the CSRF token param also in the request or disable the CSRF validation for this request path. Look at this doc if you need more details: https://docs.alfresco.com/6.1/concepts/csrf-policy.html

There may be better ways to achieve this use case, someone else can provide additonal options. 

~Abhinav
(ACSCE, AWS SAA, Azure Admin)

stefanwalbers
Champ in-the-making
Champ in-the-making

I achieved importing a custom content model through CMIS.
I used Javascript (NodeJs) code and the cmis npm package: https://www.npmjs.com/package/cmis
Alfresco does not support (did not implement) the createType method.
But you can create an "cm:dictionaryModel" with xml content in folder /Data Dictionary/Models to create a custom model (CMIS document type).
By setting the 'cm:modelActive' to true, the model is set active.

This is the code I use:

const cmis = require('cmis');
const fs = require('fs');

// Establish a connection with Alfresco and load the repository information
this.afSession = new cmis.CmisSession(afConfig.url);
this.afSession.setCredentials(afConfig.username, afConfig.password);
await this.afSession.loadRepositories();
// Find content model on file system and import into Alfresco
const contentModelNameWithExt = `${contentModelName}.xml`;
const filename = `./data/content-model/${contentModelNameWithExt}`;
const contentModelData = Buffer.from(fs.readFileSync(filename));
try {
  const modelsFolder = await this.afSession.getObjectByPath(`/Data Dictionary/Models`);
  const modelsFolderId = modelsFolder.succinctProperties['cmis:objectId'];
  const queryResponse = await this.afSession.query(
	`SELECT cmis:versionSeriesId FROM cm:dictionaryModel WHERE cmis:name='${contentModelNameWithExt}' AND IN_FOLDER('${modelsFolderId}')`
  );
  if (queryResponse && queryResponse.results.length === 1) {
	console.log(`Updating in Alfresco: ${contentModelNameWithExt}`);
	const modelId = queryResponse.results[0].succinctProperties['cmis:versionSeriesId'];
	await this.afSession.setContentStream(modelId, contentModelData, true, contentModelNameWithExt);
	await this.afSession.updateProperties(modelId, { 'cm:modelActive': true });
  } else {
	console.log(`Creating in Alfresco: ${contentModelNameWithExt}`);
	await this.afSession.createDocument(modelsFolderId, contentModelData, {
	  'cmis:name': contentModelNameWithExt,
	  'cmis:objectTypeId': 'D:cm:dictionaryModel',
	  'cm:modelActive': true,
	});
  }
}