Jackrabbit Oak versioning Custom Node with Custom attributes - jcr

Question is regarding versioning of node,
Step 1) If a Custom node which is of type mix:versionable and with custom properties is added as child of root node. using
Node node=rootNode.addNode(name, type);
node.addMixin("mix:versionable");
setFolderNodeAttributes(cutomMetadataObj, node, type); api.
Step 2 ) and if second version is created and saved on same node but with Different attributes for eg. below
final VersionManager versionManager=session.getWorkspace().getVersionManager();
Node node = RootNode.getNode(name);
versionManager.checkout(node.getPath());
setCustomNodeAttributes(newMetadataObj, node, type);
session.save();
versionManager.checkin(node.getPath());
Now Version history object gives me two version
1) jcr:rootVersion
2) First Version naming 1.0
This version 1.0, has currently updated Custom attributes, and root version doesn't have any custom attributes.
So for first commit or 0the version of node, which was created in step 1, custom attributes are lost(In DB they are present), but through VersionManager API I'm not able to read the 0th commit attributes.
I'm using following code for iterating over versions
final VersionHistory versionHistory = versionManager.getVersionHistory(node.getPath());
final VersionIterator versionItrator = versionHistory.getAllVersions();
while(versionItrator.hasNext()){
final Version version = versionItrator.nextVersion();
final Node idNode = version.getFrozenNode();
if (idNode.hasProperty("<Custom Property>")){
// For JCR:rootVersion its not present and for version 1.0 it printing latest checkedin property
}
}
Thanks In advance

Related

Assertion fails on object copied using Kotlin copy

This is a problem that has been really puzzling. For some reason, equals method fails here:
val newItem = testPlaylistItem.copy(id = returnedItem.id, index = 0, updatedAt = newPlaylistFromDb.updatedAt)
assertEquals(newPlaylistFromDb, newItem)
As you can see, I'm just overwriting some properties that I know that change and I can't control (id isn't known since it's generated by the persistence and index and updatedAt are internally generated). Basically what I'm doing is ignoring them for the test at hand. This test is successful locally all the time but randomly fails when run by the compilation inside a Docker container (in CI pipeline). As displayed in the error, it shows a small difference: 2022-06-20T15:50:45.187Z vs 2022-06-20T15:50:45.186Z.
What I've tried so far is decompiling the generated bytecode into Java and I can't see the reason why this could happen. Apparently the copy method would pass the instant parameter by reference to instantiate a new object.
The stack and versions I'm using are:
Docker image: openjdk:11.0.3-jre-slim
Gradle 6.9.2
Kotlin 1.4.10

how to find size of a jcr node including its childnodes?

I am using Jackrabbit 2.8.0 and JCR 2.0, I am developing a project for a organization so that it's users can store their documents and directories in digital format using their user account. I want to give size quota limit to all users. For keeping track of size, I am trying to get size of any JCR Node including its child nodes.
Any kind of help would be highly appreciable.
Thanks in advance
//jcr session after login to repository with user credentials
Session jcrsession = sessions.getSession();
Node root = jcrsession.getRootNode();
//added a file type node to root
file = root.addNode(fileName, Config.EDMS_DOCUMENT);
file.setProperty(Config.EDMS_SIZE, filesize);
InputStream isss= new ByteArrayInputStream(decodedBaseData);
Binary myBinary = valueFactory.createBinary(isss);
file.addMixin("mix:referenceable");
//added a node which will contain binary file
Node resNode = file.addNode(Config.EDMS_CONTENT,"edms:resource");
try {
//added binary data to node
resNode.setProperty("jcr:data",myBinary);
} catch (IOException e) {
e.printStackTrace();
}finally{
myBinary.dispose();
isss.close();
}
jcrsession.save();
this is how I add document type nodes and now I want to get size (in KB) of a node which may have several child nodes either of folder type or file type.
The JCR Property.getLength() method is specified at [1] to return the length of a binary property in bytes, so if you have your resNode as above, resNode.getProperty("jcr:data").getLength() should return the binary size.
You can then walk the tree with Node.getNodes() to recursively compute the total size.
Note that getLength() can return -1 if the implementation cannot determine the length, so you'll have to check for any possible constraints with the JCR implementation and file store implementation that you are using.
[1] https://www.day.com/maven/jsr170/javadocs/jcr-2.0/javax/jcr/Property.html#getLength%28%29

Trimming down or capping max version history for Apache Jackrabbit JCR

In an application that uses Apache Jackrabbit as JCR backend there are some versionable nodes in the repository (mostly text content). It seems that version history for those nodes just grows "in perpetuity".
What is the best/correct way to configure max number of versions in the version history (per workspace?) - for the future history entries AND to "trim down" the existing version histories for an arbitrary max number of entries per history?
We just set a property, a limit on number of versions we want to keep then delete the excess.
Here's an untested idea of how you could do it...
public void deleteOldVersions(Session session, String absPath, int limit)
throws RepositoryException {
VersionManager versionManager = session.getWorkspace().getVersionManager();
VersionHistory versionHistory = versionManager.getVersionHistory(absPath);
VersionIterator versionIterator = versionHistory.getAllLinearVersions(); // Gets the history in order
long numberToDelete = versionIterator.getSize() - limit;
while (numberToDelete-- > 0) {
String versionName = versionIterator.nextVersion().getName();
versionHistory.removeVersion(versionName);
}
}

A sha value represent to the status for git repository

