goblin
goblin

Reputation: 45

CQ 5.6 Reverse replication: Replication triggered, but no agent found or selected

I'm trying to write custom file upload component for CQ5.6, but I meet the problem with reverse replication. Node created in Publish instance, but not replicated to Author instance. After replicator call, next line appears in error.log:

com.day.cq.replication.impl.ReplicatorImpl Replication triggered, but no agent found or selected.

Replication agents are turned on. In other cases, userforms for example, replication works successfully, so I'm think the problem is somewhere in my code. There is the code I use:

Node node = session.getNode(path);
ValueFactory valueFactory = session.getValueFactory();
Binary contentValue = valueFactory.createBinary(is);
Node parent = node.addNode(fileName, "nt:unstructured");
parent.setProperty(DELETED, false);
parent.setProperty(DESCRIPTION, description);
Node fileNode = parent.addNode(fileName, "nt:file");
fileNode.addMixin("mix:referenceable");
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty(Property.JCR_DATA, contentValue);
Calendar lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(lastModified.getTimeInMillis());
resNode.setProperty(Property.JCR_LAST_MODIFIED, lastModified);
parent.setProperty("cq:distribute", true);
parent.setProperty("cq:lastModified", Calendar.getInstance());
parent.setProperty("cq:lastModifiedBy", session.getUserID());
session.save();
replicator.replicate(session, ReplicationActionType.ACTIVATE, parent.getPath());
session.logout();

What should I do to make reverse replication works for this nodes I create in servlet?

UPDATE: According to Tomek Rękawek answer I updated my code, but problem still not solved. Here is new code:

ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
Session session = resourceResolver.adaptTo(Session.class);
String path = (String) componentContext.getProperties().get(SAVEPATH);
Node node = session.getNode(path);
ValueFactory valueFactory = session.getValueFactory();
Binary contentValue = valueFactory.createBinary(is);
Node parent = node.addNode(fileName, "cq:Page");
Node jcrContent = parent.addNode("jcr:content", "cq:PageContent");
jcrContent.setProperty("cq:distribute", true);
jcrContent.setProperty("cq:lastModified", Calendar.getInstance());
jcrContent.setProperty("cq:lastModifiedBy", session.getUserID());
Node fileNode = jcrContent.addNode(fileName, "nt:file");
fileNode.addMixin("mix:referenceable");
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty(Property.JCR_DATA, contentValue);
session.save();
session.logout();

Upvotes: 2

Views: 7060

Answers (2)

DaveC
DaveC

Reputation: 81

For your replicator object make sure to set the agent ID of "outbox"

    AgentIdFilter filter = new AgentIdFilter("outbox");
    ReplicationOptions opts = new ReplicationOptions();
    opts.setFilter(filter);
    replicator.replicate(session, ReplicationActionType.ACTIVATE, parent.getPath(), opts);

Upvotes: 0

Tomek Rękawek
Tomek Rękawek

Reputation: 9304

Reverse replication is action performed by the author instance, not the publish. Agent responsible for this is Reverse Replication Agent on the author. It connects to the publish every 30 seconds and gathers page nodes with cq:distribute property set.

In order to reverse replicate the image you need to:

  1. Create cq:Page node
  2. Create cq:PageContent node under it and name it jcr:content.
  3. Create your image node under the jcr:content and save your session [edited]
  4. Set cq:distribute, cq:lastModified and cq:lastModifiedBy properties on the jcr:content node.
  5. Save the session

Sample method that creates page wrapping input stream and reverse-replicates it:

private void reverseReplicateBinary(Session session, String parentPath, String name, InputStream is)
        throws RepositoryException {
    ValueFactory valueFactory = session.getValueFactory();
    Node parent = session.getNode(parentPath);

    Node page = JcrUtils.getOrCreateUniqueByPath(parent, name, "cq:Page");
    Node jcrContent = page.addNode(Property.JCR_CONTENT, "cq:PageContent");
    Node file = jcrContent.addNode("file", "nt:file");
    Node resource = file.addNode(Property.JCR_CONTENT, "nt:resource");
    resource.setProperty(Property.JCR_DATA, valueFactory.createBinary(is));
    session.save();

    jcrContent.setProperty("cq:lastModified", Calendar.getInstance());
    jcrContent.setProperty("cq:lastModifiedBy", session.getUserID());
    jcrContent.setProperty("cq:distribute", false);
    session.save();
}

Complete example can be found on the gist.

That's all. You don't need to call replicator manually, author instance will gather page automatically.

Upvotes: 5

Related Questions