IBM Support

Technology preview: Using the FileNet Content Manager Content Services GraphQL API

Product Documentation


Abstract

Version 5.5.3 introduces a technology preview of the new Content Services GraphQL API, an intuitive API that enables the caller to create, retrieve, update, or delete resources. The API is ideal for web and mobile application development because it supports retrieving exactly the data you need with a single call.

Content

The Content Services GraphQL API provides a schema and an easy-to-understand query language system that simplifies application development for your Content Platform Engine. The API schema definition of types and fields matches Content Engine Java API object model closely, with necessary and desirable extensions for natural GraphQL developer consumption.

The technology preview feature set focuses on end-user runtime support, including the following operations:

  • Metadata discovery - ClassDescription, PropertyDescription, ChoiceList, and in V5.5.3 iFix 1, sub-ClassDescriptions
  • Document and Folder operations
    • Create, Read, Update, Delete (CRUD)
      • Change class
      • Update properties
      • Update securities - ACLs and ACEs, delegated permissions, role permissions
    • Object type-specific operations
      • Document - content upload and download, check in and check out, versioning, and in V5.5.3 iFix1, cancel document checkout
      • Folder - document file in and out
  • Search and query
    • Matches the Content Engine object model closely
    • Metadata search in V5.5.3, and full text search in V5.5.3 iFix1
  • Browse - folder hierarchy query of contained subfolders and documents
    • Containees can be obtained by selecting fields corresponding to similar Content Engine properties that return the containees of a folder.
    • Alternatively the SQL-like search API can be used to obtain containees with control over filter and ordering criteria. The search API also allows the results from multiple queries to be returned in a single contiguous result set, allowing subfolders, documents and even custom objects to be retrieved in one set.
    • Implicit support for columns and properties to return in the list based on data shaping
    • Paging, sorting, and so on
 

Getting started with the Content Services GraphQL API

The technology preview of the Content Services GraphQL API is available in a Docker container environment with a WebSphere® Liberty Application Server. You use the configuration files that are provided in the GitHub samples repository to configure your environment. You can use either Helm charts or a YAML file to deploy the API component.

The Content Services GraphQL API is packaged with the GraphiQL integrated development environment, which you can use to explore and interact with the API.

Use the following information to configure, deploy, and use the Content Services GraphQL API:

Preparing your environment for the Content Services GraphQL API container

Before you begin:

Deploy the FileNet Content Manager containers on an IBM Cloud Private or certified Kubernetes platform.

