WEB/REST services

By default, beCPG offers an HTTP REST API service named Remote API which enables to:

  • import data of an entity in xml format,
  • export data of an entity in xml format according to criteria (e.g. I wish to get all validated and active products at a specific date MM/DD/YYYY).

REST service enables to create new interfaces with third party softwares such as ERP. By entity, we mean products, clients, suppliers, projects... with all their information and, these, dynamically and without development.

The exchange interface can be realized by a third party tool to:

  • manage exchanges,
  • manage flows (for example, with transformation rules on list of values),
  • handle errors.

That third party tool uses the Remote API to import and export data in beCPG. 2 ways of approach are possible:

  • the client has a third party tool capable of creating the interface,
  • the client wishes that beCPG puts in place a third patty tool to create the interface

In addition to that, most APIs are accessible by REST services:

  • CRUD operations, Create/Read/Update/Delete
  • formulation
  • document generation
  • versions and reports recovery
  • etc...

API beCPG

The remote API of beCPG provides the following URL REST:

<url>/becpg/remote/entity/list?path={path}</url>
<url>/becpg/remote/entity/list?query={query}&maxResults={maxResults}</url>
<url>/becpg/remote/entity?nodeRef={nodeRef}</url>
<url>/becpg/remote/entity?path={path}</url>
<url>/becpg/remote/entity?query={query}</url>
<url>/becpg/remote/formulate?nodeRef={nodeRef}</url>
<url>/becpg/remote/formulate?path={path}</url>
<url>/becpg/remote/formulate?query={query}</url>
<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}</url>
<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}&locale={locale}</url>
<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}&locale={locale}&format={format}</url>

POST/GET/PUT/DELETE methods enable to add, find, update and delete entites in the PLM (products, clients, suppliers, etc...)

Listing entities

The list of entities is obtained with LIST requests and can be filtered with advanced research criteria (last modified product since "specific date").

<url>/becpg/remote/entity/list?path={path}</url>
<url>/becpg/remote/entity/list?query={query}&maxResults={maxResults}&fields={fields}</url>
<url>/becpg/remote/entity/list?path={path}&maxResults={maxResults}&fields={fields}</url>

The syntax to search is Lucene FTS Alfresco 1 and is available here: http://docs.alfresco.com/5.0/concepts/rm-searchsyntax-intro.html

1. For more information, please read the part on the creation of Lucene requests which is available here documentation

Example of request to find a finished product with its ERP code:

+TYPE:"bcpg:finishedProduct" AND +@bcpg\\:erpCode:"codeErp" AND -ASPECT:"bcpg:compositeVersion"
(-ASPECT:"bcpg:compositeVersion" allows to ignore old versions)

Corresponding URL:

http://localhost:8080/alfresco/service/becpg/remote/entity?query=%2BTYPE%3A%22bcpg%3AfinishedProduct%22%20AND%20%2B%40bcpg%5C%3AerpCode%3A%22codeErp%22%20AND%20-ASPECT%3A%22bcpg%3AcompositeVersion%22

To get the encrypted URL (in the firefox console):

encodeURIComponent('+TYPE:"bcpg:finishedProduct" AND +@bcpg\\:erpCode:"codeErp" AND -ASPECT:"bcpg:compositeVersion"')

The maxResults parameter enables to specify a number of results (-1 to get all results)
The fields parameter enables to specify fields or associations which need to be extracted in the results. The format paramater enables to specify the output format

  • format=xml (by default)
  • format=json (json format)
http://localhost/alfresco/service/becpg/remote/entity/list?query=%2BTYPE%3A%22bcpg%3AfinishedProduct%22&fields=bcpg:legalName,bcpg:clients

Examples:

Example of a script script bash allowing to directly recover a list of entities in xml format:

#!/bin/sh

export REMOTE_SERVER=http://localhost:8080/alfresco/service/becpg/remote/entity
export REMOTE_USER=admin
echo "Enter password"
read REMOTE_PASSWORD=

# Recovering the list of nodes:

wget --quiet --http-user=$REMOTE_USER --http-password=$REMOTE_PASSWORD  --header=Accept-Charset:iso-8859-1,utf-8 --header=Accept-Language:en-us -O list.xml $REMOTE_SERVER/list 
count=1

