If you have a comment on this topic, contact Aptify Documentation. If you want to return to the Aptify Community Site, please click here.

Sample endpoint to leverage binary uploads for attachments

Overview

It describes using e-Business 6.0 services to leverage the Attachment functionality. Let's consider an example, the customer is required to upload a Date of Birth (DOB) document to their profile through e-Business 6.0.

How do we determine what a DOB document is?

You can create an Attachment Category named as DOB to determine the DOB attachment. Upload a DOB attachment to a person using Aptify Smart Client.

Learn how we can View & Download these DOB Attachments. Then use e-Business 6.0 services to upload the DOB attachment.

Also, we will see how we can Secure the endpoint.

Prerequisites

Verify that the following prerequisites are available on your system.

  • e-Business 6.0 installed
  • Services up

Once you have e-Business 6.0 Services up, you would need to create Endpoints.

For installing e-Business 6.0, please refer Using e-business 6.0

For information on JSON endpoints creation in e-Business 6.0, please refer Endpoint Metadata

POC Example

 This will require three points as given below. All these points are discussed in detail.

  1. DOB Attachment Category
  2. JSON Endpoints
  3. Security

DOB Attachment Category

Create a new attachment category in Aptify Smart Client (under Framework), name it as DOB, and scope it to Entity. Add Persons under Entities tab. Once DOB attachment category is created, we will need 3 JSON endpoints.

                 

Here we can see the DOB category under persons attachment. We added one DOB attachment to it as given in below screenshot. Now, we will View and Download this attachment using our JSON endpoints.

JSON Endpoints

There are three endpoints used here as given below:

ViewAllAttachments

URL: v1/ViewAttachments/{EntityName}/{Id}/{CategoryName}?sort={sort}

Http method: GET

The URL segment includes:

  • EntityName
  • Entity RecordId
  • CategoryName (DOB)

This endpoint returns list of attachments for a particular record for the specified category, which is DOB in this case. The business logic uses 'speBusiness6_0GetPersonRecordAttachments' Stored Procedure (SP) to fetch attachment records based on person and attachment category (You can find this in the CMPacks attached with the document). The response can be configured to return different fields by editing 'outputEntityDefintion' in JSON code given below. Also, the SP can be modified to return more or less values depending on requirement. 

Here is the JSON code for the View Attachments endpoint.

JSON - View attachments
"ViewAllAttachments": {
    
    "route": {
      "httpMethod": "GET",
      "segments": {
        "ViewAttachments": {
          "isLiteral": true,
          "type": "string"
        },
        "EntityName": {
          "isLiteral": false,
          "type": "string"
        },
        "Id": {
          "isLiteral": false,
          "type": "long",
          "security": {
            "IsYourRecord": {
              "$ref": "../../Common/security.json#/isYourRecord"
            }
          }
        },
        "CategoryName": {
          "isLiteral": false,
          "type": "string"
        }
      }
    },
    
    "inputEntityDefinition": {
      "name": "GetAllAttachments",
      "fields": {
        "EntityName": {
          "type": "string",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        },
        "Id": {
          "type": "long",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        },
        "CategoryName": {
          "type": "string",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        }
      }
    },
    "outputEntityDefinition": {
      "isCollection": true,
      "name": "AttachmentsOutput",
      "fields": {
        "id": {
          "type": "long"
        },
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string",
          "description": "A plain text description of the attachment."
        } 
      }
    },
    "businessLogic": {
      "allAttachmentsRetrieval": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "Execute Data Object",
          "processFlowParameters": {
            "DataObjectName": "speBusiness6_0GetPersonRecordAttachments", //"speBusiness6_0GetRecordAttachments",
            "authenticatedAttributes": "@AuthenticatedAttributes"
          }
        }
      }
    },
    "security": {
      "IsYourRecord": {
        "$ref": "../../Common/security.json#/isYourRecord"
      }
    } 
  }

This code is written in the HDEB-10 (Code + Metadata) Attachments.zip →DownloadAttachment.json file.

Below is the stored procedure for fetching attachment records.

SQL - speBusiness6_0GetPersonRecordAttachments
CREATE PROC speBusiness6_0GetPersonRecordAttachments
   (  
    @Request_Id      INT,
	@Request_EntityName NVARCHAR(100),
	@Request_CategoryName  NVARCHAR(100)
	)
