How to Copy AEM node one place to another location? - java

I need to copy an AEM JCR node source to destination. The following code is working but if that node already exists in the destination I'm getting an error:
String sourcePath="/content/dam/assets/content";
String destinationPath="/content/dam/Marketing/content";
Session session = resourceResolver.adaptTo(Session.class);
Workspace workspace = session.getWorkspace();
workspace.copy(sourcePath, destinationPath);
session.logout();
But the problem is that the content node already exists inside the folder "Marketing" so that it's only working on the first time. Once the content node is created I'm not able to copy/update the node but I need to replace each time without deleting the source node.

If you want to operate on a whole node you can always use workspace move/copy operations (workspace.copy(String srcAbsPath, String destAbsPath) to the destination path, where the destination node should not be present/exist in JCR, if it present/exist you will end up with
javax.jcr.ItemExistsException: /jcr/repository/path/nodepresent
and for the workspace clone (workspace.clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting) usage you need to operate with two different workspaces, if you use the clone operation with the same workspace you will end up with
javax.jcr.RepositoryException: crx.default: illegal workspace (same as
current)
As i can see your requirement is to verify the destination path and update operation, you need to handle it with custom code which can verify destpath and have the NodeIterations and perform update operation.
Also have a look at copy-aem-node-tree-in-jcr which might help for your use case.

Use clone instead of copy.because clone has a removexisting boolean argument. Refer https://docs.adobe.com/docs/en/spec/jsr170/javadocs/jcr-1.0/javax/jcr/Workspace.html#clone

Related

JGit: Can I find out whether or not a particular tag exists in a Git repository without checking it out?

I need to write a piece of code in Java which tests whether or not a particular tag exists in a Git repository.
Most obvious way to do it it this:
git = Git.cloneRepository()
.setURI(gitUri)
.setDirectory(dir)
.call();
git.checkout().setName(String.format("refs/tags/%s", version)).call();
If tag version does not exist, an exception will be thrown.
But this way requires me to have a directory (dir) into which the repository will be checked out.
Is it possible to find out whether or not a tag exists in a remote repository without checking it out on disk? If yes, how can I do it?
The LsRemoteCommand is able to list the refs that a remote repository has.
The command can be configured to include tags like this:
LsRemoteCommand ls = Git.lsRemoteRepository();
Collection<Ref> remoteRefs = ls
.setRemote("url-to-remote-repo")
.setHeads(true) // true by default, set to false if not interested in refs/heads/*
.setTags(true) // include tags in result
.call();
If you prefer to get a map of ref-names to Ref objects, you can execute the command with callAsMap().

Get the default branch of a remote repository with JGit

I am working on a Git client, and right now I am trying to implement the checkout of a specific branch. I have a combo box that I populate with branch names, and I would like to find out which branch is the default, so that I can set it as the preselected item in the combo box when connecting to a valid Git repository.
I am listing all the remote branches as you can see below, but I cannot figure out which is the default one.
Map<String, Ref> callAsMap = Git.lsRemoteRepository()
.setRemote("https://github.com/example")
.setCredentialsProvider(credentialsProvider)
.callAsMap();
So, is there a way (standard or "hacky") to detect which Ref object represents the default branch? And how can I get its name?
Repository::getFullBranch returns the current branch of the local repository.
To get the default branch of a remote repository, you need to ask for its HEAD ref. The map that is returned by the snippet that you posted should contain an entry with key HEAD and (if I'm not mistaken) a value that denotes the name of the default branch.
If HEAD refers to an object id, you could obtain a list of all remote refs with repository.getRefDatabase().getRefs(Constants.R_REMOTES) to look up the HEAD id. This approach may be inaccurate as multiple refs could point to the same object id.
Note that it is not required for a remote repository to advertise a default branch.
See also these posts for how C-Git finds the default branch: git - how to get default branch? and What determines default branch after "git clone"?)
After the chain with .get("HEAD"), if it is a symbolic link, you can chain it with .getTarget().getName() to "extract" its name e.g.
Map<String, Ref> callAsMap = Git.lsRemoteRepository()
.setRemote("https://github.com/example")
.setCredentialsProvider(credentialsProvider)
.callAsMap().get("HEAD").getTarget().getName()
Source: https://www.eclipse.org/lists/jgit-dev/msg03320.html

Need help related with cluster setup

I am trying to make a cluster of ejabberd.For the same purpose i have configured the single node of ejabberd(i am using version 15.04 which is the latest one available)and now to add another node i am trying modify the configuration file.I opened the "/sbin/ejabberdctl" script file for changing the host name and modified the
ERLANG_NODE=ejabberd#localhost to ERLANG_NODE=ejabberd#ejabbered1
and modified the "/etc/ejabberd/ejabberd.yml" ERLANG_NODE=ejabberd#ejabbered1
Now when I try to run the ejabberd using "ejabberdctl start" i could see
Failed RPC connection to the node ejabberd#ejabberd1: nodedown
After going to the "ejabberd.log" i could see
"2015-05-20 06:10:21.462 [critical] <0.38.0>#ejabberd_app:db_init:120 Node name mismatch: I'm [ejabberd#ejabberd1], the database is owned by [ejabberd#localhost]"
Now i want to know how can i change the node name in change node name in Mnesia.
thanks in advance.
You can change the node name associated with a Mnesia database. You either have to restart fresh or export the Mnesia database with old node name and reimport it. See: https://www.ejabberd.im/migrate-host
Note that setting up cluster should not involve changing node name, so I am not sure what you did to get to that state.

How To Use JGit To Do Equivalent Of "git push --mirror ..."?

I'm trying to create a simple application that executes a "git push --mirror" operation from the Java domain.
The JGit library, specifically the PushCommand class, doesn't seem to support the "--mirror" option even though it supports "--all" and "--tags".
Am I missing something? How do we use JGit to do "git push --mirror ..."?
Try it manually by using the following ref spec:
git.push().setRefSpecs(new RefSpec("+refs/*:refs/*")).call();
There is no exact equivalent to --mirror in JGit yet, but you should be able to emulate this behaviour. To force-push all local refs you can configure the PushCommand with
PushCommand pushCommand = git.push();
pushCommand.setForce(true);
pushCommand.add("refs/*:refs/*");
That would leave the refs that have been deleted locally. Therefore you can obtain a list of remote-refs to determine what has been deleted locally and publish those deletions to the remote:
Collection<Ref> remoteRefs = git.lsRemote().setRemote("origin").setHeads(true).setTags(true).call();
Collection<String> deletedRefs = new ArrayList<String>();
for (Ref remoteRef : remoteRefs) {
if (git.getRepository().getRef(remoteRef.getName()) == null) {
deletedRefs.add(remoteRef.getName());
}
}
for (String deletedRef : deletedRefs) {
pushCommand.add(":" + deletedRef);
}
The git variable references the repository that you want to push from, i.e. the one from the first block. The LsRemoteCommand returns all heads and tags from the remote repository that is configured as origin in the local repository's configuration. In the usual case, the one you cloned from.
Please note that there is a small gap to the approach how deleted local refs are propagated. The LsRemoteCommand only returns refs under heads and tags (e.g. no custom refs like pulls), hence you would not detect a local deletion of e.g. refs/foo/bar.
Does that work for you?

Migration of blobs from database to the file system in jackrabbit

As being proposed in the previous discussion Using file system instead of database to store pdf files in jackrabbit
we can use FileDataStore to store blob files in the file system instead of database (i my case have stored ~ 100 kb size pdfs).
The following problem I have faced is dealing with files that have been previously stored in blobstore and I want them to be accessible after switching to FileDataStore.
After adding FileDataStore support to the repository.xml
when using JcrUtils method getOrAddNode i get ItemExistsException:
public static Node getOrAddNode(Node parent, String name)
throws RepositoryException {
if (parent.hasNode(name)) {
return parent.getNode(name);
} else {
return parent.addNode(name);
}
}
e.g. parent.hasNode(name) returns false (it seems the item doesn't exist)
but then we fall in to the code parent.addNode(name) which consequently throws ItemExistsException.
Any help?
Is it necessary to proceed the migration of blobs to the FileDataStore or there is kind of configuration that jackrabbit could search for blobs in different locations at the same time: in my case mysql database and filesystem.
Some comments:
I have found at least several ways that could help do the migration job:
spec http://wiki.apache.org/jackrabbit/BackupAndMigration
tells about using JCR API (Session.exportSystemView(..) and then Session.importXML(..) ), using RepositoryCopier API etc.
jackrabbit-jcr-import-export-tool (see http://svn.apache.org/repos/asf/jackrabbit/sandbox/jackrabbit-jcr-import-export-tool/README.txt)
using jackrabbit standalone server (http://jackrabbit.apache.org/standalone-server.html)
It might be possible that there is a repository corruption. That is, the node contains a child node entry for the given name (the node you want to add), but the child node itself doesn't exist. Specially in older version of Jackrabbit you could get into this situation if multiple sessions concurrently tried to change the same nodes.
To fix such corruption problems, the bundle db persistence managers support a consistency check & fix feature. You would need to set those options in the repository.xml and workspace.xml files, and restart Jackrabbit. Once fixed, you can disable those options again.
There is also a way to fix such problems at runtime, by setting the system property org.apache.jackrabbit.autoFixCorruptions to true, and then traverse over all nodes in the repository.

Categories