#We go through the list
while [ -n "$nodeRef" -o $count = 1 ]
   do
      nodeRef=`cat list.xml | xpath -q -e //*[$count]/@nodeRef | sed s/nodeRef=//g |sed s/\"//g`
      echo "\Obtention du noeud $nodeRef"; 
      #Each node is saved
      wget --quiet --http-user=$REMOTE_USER --http-password=$REMOTE_PASSWORD  --header=Accept-Charset:iso-8859-1,utf-8 --header=Accept-Language:en-us -O entity_$count.xml $REMOTE_SERVER?nodeRef=$nodeRef
      count=$((count+1))
done

Getting an entity

To get entities, two REST services are available:

Remote API using the following TYPE GET requests

<url>/becpg/remote/entity?nodeRef={nodeRef}&format={format}</url>
 <url>/becpg/remote/entity?path={path}&format={format}</url>
 <url>/becpg/remote/entity?query={query}&format={format}</url>
 <url>/becpg/remote/entity?nodRef={nodeRef}&lists={lists}&fields={fields}</url>
 <url>/becpg/remote/entity?path={path}&lists={lists}&fields={fields}</url>
 <url>/becpg/remote/entity?query={query}&lists={lists}&fields={fields}</url>

Format enables to modify the XML format of the response:

  • format=xml (by default)
  • format=json (json format)
  • format=xml_all (contains details of all associations)
  • format=xml_excel (adapted format for use as datasource in excel)
  • format=xml_light (that format does not contain child associations)
  • format=xsd (that format enables XSD extraction)
  • format=xsd_excel (that format allows XSD extraction for excel)

You can also get additional filter parameters. There are 3 types of filer:

  • filtering properties : only includes listed properties (fields=bcpg:legalName)
  • filtering associations : only includes listed associations (fields=bcpg:clients)
  • filtering lists : only includes listed lists (lists=bcpg:compoList)

Also, you can extract the properties of an association by putting in the fields parameter, the association's names and their properties, by respecting the following format : ASSOC_Name1|PROP_Name1,ASSOC_Name1|PROP_Name2.

Example

http://localhost/alfresco/service/becpg/remote/entity?nodeRef=workspace://SpacesStore/9b4dd09a-afaa-41ec-84eb-db062146975c&fields=bcpg:legalName,bcpg:clients,bcpg:compoListProduct|bcpg:productState&lists=bcpg:compoList

API report

<url>/becpg/report/datasource?nodeRef={nodeRef}</url>

The API report reworks data and enables to get an easier to use XML. Formulation data, tares, costs and multi levels lists are directly usable. That API is recommended if you wish to extract data from a product.

Updating an entity

The update and creation of an entity is done by using PUT (creation) and POST (update) methods with the following requests:

<url>/becpg/remote/entity?nodeRef={nodeRef}</url>
<url>/becpg/remote/entity?path={path}</url>
<url>/becpg/remote/entity?query={query}</url>    

The content of a request must contain an XML in the by default format of the remote API. It is not necessary to have all fields. Only present fields are created/updated.

Example:

Example of a CURL request used to create an entity.

curl --user username:password -H "Content-Type: application/xml"  -X PUT --data @sample-entity.xml  http://localhost/alfresco/service/becpg/remote/entity

Example of XML enabling to create a project sample-entity.xml

<?xml version='1.0' encoding='UTF-8'?>
<pjt:project xmlns:pjt="http://www.bcpg.fr/model/project/1.0" path="/app:company_home/st:sites/cm:simulation/cm:documentLibrary"
    type="node" name="Sample project">
    <pjt:projectPriority type="d:int"><![CDATA[2]]></pjt:projectPriority>
    <cm:description xmlns:cm="http://www.alfresco.org/model/content/1.0" type="d:mltext" fr="Texte - texte -texte"><![CDATA[Texte - texte -texte]]></cm:description>
    <cm:name xmlns:cm="http://www.alfresco.org/model/content/1.0" type="d:text"><![CDATA[Sample project]]></cm:name>
    <cm:title xmlns:cm="http://www.alfresco.org/model/content/1.0" type="d:mltext" fr="Sample project"><![CDATA[Sample project]]></cm:title>
    <pjt:projectState type="d:text"><![CDATA[Planned]]></pjt:projectState>