AS
	SELECT 
		ID,Name,Description,DateCreated,
	      DateUpdated,WhoCreated,WhoUpdated,Status,LocalFileName
	FROM 
		vwAttachments
	WHERE
		--EntityID=1006 AND
		EntityID = (Select top 1 ID from vwEntities where Name = @Request_EntityName) AND
		RecordID=@Request_Id AND
		Category=@Request_CategoryName


Code in Action

When this endpoint is executed against the above person record for the DOB attachment category, we can see the result.

Here is the response as shown in POSTMAN:


getSingleDownload

URL: v1/ProfilePersons/{id}/Download/{entityName}/{recordId}/{attachmentId}

Http method: GET

This downloads the attachment of a person based on attachment ID. This action requires below URL parameters as given below:

  • entityName - Persons in this case
  • recordId - Entity Record ID
  • attachmentId - The ID of attachment record to download


JSON - get single download
 "getSingleDownload": {
    "parent": {
      "name": "getSingleProfilePerson"
    },
    "route": {
      "httpMethod": "GET",
      "segments": {
        "Download": {
          "isLiteral": true,
          "type": "string"
        },
        "entityName": {
          "isLiteral": false,
          "type": "string"
        },
        "recordId": {
          "isLiteral": false,
          "type": "long"
        },
        "attachmentId": {
          "isLiteral": false,
          "type": "long",
          "security": {
            "IsYourAttachment": {
              "$ref": "../../Common/security.json#/isYourAttachment"
                //
            }
          }
        }
      },
      "description": "Downloads the Attachment of a person record"
    },
    "inputEntityDefinition": {
      "name": "getSingleDownloadInput",
      "fields": {
        "entityName": {
          "type": "string",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        },
        "recordId": {
          "type": "long",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        },
        "attachmentId": {
          "type": "long",
          "input": {
            "httpMethods": [ "GET" ],
            "source": "path"
          }
        }
      }
    },
    "outputEntityDefinition": null,
    "businessLogic": {
      "downloadAttachmentToServer": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "Download Attachment To Server",
          "processFlowParameters": {
            "EntityName": "@request.entityName", //"Persons", //"@request.entityName",//hardcode entity name in json
            "RecordID": "@request.recordId", //"@request.Id", //"@request.recordId",//request.recordId for person
            "AttachmentID": "@request.attachmentId",
            "ServerFilePath": ""
          }
        }
      },
      "downloadAttachmentToClient": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "Download Attachment To Client",
          "processFlowParameters": {
            "FileName": "@parent.downloadAttachmentToServer.outputAttachmentFileWithPath"
          }
        }
      }
    },
    "security": {
      "IsYourAttachment": {
        "$ref": "../../Common/security.json#/isYourAttachment"
      }
    },
    "options": {
      "customOutput": true
    }
  }

This code is also written in HDEB-10 (Code + Metadata) Attachments.zip → DownloadAttachment.json file.


Code in Action

Download the DOB attachment of the above person in Chrome browser. As we can see in the Screenshot below, we successfully downloaded the attachment which we uploaded initially through Smart Client.

The code given below provides security to this endpoint. We will discuss about this in Security.

Security for Download Attachment
"security": {
      "IsYourAttachment": {
        "$ref": "../../Common/security.json#/isYourAttachment"
      }

Upload DOB Attachment

URL: v1/ProfilePersons/{id}/UploadAttachment

Http method: POST

This endpoint attaches the file to the Person's record under the DOB category.

This code is written in HDEB-10 (Code + Metadata) Attachments.zip → FileUpload.json file.


JSON - Upload
"UploadFile": {
    "parent": {
      "name": "getSingleProfilePerson"
    },
    "route": {
      "httpMethod": "POST",
      "segments": {
        "UploadAttachment": {
          "isLiteral": true,
          "type": "string"
        }
      }
    },
    "inputEntityDefinition": null,
    "outputEntityDefinition": null,
    "businessLogic": {
      "MultiPartFormDataReaderPF": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "MultiPartFormDataReader Process Flow",
          "processFlowParameters": {
          }
        }
      },
      "MultiPartFormDataContentTypeValidatorPF": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "MultiPartFormDataContentTypeValidator Process Flow",
          "processFlowParameters": {
            "MultiPartFormDataObject": "@parent.MultiPartFormDataReaderPF.outputMultipartFormDataObject",
            "ValidMimeTypes": "image/jpg,image/png"
          }
        }
      },
      //POC
      "AttachmentPF": {
        "executionType": "processFlow",
        "processFlowProperties": {
          "processFlowName": "Test Attachment PF",
          "processFlowParameters": {
            "FileData": "@parent.MultiPartFormDataReaderPF.outputMultipartFormDataObject",
            "RecordId": "@request.Id",
            "EntityName": "Persons", //Hardcoded for POC
            "CategoryId": 1 //DOB Category ID, Hardcoded for POC
          }
        }
      }

      /*
		,
        "MultiPartFormDataCleanupPF": {
          "executionType": "processFlow",
          "processFlowProperties": {
            "processFlowName": "MultiPartFormDataCleanup process flow",
            "processFlowParameters": {
              "MultiPartFormDataObject": "@parent.MultiPartFormDataReaderPF.outputMultipartFormDataObject"
            }
          }
        }		
		*/
    }
  }

