Embark on a journey where innovation meets real-world application! This post delves into the realm of integrating blockchain into SharePoint, demystifying its simplicity through a practical case. Picture a global company specializing in NBA shirt sales, our focal point today, grappling with the intricacies of shipments and deliveries. This scenario serves as a tangible example to unravel the role of blockchain in SharePoint amidst everyday business challenges.
This marks the second part, exploring the intricate technical aspects of the solution. Meanwhile, the initial segment, titled Implementing Blockchain for Shipment and Delivery Management in SharePoint, offers a comprehensive view of the business side and solution. We hope you find both segments enlightening!
This exploration is not just for tech enthusiasts; it's an invitation to witness the magic of technological simplification.
The article is divided into three parts, breaking down the data layer, the API layer, and the implementation of the business layer in Azure Logic Apps. Gain a comprehensive view with the accompanying technical diagram.
Data layer
The app data resides in SharePoint Online, requiring three lists: shipments, deliveries, and an event log capturing creation, modification, and deletion events for both. Essentially, this last list functions as our blockchain storage.
The Shipment Information
list handles shipment management, featuring custom columns alongside standard SharePoint Online columns:
-
Shipment ID
records the shipment identifier. -
Shipment Date
designates the shipment's scheduled date. -
Shipment Information
captures additional details about the shipment.
The Delivery Details
list manages delivery content and includes custom columns alongside standard SharePoint Online columns:
-
Delivery ID
records the delivery identifier. -
Delivery Date
designates the scheduled delivery date. -
Shipment ID
records the associated shipment identifier, linking to the corresponding shipment record. -
Recipient Information
captures additional details about the delivery.
Finally, the list that will be the store of our blockchain is called Event Tracking Information
and, apart from the standard SharePoint columns, it has the following custom columns distributed in 2 types of content:
- For the
Shipment Block Event
content type:-
Shipment ID
, -
Shipment Date
, -
Shipment Author
, -
Record Creation
, Block Hash
-
- For the
Delivery Block Event
content type:-
Delivery ID
, -
Delivery Date
, -
Shipment ID
, -
Delivery Author
, -
Record Creation
, Block Hash
-
Finally, the list designated as our blockchain repository is named Event Tracking Information
. In addition to standard SharePoint columns, it includes the following custom columns distributed across two content types.
For the Shipment Block Event
content type: Shipment ID
, Shipment Date
, Shipment Author
, Record Creation
, and Block Hash
.
For the Delivery Block Event
content type: Delivery ID
, Delivery Date
, Shipment ID
, Delivery Author
, Record Creation
, and Block Hash
.
API Layer
The API layer implementation in this exercise is straightforward. It consists of a single function developed in Azure Functions using Node.js as the engine for executing functionality.
Below, you'll find the source code for the function, allowing you to observe its simplicity despite being packed with validations and log messages.
const crypto = require("crypto");
const { app } = require('@azure/functions');
const secret = 'YOUR SECRET HERE';
function getSourceParameterNotFoundBodyAnswer() {
return {
jsonBody: {
message: 'source parameter must be provided'
},
status: 400
};
}
app.http('generateHashFromText', {
methods: ['post'],
route: 'hash/text',
authLevel: 'anonymous',
handler: async (request, context) => {
try {
context.log(`Http function processed request for url "${request.url}"`);
context.trace(`Obtaining body parameters...`);
// Checking if there is something in the body content...
if(request.body === undefined || request.body === null) {
context.warn(`No body parameters have been provided.`);
return getSourceParameterNotFoundBodyAnswer();
}
// Checking if there is something in the body out of being empty...
const bodyContent = await request.body.getReader().read();
if(bodyContent.value.length === 0) {
context.warn(`No body parameters have been provided.`);
return getSourceParameterNotFoundBodyAnswer();
}
// Reading source parameter from the body
const body = JSON.parse(new TextDecoder().decode(bodyContent.value));
const source = body.source;
if(source === undefined || source === null || source === '') {
context.info(`source query parameter not found.`);
return getSourceParameterNotFoundBodyAnswer();
}
context.info(`source query parameter value: ${source}`);
// Doing the hash to the source parameter content...
context.trace(`Do the hash for source value...`);
const hasher = crypto.createHmac("sha256", secret);
const result = hasher.update(source).digest('hex');
context.trace(`Hash obtained is ${result}`);
// Returning the hash....
return {
jsonBody: {
hash: result,
source: source,
},
status: 200
};
}
catch(err) {
context.error(`An unknow error has ocurred: ${err}`);
return {
jsonBody: {
err: err
},
status: 500
};
}
}
});
Azure Logic Apps and Custom Connector
Custom connector configuration
The setup of the Custom Connector is straightforward. After implementing the API, adding the relevant information is all that's required. If you're acquainted with OpenAPI or Swagger, this process is intuitive. For those unfamiliar, Microsoft's guide, Create a custom connector from scratch, provides step-by-step instructions. Pay attention to the settings in the third step, which become visible when you select it as an action during the deployment of Azure Logic Apps.
When a new Shipment is created in Azure Logic Apps
I'd like to walk you through the implementation details of a specific Azure Logic App—specifically, the one triggered after a new item is submitted. The rest of the Azure Logic Apps work in a similar way but with the corresponding trigger for modification and deletion.
The implementation unfolds in six phases, each with a distinct and detailed objective.
1. The trigger
The trigger is set up to identify any newly created item in the Shipment list within SharePoint Online. It's a straightforward process where we simply specify the SharePoint Online site and choose the relevant list.
2. Variable initialization
I want to underscore the significance of establishing these two stream variables. Initially, to preserve the hash of our blockchain's latest block, we initialize a variable named LatestBlockHash
. Given that hashes are alphanumeric, we set its type to string
. The default value is set to 0, serving as the hash for the genesis block or the chain's first block in case no blocks exist yet.
Conversely, we also initialize the ShipmentBlockHash
variable, also of type string
, to store the hash of the upcoming block. This variable guides us throughout the process and provides a traceable record of the value generated at each stage if needed.
3. Get the latest block hash
At this stage, we navigate to our repository housing the blockchain to fetch the latest block and consequently, obtain the value of the property where its hash is stored. Our blockchain resides in a SharePoint Online list, and that's where we retrieve the latest block.
As illustrated in the image, we utilize the action to fetch items from the SharePoint Online list. We specify the site and list, and for enhanced performance, we arrange the items based on the creation date column, ordered from newest to oldest. Additionally, we opt to retrieve only one item, streamlining the process for the system to efficiently return the desired item.
Following this, we assign the value of the Block Hash
column to the LatestBlockHash
variable, initialized earlier, enabling its incorporation into the new block.
4. Generate the shipment block
This step is straightforward; we only need to provide the necessary information to our Custom Connector. As mentioned earlier, Azure Logic Apps lacks an action to generate a hash value. Hence, we've created an API to fulfill this need and configured an Azure Logic Apps Custom Connector for its utilization.
The text string we transmit to generate a new block comprises the properties of the created Shipment and the hash value of the last block in the blockchain. The configuration of the source
parameter in the Custom Connector is outlined below:
concat('Shipment#;#',triggerBody()?['Shipment_x0020_ID'],'#;#',triggerBody()?['Shipment_x0020_Date'],'#;#',triggerBody()?['Author']?['Email'],'#;#',triggerBody()?['Created'],'#;#',variables('LatestBlockHash'))
Commencing with the text string 'Shipment' for block type identification, the following parameters consist of the ID field, shipment date, SharePoint item creator, item creation date, and ultimately, the hash of the last blockchain block. The string '#;#' functions as a separator for these values.
Following that, we assign the generated hash value to the ShipmentBlockHash
variable.
5. Add block event to the blockchain list
By utilizing the function to append a new item to a SharePoint Online list, we store our recently created block, capturing the transaction, such as the initiation of a new shipment in this instance.
The setup is straightforward; we commence by designating the SharePoint Online site and the list associated with the event log. Subsequently, we input the appropriate values into the corresponding fields. Notably, the Block Hash
field is of particular importance, as it receives the freshly generated hash from the preceding stage, stored in the ShipmentBlockHash
variable.
6. Notification
The final stage is discretionary. In my scenario, I opted to dispatch an email to the administrator whenever a block is generated, serving as a notification for the completed activity. Alternatively, this step can be substituted with any other form of notification or annotation within another system, or it can be omitted from the workflow entirely.
Conclusion
I trust that engaging in this exercise has sparked inspiration for various ideas as you reflect on its content. The underlying objective is to explore diverse technologies, understand their potential, and gain hands-on experience. Through this process, my aim is to share these insights with you, not only as a record of experimentation but also as a source of encouragement for your own ventures and explorations in the realm of technology and innovation.
By delving into this exercise, we open doors to new possibilities and discoveries. It's a testament to the spirit of experimentation, demonstrating the potential of blending different technologies. As we navigate through these technical intricacies, the ultimate goal is not only to showcase what's achievable but also to inspire a community of enthusiasts, encouraging them to embark on their unique journeys of exploration and technological experimentation.
References
- Implementing Blockchain for Shipment and Delivery Management in SharePoint: https://intranetfromthetrenches.substack.com/p/implementing-blockchain-in-sharepoint
- Custom connectors: https://learn.microsoft.com/en-us/connectors/custom-connectors/
- Create a custom connector from scratch: https://learn.microsoft.com/en-us/connectors/custom-connectors/define-blank
- Write code in a custom connector: https://learn.microsoft.com/en-us/connectors/custom-connectors/write-code
- Thanks to Hector Sosa, the author of usescreenshot.app application, for allowing framing pictures: https://usescreenshot.app/
Top comments (0)