To prepare the Content Services GraphQL API container environment:

  1. Prepare the required persistent volume and persistent volume claim pairs for the deployment.

    You can create a YAML file with the specifications for your persistent volume or persistent volume claim, then use the kubectl command line with the YAML file to create the volume or volume claim.

    1. Create a pv-crs-cfgstore.yaml file for the crs-cfgstore persistent volume:
      apiVersion: v1
            kind: PersistentVolume
            metadata:
                 annotations:
                 name: crs-cfgstore
               spec:
                 accessModes:
                 - ReadWriteMany
                 capacity:
                   storage: 1Gi
                 nfs:
                   path: /crs/configDropins/overrides
                   server: 
                 persistentVolumeReclaimPolicy: Retain
      
      
    2. Save the file to a path in the cluster, for example, pv-crs-cfgstore.yaml.
    3. Use the kubectl command line to create the persistent volume with the specifications in the YAML file:
      kubectl apply -f pv-crs-cfgstore.yaml
    4. Set the following permission on the mount path folders:
      chgrp -R 0 /crs
      chmod -Rf g=u /crs
    5. Repeat the process, including permission settings, to create the crs-cfgstore persistent volume claim (PVC).
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: crs-cfgstore
        namespace: 
      spec:
        accessModes:
        - ReadWriteMany
         resources:
           requests:
             storage: 1Gi
         volumeName: crs-cfgstore-pv
      
      
    6. Repeat the process to create the crs-logstore persistent volume and persistent volume claim:

      crs-logstore PV:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        annotations:
        name: crs-logstore-pv
      spec:
        accessModes:
        - ReadWriteMany
        capacity:
          storage: 1Gi
        nfs:
          path: /crs/logs
          server: 
        persistentVolumeReclaimPolicy: Retain
      
      
      

      crs-logstore PVC:

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: crs-logstore
        namespace: 
      spec:
        accessModes:
        - ReadWriteMany
         resources:
           requests:
             storage: 1Gi
         volumeName: crs-logstore-pv
      
      
  2. Configure basic authentication by adding the LDAP configuration from the Content Platform Engine container to the configuration volume for Content Services GraphQL:
    1. In the configDropins/overrides directory for the Content Platform Engine, copy the LDAP.xml file.
    2. Paste the LDAP.xml file into the configDropins/overrides directory that you created for the Content Services GraphQL API container.

      Note: Users for the Content Services GraphQL API must be in the LDAP directory server that is specified in the LDAP.xml settings.

  3. Enable cross origin resource sharing by updating and adding the CORS.xml file to the configDropins/override directory for the Content Services GraphQL API container.

    Cross origin resource sharing (CORS) allows requests from a different URL to be processed by the REST service that is running in the API container, and allows responses to be returned.

    1. Copy the CORS.xml sample file from the following Github location:

      For containers delivered with IBM Cloud Pak for Automation:

      https://github.com/icp4a/cert-kubernetes/tree/19.0.2/CONTENT/configuration/ContentGraphQL/configDropins/overrides

      For containers delivered with FileNet Content Manager:

      https://github.com/ibm-ecm/container-samples/tree/5.5.3/ContentGraphQL/configDropins/overrides

    2. Save the copy to the configDropins/overrides directory for your Content Services container.
    3. Edit the allowedOrigins parameter and enter the client domain names.

      The domain names consist of HTTP (non-SSL) or HTTPS (SSL), and the client host name and port that matches the requests coming from the client. For example:

      <server>
      
          <!-- https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_cors.html -->
      
          <cors domain="/content-services-graphql"
      
              allowedOrigins="https://www.domain1.com:port, http://www.domain1.com:port, https://www.domain2.com:port, http://www.domain2.com:port"
      
              allowedMethods="GET, POST"
      
              allowedHeaders="Connection,Pragma,Cache-Control,XSRFtoken,Origin,User-Agent,Content-Type,Content-Length,Accept-Control-Request-Method,Accept-Control-Request-Headers,Accept,Referer,Accept-Encoding,Accept-Language,DNT,Host,Content-Length,Cache-control,Cookie"
      
             exposeHeaders="Content-Length,Content_Type,Content-Language,X-Powered-By,Date,Allow,Transfer-Encoding,$WSEP,DNT,Access-Control-Allow-Credentials,Access-Control-Allow-Headers,Access-Control-Allow-Max-Age,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Expose-Headers,Connection,Cache-control,Cookie"
      
              allowCredentials="true"
      
              maxAge="3600" />
      
      </server>
      
      
    4. You can add both HTTP and HTTPS values for the allowedOrigins value. Use a comma to separate multiple values for the entry.

      Trailing slashes (/) are not allowed.

      Important:Do not modify any parameter values other than the allowedOrigins value.

Configuring advanced authentication

Basic authentication, configured by using LDAP, includes browser authentication and API authentication. These methods might be sufficient in a test or development environment. However, if you plan to use the API in a production environment, it is recommended to configure advanced authentication by using OAuth 2.0 or OpenID Connect authentication.

The basic authentication setup and steps for preparing your environment, including the LDAP.xml configuration, are prerequisites for configuring advanced authentication. Complete those steps before you start this process.

Any identity providers that support OAuth2.0 or OpenID Connect can be used for this advanced authentication. A prerequisite for this configuration is that user names in the OAuth 2.0 / OpenID Connect Identity Provider must be identical to the user names in the LDAP server that P8 servers are configured to use. The following steps demonstrate how OAuth 2.0 or OpenID Connect is configured using a User Management Service (UMS) server as the identity provider. Configuration options might be different if you use a different type of identity provider.

