Getting SUSI Skill at a Commit ID
Susi Skill CMS is a web app to edit and create new skills. We use Git for storing different versions of Susi Skills. So what if we want to roll back to a previous version of the skill? To implement this feature in Susi Skill CMS, we needed an API endpoint which accepts the name of the skill and the commit ID and returns the file at that commit ID.
In this blog post I will tell about making an API endpoint which works similar to git show.
First we will accept all the request parameters from the GET request.
String model_name = call.get("model", "general"); String group_name = call.get("group", "Knowledge"); String language_name = call.get("language", "en"); String skill_name = call.get("skill", "wikipedia"); String commitID = call.get("commitID", null);
In this we get the model name, category, language name, skill name and the commit ID. The above 4 parameters are used to make a file path that is used to find the location of the skill in the Susi Skill Data repository.
This servlet need CommitID to work and if commit ID is not given in the request parameters then we send an error message saying that the commit id is null and stop the servlet execution.
Repository repository = DAO.getRepository(); ObjectId CommitIdObject = repository.resolve(commitID);
Then we get the git repository of the skill from the DAO and initialize the repository object.
From the commitID that we got in the request parameters we create a CommitIdObject.
(RevWalk revWalk = new RevWalk(repository)) { RevCommit commit = revWalk.parseCommit(CommitIdObject); RevTree tree = commit.getTree();
Now using commit’s tree, we will find the find the path and get the tree of the commit.
From the TreeWalk in the repository we will set a filter to find a file. This searches recursively for the files inside all the folders.
revWalk = new RevWalk(repository)) { try (TreeWalk treeWalk = new TreeWalk(repository)) { treeWalk.addTree(tree); treeWalk.setRecursive(true); treeWalk.setFilter(PathFilter.create(path)); if (!treeWalk.next()) { throw new IllegalStateException("Did not find expected file"); }
If the TreeWalk reaches to an end and does not find the specified skill path then it returns anIllegal State Exception with an message saying did not found the file on that commit ID.
ObjectId objectId = treeWalk.getObjectId(0);
ObjectLoader loader = repository.open(objectId);
OutputStream output = new OutputStream();
loader.copyTo(output);
And then one can the loader to read the file. From the treeWalk we get the object and create an output stream to copy the file content in it. After that we create the JSON and put the OutputStream object as as String in it.
json.put("file",output);
This Servlet can be seen working api.susi.ai: http://api.susi.ai/cms/getFileAtCommitID.json?model=general&group=knowledge&language=en&skill=bitcoin&commitID=214791f55c19f24d7744364495541b685539a4ee
Resources
JGit Documentation: https://eclipse.org/jgit/documentation/
JGit User Guide: http://wiki.eclipse.org/JGit/User_Guide
JGit Repository access: http://www.codeaffine.com/2014/09/22/access-git-repository-with-jgit/
JGit Github: https://github.com/eclipse/jgit