</pjt:project>

You can also use the JSON format which is the recommended format for creating and updating from version 3.2. This format has the advantage of allowing certain fields to be updated beforehand.

curl --user username:password -H "Content-Type: application/json"  -X PUT --data @sample-json.json  http://localhost/alfresco/service/becpg/remote/entity?format=json

For each element, the root defines the keys on which to search for an element and attributes makes it possible to specify the values ​​to update.

Example:

{
    "entity": {
        "bcpg:erpCode": "TEST-REMOTE001",
        "cm:name":"Test remote",
        "type": "bcpg:finishedProduct",
        "params" : {
            "replaceExistingLists" : true
        },
        "attributes": {
                 "bcpg:legalName_en": "Legal Produit fini EN",
                 "bcpg:legalName": "Legal Produit fini FR",
                 "bcpg:clients": [
                        {
                            "bcpg:code": "C1"
                        },
                        {
                            "bcpg:code": "C2"
                        }
                    ],

                  "bcpg:productHierarchy2": {
                    "path": "/app:company_home/cm:System/cm:ProductHierarchy/bcpg:entityLists/cm:finishedProduct_Hierarchy",
                    "bcpg:lkvValue": "Pizza",
                    "type": "bcpg:linkedValue"
                }  
            },
        "datalists": {
          "bcpg:allergenList": [
                {
                    "bcpg:allergenListAllergen": {
                         "bcpg:charactName": "Allergen 4"
                    },
                    "attributes": {
                        "bcpg:allergenListVoluntary": false,
                        "bcpg:allergenListInVoluntary": true
                    },
                    "type": "bcpg:allergenList"
                }
            ],
          "bcpg:compoList": [
                {
                     "bcpg:compoListProduct": {
                            "bcpg:code": "LSF411"
                     },
                    "attributes": {
                        "bcpg:compoListQtySubFormula": 15,
                        "bcpg:compoListUnit": "kg"
                    }
                },
                 {
                     "bcpg:compoListProduct": {
                            "bcpg:erpCode": "TEST1"
                     },
                    "attributes": {
                        "bcpg:compoListQtySubFormula": 10,
                        "bcpg:compoListUnit": "kg"
                    }
                }
        ]
        }
    }
}

The params attribute allows you to pass certain parameters to the API:

  • replaceExistingLists (false): Allows you to delete the lines in the lists not present in the JSON file

Update of a multi-language property

Since 2.2.X PLM version, you can import mltext fields in multi-languages, for example import the title property:

<cm:title xmlns:cm="http://www.alfresco.org/model/content/1.0" type="d:mltext" de="Beispielprojekt" fr="Exemple de projet" en="Sample project"><![CDATA[Sample project]]></cm:title>

In json, the property is followed by an underscore and the language code.

"bcpg:legalName_en_US": "value for US"    

Update Associations

An association can be identified by its nodeRef, name, code (beCPG/ERP) and path.

N.B: Before 2.2.X PLM version, you are supposed to provide a fake nodeRef.

Example :

<pjt:projectEntity type="assoc"><bcpg:finishedProduct type="node" name="ENTITY_NAME" code="BCPG_CODE" nodeRef="FAKE_NODEREF"></bcpg:finishedProduct></pjt:projectEntity>

Deleting an entity

the remote API enables to delete entities using the following TYPE DELETE requests:

<url>/becpg/remote/entity?nodeRef={nodeRef}&format={format}</url>
 <url>/becpg/remote/entity?path={path}&format={format}</url>
 <url>/becpg/remote/entity?query={query}&format={format}</url>

Example of a script enabling to delete multiple entities (all materials)

#!/bin/sh
export REMOTE_SERVER=http://localhost/alfresco/service/becpg/remote/entity
export REMOTE_USER=admin
echo "Enter password"
read REMOTE_PASSWORD=