To configure advanced authentication:

  1. Make sure that your identity provider supports JWK token validation using the RS256 signature algorithm. For UMS, for example, ensure that the following properties are set in the openidConnectProvider configuration:
    • jwkEndpointUrl="https://UMS_HOST/oidc/endpoint/ums/jwk"
    • signatureAlgorithm=“RS256”
  2. Register the Content Services GraphQL API with the identity provider.

    All identity providers (IdP) supporting OAuth 2.0 and OpenID Connect authentication have some registration mechanism to identify the client application to the IdP. At a minimum a client id, client secret, and redirect url(s) to the client application are required by the OAuth 2.0 and OpenID Connect specifications.

    You can post a JSON like the following example to a UMS registration endpoint to register a content services client. A description of each of these parameters can be found in https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_client_registration.html

    JSON example:

    POST https://<UMS host>:<UMS port>/oidc/endpoint/ums/registration
    {
        "token_endpoint_auth_method": "client_secret_basic",
        "scope": "openid profile email",
        "grant_types": [
            "authorization_code",
            "client_credentials",
            "implicit",
            "refresh_token",
            "urn:ietf:params:oauth:grant-type:jwt-bearer"
        ],
        "response_types": [
            "code",
            "token",
            "id_token token"
        ],
        "application_type": "web",
        "subject_type": "public",
        "post_logout_redirect_uris": [],
        "preauthorized_scope": "openid profile email",
        "introspect_tokens": true,
        "trusted_uri_prefixes": [
            "https://<ContentGraphQL host>:<ContentGraphQL port>/"
        ],
        "resource_ids": [],
        "functional_user_groupIds": [],
        "client_id": "contentServicesUms",
        "client_secret": "password",
        "client_name": "Content Services UMS",
        "redirect_uris": [
            "https://<ContentGraphQL host>:<ContentGraphQL port>/oidcclient/redirect/ContentServicesUms"
        ],
        "allow_regexp_redirects": true
    }

    Notes:

    • Multiple redirect_uris can be specified if there are multiple Content Services GraphQL servers. Update both the trusted_uri_prefixes and redirect_uris sections to be consistent:
    e.g
    "trusted_uri_prefixes": [
            "https://servername:port/",
            "https://servername2:port2/"
        ],
    redirect_uris": [
            "https://servername:port/oidcclient/redirect/ContentServicesUms",
             "https://servername2:port2/oidcclient/redirect/ContentServicesUms"
        ],
    
    
    • If allow_regexp_redirects is set to true, you can use regular expressions in the redirect_uris instead of listing all of the Content Services hosts.
  3. Import the identity provider certificate into the CRS trust store.

    To verify that the identity provider validation endpoint URI is trusted, the SSL certificate associated to that URI must be imported into the Content Services trust store.

    1. For a UMS server, use a command similar to the following to export its default SSL certificate into a file that will be imported in to the Content Services trust store:
      keytool -exportcert -keystore your_keystore_filename -storepass your_ums_keystore_password -alias default -rfc -file umscert.pem
    2. On your Content Services Liberty server, import this certificate into its trust store, giving it a unique alias name:
      keytool -importcert -trustcacerts -keystore your_keystore_filename -storetype your_keystore_type -storepass your_password -alias ums -file umscert.pem
    3. Use the following list command to make sure that all keys are imported correctly:
      keytool -list -keystore your_keystore_filename -storetype your_keystore_type -storepass your_password
    4. Add a file called ums-ssl.xml to the configDropin/overrides directory to ensure that the keystore where you imported the UMS keys and certificates is configured for the GraphQL Liberty server.
      <?xml version="1.0" encoding="UTF-8"?>
      <server>
      <keyStore id="defaultKeyStore" location="<WLP_DEFAULT_SERVER_DIR>/resources/security/key.p12" type="PKCS12" "password="your_password"/>
      </server>
      

      Samples of the ums-ssl.xml file are available in GitHub:

      For containers delivered with IBM Cloud Pak for Automation:

      https://github.com/icp4a/cert-kubernetes/tree/19.0.2/CONTENT/configuration/ContentGraphQL/configDropins/overrides

      For containers delivered with FileNet Content Manager:

      https://github.com/ibm-ecm/container-samples/tree/5.5.3/ContentGraphQL/configDropins/overrides

  4. Define the identity provider client configuration for your Content Services GraphQL API environment:
    1. Copy the UMS.xml file from the following GitHub location:

      For containers delivered with IBM Cloud Pak for Automation:

      https://github.com/icp4a/cert-kubernetes/tree/19.0.2/CONTENT/configuration/ContentGraphQL/configDropins/overrides

      For containers delivered with FileNet Content Manager:

      https://github.com/ibm-ecm/container-samples/tree/5.5.3/ContentGraphQL/configDropins/overrides

    2. Save the file to the configDropins/overrides directory that you created for the Content Services GraphQL environment.
    3. Edit the UMS.xml file to add the appropriate values for your environment:
      <?xml version='1.0' encoding='UTF-8'?>
      <server>
        
          <openidConnectClient id="ContentServicesUms"
                               mapIdentityToRegistryUser="true"
                               scope="openid profile email"
                               responseType="code"
                               clientId="contentServicesUms"
                               clientSecret=""
                               issuerIdentifier="https://<UMS host>:<UMS port>/oidc/endpoint/ums"
                               audiences="contentServicesUms"
                               validationMethod="introspect"
                               inboundPropagation="supported"
                               signatureAlgorithm="RS256"
                               jwkEndpointUrl="https://<UMS host>:<UMS port>/oidc/endpoint/ums/jwk"
                               validationEndpointUrl="https://<UMS host>:<UMS port>/oidc/endpoint/ums/introspect"
                               authorizationEndpointUrl="https://<UMS host>:<UMS port>/oidc/endpoint/ums/authorize"
                               tokenEndpointUrl="https://<UMS host>:<UMS port>/oidc/endpoint/ums/token">
          </openidConnectClient>
      
      </server>
      

      Consider the following important points about this configuration:

      • The values for clientId and clientSecret must match the client_id and client_secret values that you used when you registered the client with the identity provider.
      • The Content Services server with this configuration must run on a host matching one of the redirect_uris that you specified when you registered the client with the identity provider.
      • The value for id, for example, "ContentServicesUms", must match the target of a redirect_uri in the registration with the identity provider. For example, https://servername:port/oidcclient/redirect/ContentServicesUms.
      • The value for issuerIdentifier must match how the identity provider, for example, UMS, sees its URI.  If UMS is running in a Docker container under port 9443, but due to port mapping the UMS server is actually accessed externally through a different port number, the issuerIdentifier port must be specified as 9443. This value reflects how the Liberty server inside the Docker container sees its URI.
      • The value for audiences must include your clientId plus the clientId of other applications that might invoke Content Services with an OpenID Connect token. Depending on your identity provider, additional configuration might be required to support this scenario. For more details, refer to https://www.ibm.com/support/knowledgecenter/SSD28V_9.0.0/com.ibm.websphere.wlp.core.doc/ae/twlp_oidc_rsa_sha.html.
        The identity provider uses the clientId setting to verify that the request is coming from a valid location. The Content services server uses the audiences setting to verify that the received authentication token was meant for it and not for some other application.
    4. Save the changes to the file.

