in src/governance/ccf-app/js/src/endpoints/documents.ts [46:142]
export function putDocument(request: ccfapp.Request<PutDocumentRequest>) {
const id = request.params.documentId;
// Check if the document is already accepted.
if (acceptedDocumentsStore.has(id)) {
return {
statusCode: 405,
body: new ErrorResponse(
"DocumentAlreadyAccepted",
"An accepted document cannot be changed."
)
};
}
const contractId = request.body.json().contractId;
if (!contractId) {
return {
statusCode: 400,
body: new ErrorResponse(
"ContractIdMissing",
"ContractId must be specified in document payload."
)
};
}
const data = request.body.json().data;
if (!data) {
return {
statusCode: 400,
body: new ErrorResponse(
"DataMissing",
"data key must be present in document payload."
)
};
}
// A contract must exist. We don't check the accepted contract store as the state of the contract
// is not considered. Mere presence of a contract in the store sufficient.
const contractsStore = ccfapp.typedKv(
"public:contracts",
ccfapp.string,
ccfapp.json<ContractStoreItem>()
);
if (!contractsStore.has(contractId)) {
return {
statusCode: 404,
body: new ErrorResponse(
"ContractNotFound",
"A contract with the specified id was not found."
)
};
}
const incomingVersion = request.body.json().version;
if (documentsStore.has(id)) {
const seqno = documentsStore.getVersionOfPreviousWrite(id);
const view = ccf.consensus.getViewForSeqno(seqno);
if (view == null) {
return {
statusCode: 503,
body: new ErrorResponse(
"ViewNotKnown",
"View for given sequence number not known to the node at this time."
)
};
}
if (!incomingVersion) {
return {
statusCode: 409,
body: new ErrorResponse(
"DocumentAlreadyExists",
"The specified document already exists. If the intent was to update the " +
"existing document then retry the " +
"request after reading the latest version of the resource and setting the version on " +
"the request."
)
};
}
const version = view + "." + seqno;
if (version != incomingVersion) {
return {
statusCode: 412,
body: new ErrorResponse(
"PreconditionFailed",
"The operation specified a version that is different from the version " +
"available at the server, that is, an optimistic concurrency error. Retry the " +
"request after reading the latest version of the resource and updating the version on " +
"the request."
)
};
}
}
documentsStore.set(id, { contractId: contractId, data: data });
return {};
}