This endpoint uses the "Test Attachment PF” process flow which is under HDEB-10 (Code + Metadata) Attachments.zip → HDEB-10_PF_TestAttachment.cmpack.

Upload - Hardcoded entity and category

For the POC, Entity Name, and Category Id are hardcoded in the Business Logic.


Code in Action

Upload one more DOB attachment to the person as shown is the below screenshot, using this endpoint:

Now, refresh the Person record on Smart Client and we can see that there are two attachments. Second attachment uploaded by using JSON endpoint.

Also, when we hit 'ViewAttachments' endpoint, we can see two attachments being returned.

Security

The attachment Record is secured by a SQL function 'spSecurityeBusiness6_0CanPersonAccessAttachment'. This function makes sure that the attachment belongs to the authenticated Person Record and category DOB.

You can find the Stored Procedure under HDEB-10 (Code + Metadata) Attachments.zip → HDEB-10_SPs.cmpack.

This code block is written in "..\eBusiness\json\metadata\v1\Common\security.json". This executes the above security function with the required parameters.

JSON - Security function
"isYourAttachment": {
    "type": "SQLFunction",
    "parameters": {
      "functionName": "spSecurityeBusiness6_0CanPersonAccessAttachment",
      "functionParameters": {
        "@PersonId": "@request.recordId",
        "@AttachmentId": "@request.attachmentId",
        "@CategoryName": "DOB"
      }
    }
  }


SQL - spSecurityeBusiness6_0CanPersonAccessAttachment
  CREATE PROCEDURE spSecurityeBusiness6_0CanPersonAccessAttachment
  (
  	@PersonId  INT = -1,
	@AttachmentID INT,
	@CategoryName NVARCHAR(100)
  )
  AS
  BEGIN
  Select COUNT(*) from vwattachments Where ID=@AttachmentID and Entity='Persons' and RecordID = @PersonId AND Category = @CategoryName
  END


This is written in the getSingleDownload JSON endpoint to secure with the above security.

JSON - security block
"security": {
      "IsYourAttachment": {
        "$ref": "../../Common/security.json#/isYourAttachment"
      }

Example

Whenever an unauthorized person tries to fetch an attachment, this give errors as given below:

Deployment Instructions

Follow the below given steps to deploy the above mentioned POC example.

  1. Extract the files from HDEB-10 (Code + Metadata) Attachments.zip.
  2. Unpack the PF's and DBO's CMPacks using CM tool.
  3. Paste FileUpload.json and DownloadAttachment.json files under “..\eBusiness\json\metadata\v1\Endpoints\ProfilePersons” folder.

4. The above three endpoints are registered under HDEB-10 (Code + Metadata) Attachments.zip → ProfilePersonEndpoint.json file.

JSON - Registering attachment endpoints
"UploadFile": {
      "$ref": "FileUpload.json#/UploadFile"
    },
    "ViewAllAttachments": {
      "$ref": "DownloadAttachment.json#/ViewAllAttachments"
    },
    "DownloadAttachment": {
      "$ref": "DownloadAttachment.json#/getSingleDownload"
    }

5. Add the class 'AttachmentComponent.cs' from HDEB-10 (Code + Metadata) Attachments.zip  under 'MultipartFormDataProcessFlows' project in Visual Studio.

This class Implements “IProcessComponent” interface. This component is responsible for attaching the Attachment to the entity record specified by the Input Parameters.


Copyright © 2014-2019 Aptify - Confidential and Proprietary