Deploying the Content Services GraphQL API container

Before you begin, ensure that you have prepared your deployment environment and, for production environments, configured advanced authentication, before you deploy the container.

Deploy the container by using one of the following methods:

  • Helm chart deployment - Use this method if you want to deploy the container on Red Hat OpenShift or IBM Cloud Private.
  • YAML file deployment - Use this method for deployments on certified Kubernetes.
     

Download and load the container image:

How you obtain the container image depends on the environment where you plan to deploy the Content Services GraphQL API container.

Containers delivered with IBM Cloud Pak for Automation

On Red Hat OpenShift:

  1. Download the compressed files from IBM Passport Advantage®
    • See the download document to find the part numbers for the components that you need.
  2. Download the loadimages.sh script from this GitHub location.
  3. Log in to the specified Docker registry with the Docker login command. This command varies depending on your environment. For Red Hat OpenShift, you can get the oc login command from the console:
    oc login https://ocp-host-url:8443 --token=the-token
  4. From the command line, run the loadimages.sh script, specifying the mandatory parameters, for example:
    # ./loadimages.sh -p /Downloads/PPA/ContentImageArchive.tgz -r /demo-project

On IBM Cloud Private:

  1. Download the compressed files from IBM Passport Advantage®
    • See the download document to find the part numbers for the components that you need.
  2. Log in to your IBM Cloud Private cluster and Docker registry from the command line:
    cloudctl login -a https://cluster_CA_domain:8443 --skip-ssl-validation
    docker login cluster_CA_domain:8500

    Where cluster_CA_domain is the certificate authority (CA) domain name. If you did not specify a CA domain, the default value is mycluster.icp. The skip-ssl-validation parameter disables the SSL validation process. SSL validation is disabled in the example to do without a trusted certificate in development environments. The self-signed SSL certificate causes an error when using the cloudctl

    If you want to load the archive into a specified namespace, you need to run the command with the -n parameter. The following example specifies the name of the namespace to load the archive as my-icp-space.

    cloudctl login -a https://cluster_CA_domain:8443 --skip-ssl-validation \
    -u admin -p admin -c id-mycluster-account -n my-icp-space
    
  3. Load the archive by entering the catalog load-archive command.
    cloudctl catalog load-archive --archive partnumber.tgz --registry mycluster.icp:8500