if [ $# -ne 1 ]
   then
                #LIST
                wget --quiet --http-user=$REMOTE_USER --http-password=$REMOTE_PASSWORD  --header=Accept-Charset:iso-8859-1,utf-8 --header=Accept-Language:en-us -O list.xml $REMOTE_SERVER/list?query=%2BTYPE%3A%22bcpg%3ArawMaterial%22%20-ASPECT%3A%22sys%3Atemporary%22%20-ASPECT%3A%22bcpg%3AentityTplAspect%22
                count=1

                while [ -n "$nodeRef" -o $count = 1 ]
                do
                   nodeRef=`cat list.xml | xpath -q -e //*[$count]/@nodeRef |sed s/nodeRef=//g|sed s/\"//g|sed s/\:\\\///g| xargs`

                 echo "DELETE ${nodeRef}";
                 curl --user $REMOTE_USER:$REMOTE_PASSWORD -X $REMOTE_SERVER?nodeRef=$nodeRef
                 count=$((count+1))
                done

      exit 0
fi

Download reports

The Remote API makes it easier to download reports files using the following endpoints:

<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}</url>
<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}&locale={locale}</url>
<url>/becpg/remote/report?nodeRef={nodeRef}&tplNodeRef={tplNodeRef}&locale={locale}&format={format}</url>

Where:

  • nodeRef being the product nodeRef
  • tplNodeRef being the report template nodeRef
  • locale being the language code
  • format being the report format which can be (PDF, XLSX, DOCX, ODT, ZIP)

Also, you can download customizable reports using POST method and pass in the body parameters as a JSON object

Example: Download custom report using CURL

#!/bin/sh

export LOCAL_SERVER=http://localhost/alfresco/service/becpg/remote/report
export LOCAL_USER=admin
export LOCAL_PASSWORD=becpg

curl --user $LOCAL_USER:$LOCAL_PASSWORD -H "Content-Type: application/json"  -X POST --data @params.json  "$LOCAL_SERVER?nodeRef=$1&tplNodeRef=$2" > report.pdf

Where $1 represents the product id and $2 represents the report template id.

  • params.json file contains a JSON object :

      {
      iterationKey : "bcpg:plant",
      params : [{
      id: "param1",
      prop : "cm:name" 
      }],
      prefs : {
      assocsToExtract : "bcpg:plants,bcpg:suppliers,bcpg:storageConditionsRef,bcpg:precautionOfUseRef,bcpg:nutListNut",
      assocsToExtractWithDataList : "bcpg:compoListProduct" 
      },
      nameFormat : "{entity_cm:name}- {report_cm:name}  - {locale} - {param1} ",
      titleFormat : " {report_cm:name} -  {locale} - {param1}" 
      }
    

For more details on report customization using report parameters, please read Extractor - Part 1

JAVA Utility

beCPG also provides a JAVA utility library facilitating calls to the REST service. That library can be compiled from the source code:

https://www.becpg.fr/hg/becpg-tools (read-only:read-only)

Or in jar: becpg-tools.jar

Below is an example of class java allowing to recover the list of entities and then replicate each entity.

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.HttpClient;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import fr.becpg.tools.http.GetEntityCommand;
import fr.becpg.tools.http.ListEntitiesCommand;