There is a sha value represent to the status for git repository in current status?
The sha value to be updated each time the Object Database updated and References changed if git has this sha value.
In other words, the sha value represent to the current version of whole repository.
Here is my code for calculate a sha for current references. There is a git level API or interface?
private string CalcBranchesSha(bool includeTags = false)
{
var sb = new StringBuilder();
sb.Append(":HEAD");
if (_repository.Head.Tip != null)
sb.Append(_repository.Head.Tip.Sha);
sb.Append(';');
foreach (var branch in _repository.Branches.OrderBy(s => s.Name))
{
sb.Append(':');
sb.Append(branch.Name);
if (branch.Tip != null)
sb.Append(branch.Tip.Sha);
}
sb.Append(';');
if (includeTags)
{
foreach (var tag in _repository.Tags.OrderBy(s => s.Name))
{
sb.Append(':');
sb.Append(tag.Name);
if (tag.Target != null)
sb.Append(tag.Target.Sha);
}
}
return sb.ToString().CalcSha();
}
There is a sha value represent to the status for git repository in current status?
In git parlance, the status of a repository usually refers to the paths that have differences between the working directory, the index and the current HEAD commit.
However, it doesn't look like you're after this. From what I understand, you're trying to calculate a checksum that represents the state of the current repository (ie. what your branches and tags point to).
Regarding the code, it may be improved in some ways to get a more precise checksum:
Account for all the references (beside refs/tags and refs/heads) in the repository (think refs/stash, refs/notes or the generated backup references in refs/original when one rewrite the history of a repository).
Consider disambiguating symbolic from direct references. (ie: HEAD->master->08a4217 should lead to a different checksum than HEAD->08a4127)
Below a modified version of the code which deals with those two points above, by leveraging the Refs namespace:
private string CalculateRepositoryStateSha(IRepository repo)
{
var sb = new StringBuilder();
sb.Append(":HEAD");
sb.Append(repo.Refs.Head.TargetIdentifier);
sb.Append(';');
foreach (var reference in repo.Refs.OrderBy(r => r.CanonicalName))
{
sb.Append(':');
sb.Append(reference.CanonicalName);
sb.Append(reference.TargetIdentifier);
sb.Append(';');
}
return sb.ToString().CalcSha();
}
Please keep in mind the following limits:
This doesn't consider the changes to the index or the workdir (eg. the same checksum will be returned either a file has been staged or not)
There are ways to create object in the object database without modifying the references. Those kind of changes won't be reflected with the code above. One possible hack-ish way to do this could be to also append to the StringBuuilder, the number of object in the object database (ie. repo.ObjectDatabase.Count()), but that may hinder the overall performance as this will enumerate all the objects each time the checksum is calculated).
There is a git level API or interface?
I don't know of any equivalent native function in git (although similar result may be achieved through some scripting). There's nothing native in libgit2 or Libgit2Sharp APIs.

repository created via RepositoryManager not behaving the same as repo created via workbench

I create sesame native java store using following code:
Create a native java store:
// create a configuration for the SAIL stack
boolean persist = true;
String indexes = "spoc,posc,cspo";
SailImplConfig backendConfig = new NativeStoreConfig(indexes);
// stack an inferencer config on top of our backend-config
backendConfig = new ForwardChainingRDFSInferencerConfig(backendConfig);
// create a configuration for the repository implementation
RepositoryImplConfig repositoryTypeSpec = new SailRepositoryConfig(backendConfig);
RepositoryConfig repConfig = new RepositoryConfig(repositoryId, repositoryTypeSpec);
repConfig.setTitle(repositoryId);
manager.addRepositoryConfig(repConfig);
Repository repository = manager.getRepository(repositoryId);
create a in-memory store:
// create a configuration for the SAIL stack
boolean persist = true;
SailImplConfig backendConfig = new MemoryStoreConfig(persist);
// stack an inferencer config on top of our backend-config
backendConfig = new ForwardChainingRDFSInferencerConfig(backendConfig);
// create a configuration for the repository implementation
RepositoryImplConfig repositoryTypeSpec = new SailRepositoryConfig(backendConfig);
RepositoryConfig repConfig = new RepositoryConfig(repositoryId, repositoryTypeSpec);
repConfig.setTitle(repositoryId);
manager.addRepositoryConfig(repConfig);
Repository repository = manager.getRepository(repositoryId);
When I store data in this repo and query back, the results are not same as the results returned from repository created using workbench. I get duplicate/multiple entries in my resultset.
Same behavior for in-memory store.
I also observed that my triples belong to a blank context which is not the case in repository created via workbench.
What is wrong with my code above?
There is nothing wrong with your code, as far as I can see. If the store as created from the Workbench behaves differently, this most likely means that it's configured with a different SAIL stack.
The most likely candidate for the difference is this bit:
// stack an inferencer config on top of our backend-config
backendConfig = new ForwardChainingRDFSInferencerConfig(backendConfig);
You have configured your repository with a reasoner on top here. If the repository created via the workbench does not use a reasoner, you will get different results on identical queries (including, sometimes, apparent duplicate results).
If you consider this a problem, you can fix this in two ways. One is (of course) to simply not create your repository with a reasoner on top. The other is to disable reasoning for specific queries. In the Workbench, you can do this by disabling the "Include inferred statements" checkbox in the query screen. Programmatically, you can do this by using Query.setIncludeInferred(false) on your prepared query object. See the javadoc for details.