Containers delivered with FileNet Content Manager

On Red Hat OpenShift

  1. From Passport Advantage, download the Docker image for the Content Services GraphQL API component container: CRS-container-part-number.tar
  2. Run the tar command to extract the original content services image archive tar.gz files:
    # tar xvf CRS-container-part-number.tar

    The command results are as follows:

    • crs/ibm-dba-contentrestservice-dev-3.1.0.tgz
    • crs/crs.tgz
    • crs/FNCM 5.5.3 iFix1 License and Notices RTF.zip, ICF 5.5.3 iFix1 License and Notices RTF.zip
  3. Change to the crs/ directory and load the container by using the following command:
    docker load < crs.tgz
  4. Tag the local image by using the following command:
    docker tag crs:5.5.3.1 docker-registry.default.svc:5000/<namespace>/crs:<tag>
  5. Log in to OpenShift by using the following command:
    oc login https://openshift_ip_address:8443 --token=<the_token>
  6. Push the image to to the Docker registry:
    docker push docker-registry.default.svc:5000/<namespace>/crs:<tag>

On IBM Cloud Private

  1. From Passport Advantage, download the Docker image for the Content Services GraphQL API component container: CRS-container-part-number.tar
  2. Run the tar command to extract the original content services image archive tar.gz files:
    # tar xvf CRS-container-part-number.tar

    The command results are as follows:

    • crs/ibm-dba-contentrestservice-dev-3.1.0.tgz
    • crs/crs.tgz
    • crs/FNCM 5.5.3 iFix1 License and Notices RTF.zip, ICF 5.5.3 iFix1 License and Notices RTF.zip
  3. Change to the crs/ directory and load the container by using the following command:
    docker load < crs.tgz
  4. Tag the local image by using the following command:
    docker tag crs:5.5.3.1 mycluster.icp:8500/<namespace>/crs:<tag>
  5. Log in to IBM Cloud Private by using the following command:
    cloudctl login https://<icp_ip_address>:8443 --skip-ssl-validation
  6. Log in to your cluster:
    docker login mycluster.icp:8500
  7. Push the image to to the IBM Cloud Private cluster:
    docker push mycluster.icp:8500/<namespace>/crs:<tag>