public class SampleInstanceImporter {
    private static Log logger = LogFactory.getLog(InstanceImporter.class);
    private String serverUrl;
    public InstanceImporter(String serverUrl) {
        super();
        this.serverUrl = serverUrl;
    }
    public void loadEntities(String query, HttpClient client) throws Exception {
        ListEntitiesCommand listEntitiesCommand = new ListEntitiesCommand(serverUrl);
        try (InputStream entitiesStream = listEntitiesCommand.runCommand(client, query)) {
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            domFactory.setNamespaceAware(true); // never forget this!
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document doc = builder.parse(entitiesStream);
            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();
            int count = 1;
            String nodeRef = null;
            while ((nodeRef = (String) xpath.evaluate("//*[" + count + "]/@nodeRef", doc, XPathConstants.STRING)) != null && nodeRef.length() > 0) {
                count++;
                try {
                    loadEntity(client, nodeRef);
                } catch(Exception e){
                    logger.error("Invalid Xml for "+nodeRef+" skipping node");
                    if(logger.isDebugEnabled()){
                        logger.debug(e,e);
                     }
                 }
            }
         }
     }
    private void loadEntity(HttpClient client, String nodeRef) throws Exception {
        logger.info("Import nodeRef:" + nodeRef);
        GetEntityCommand getEntityCommand = new GetEntityCommand(serverUrl);
        try (InputStream entityStream = getEntityCommand.runCommand(client, nodeRef)) {
             //Parse XML and do ETL transformation
         }
    }
    public String buildQuery(Date lastImport) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        String dateRange = "MIN";
        if (lastImport != null) {
            dateRange = dateFormat.format(lastImport);
         }
        logger.info("Import from :[ " + dateRange + " TO MAX ]");
        String query = "@cm\\:created:[%s TO MAX] OR @cm\\:modified:[%s TO MAX]";
        return  String.format(query, dateRange, dateRange);
    }
       public static void main(String[] args) throws Exception {
        InstanceImporter remoteETLClient = new InstanceImporter("http://localhost:8080/alfresco");
        DefaultHttpClient httpclient = new DefaultHttpClient();
        UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password");
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
        httpclient.setCredentialsProvider(credsProvider);
        try {
                Date lastImportDate = null; // Date de dernier import
            remoteETLClient.loadEntities(remoteETLClient.buildQuery(lastImportDate), httpclient);
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
 }


}

Sample REST Requests

GET List Finished Product Sample

curl --location --request GET 'https://$server/alfresco/service/becpg/remote/entity/list?query=+TYPE:"bcpg:finishedProduct"&format=json&fields=bcpg:legalName,bcpg:clients'

PARAMS

| query | +TYPE:"bcpg:finishedProduct" | | format | json | | fields | bcpg:legalName,bcpg:clients |

GET List of products by last modified Sample

curl --location --request GET 'https://$server/alfresco/service/becpg/remote/entity?format=json&query=(@cm\:created:[2020-02-10 TO MAX] OR @cm\:modified:[2020-02-10 TO MAX]) AND ( TYPE:"bcpg:finishedProduct" OR TYPE:"bcpg:semiFinishedProduct")

PARAMS

| query | (@cm\:created:[2020-02-10 TO MAX] OR @cm\:modified:[2020-02-10 TO MAX]) AND ( TYPE:"bcpg:finishedProduct" OR TYPE:"bcpg:semiFinishedProduct") | | format | json |

Get Entity allergen list Sample

curl --location --request GET 'https://$server/alfresco/service/becpg/remote/entity?format=json&query=+@bcpg\:erpCode:"TEST1"&lists=bcpg:allergenList&fields=bcpg:allergenListAllergen|bcpg:allergenCode,bcpg:allergenListVoluntary,bcpg:allergenListInVoluntary'

PARAMS

| query | @bcpg\:erpCode:"TEST1"| | format | json | | lists | bcpg:allergenList | | fields | bcpg:allergenListAllergen|bcpg:allergenCode,bcpg:allergenListVoluntary,bcpg:allergenListInVoluntary |

Get Compo List Sample

curl --location --request GET 'https://$server/alfresco/service/becpg/remote/entity?format=json&query=+@bcpg\:erpCode:"TEST1"&lists=bcpg:compoList&fields=bcpg:compoListProduct,bcpg:compoListQtySubFormula,bcpg:compoListUnit'

PARAMS

| query | @bcpg\:erpCode:"TEST1"| | format | json | | lists | bcpg:compoList | | fields | bcpg:compoListProduct,bcpg:compoListQtySubFormula,bcpg:compoListUnit |

GET Get Entity

curl --location --request GET 'https://$server/alfresco/service/becpg/remote/entity?format=json&query=+@bcpg\:erpCode:"TEST1"'

PARAMS

| query | @bcpg\:erpCode:"TEST1"| | format | json |

API Alfresco

Alfresco also provides API REST. For more information on that please use the following link:

https://docs.alfresco.com/5.2/pra/1/topics/pra-welcome.html

and

https://api-explorer.alfresco.com/api-explorer/

results matching ""

    No results matching ""