Deploy using Helm charts:

  1. Extract the Helm chart from the image:
    tar -zxvf ibm-dba-contentrestservice-dev-3.1.0.tgz
  2. Change to the ibm-dba-contentrestservice folder and edit the following entries in the values.yaml file:
    • Image repo and tag
    • crsProductionSettings:
      • CPE_URI : http://<cpe_ip_address>:<cpe port>/wsi/FNCEWS40MTOM

        Note: This value is the endpoint for your Content Engine Platform deployment, and will be provided as a JVM argument to the Liberty server for the Content Services GraphQL API deployment.

        You can get the cpe_ip_address and cpe_port values from the Content Platform Engine container deployment.

    • Names of persistent volumes and persistent volume claims, if the values are different from yours
  3. Get the Helm chart from GitHub:
    • ibm-dba-contentrestservice-dev-3.1.0.tgz
  4. Edit the parameters, including name, namespace, PVCs, image repository and tag, and CPE_URI in the following command, and run the command:
    helm install ibm-dba-contentrestservice-dev-3.1.0.tgz --name ecm-helm-crs --namespace ecm-helm --set crsProductionSetting.license=accept,dataVolume.existingPVCforCfgstore=ecm-helm-crs-cfgstore,dataVolume.existingPVCforCfglogs=ecm-helm-crs-logstore,autoscaling.enabled=False,replicaCount=1,imagePullSecrets.name=admin.registrykey,image.repository=docker-registry.default.svc:5000/ecm-project/crs,image.tag=ga-553-p8cgql-if001,crsProductionSetting.cpeUri=http://cpe_ip_address:cpe_port/wsi/FNCEWS40MTOM

    Note: Add the --tls argument to the command for installs on IBM Cloud Private.

Deploy using YAML file:

  1. Download the sample YAML deployment file from the GitHub repository for your deployment environment:

    For containers delivered with IBM Cloud Pak for Automation:

    https://github.com/icp4a/cert-kubernetes/tree/19.0.2/CONTENT/configuration/ContentGraphQL/configDropins/overrides

    For containers delivered with FileNet Content Manager: https://github.com/ibm-ecm/container-samples/tree/5.5.3/ContentGraphQL/configDropins/overrides

  2. Edit the following entries in the crs-deploy.yml file:
    • metadata.name to ecm-crs.
    • containers.image value.
    • For OpenShift environments only, under securityContext, remove runAsUser: 50001
    • crsProductionSettings:
      • CPE_URI : http://<cpehost>:<cpe port>/wsi/FNCEWS40MTOM

        Note: This value is the endpoint for your Content Engine Platform deployment, and will be provided as a JVM argument to the Liberty server for the Content Services GraphQL API deployment.

    • Names of persistent volumes and persistent volume claims, if the values are different from yours.
  3. Change to the ibm-dba-contentrestservice folder, and run the following command:
    kubectl apply -f crs-deploy.yml 

Validating the API connection to your Content Platform Engine

If you configure your Content Services Graph QL container environment without advanced authentication, users can access the GraphQL API with basic authentication, using a login URL like the following example: http://<cshost>:<cs port>/content-services-graphql/

After you access the GraphiQL instance for the API, you can test the connection to the Content Platform Engine:

{
  _apiInfo(repositoryIdentifier: "ObjectStore1") {
    buildDate
    buildNumber
    implementationVersion
    implementationTitle
    productVersion
    cpeInfo {
      cpeURL
      cpeUser
      repositoryName
    }
  }
}

The value for the repositoryIdentifier is the Content Platform Engine object store name (symbolic name) or id (GUID).

A successful connection provides a return like the following example:

{
"data": {
"_apiInfo": {
"buildDate": "29.May 2019 at 00:58",
"buildNumber": "555",
"implementationVersion": "20190529-0058-198-user123",
"implementationTitle": "IBM ECM Content Services GraphQL API - content-graphql-api",
"productVersion": "5.5.3",
"cpeInfo": {
"cpeURL": "http://cpe_host:port/wsi/FNCEWS40MTOM/",
"cpeUser": "CN=Admin,OU=Shared,OU=Engineering,OU=Company123,DC=adam2016,DC=com",
"repositoryName": "Object Store 1"
}
}
}

Using GraphiQL to explore and use the Content Services GraphQL API

The Technology Preview: Content Services GraphQL API Developer Guide provides reference information for developers who want to use the Content Services GraphQL API in a FileNet Content Manager container environment:

Document Location

Worldwide

[{"Business Unit":{"code":"BU004","label":"Hybrid Cloud"},"Product":{"code":"SSNVNV","label":"FileNet Content Manager"},"Component":"Content Services","Platform":[{"code":"PF040","label":"RedHat OpenShift"}],"Version":"5.5.3 iFix1","Edition":""}]

Document Information

Modified date:
27 September 2019

UID

ibm10883630