我有两个发布者和一个作者服务器。 我对用户生成的内容和修改的内容使用反向复制。 所以我还有一个正向复制(自制,因为 AEM 没有)。
问题是,发布者之间的复制陷入无限循环。所以它们就像打乒乓球一样复制。
对于发行商的乒乓球比赛我能做些什么?
我正在使用 CQ 6.1、Java 1.7
最佳答案
我找到了解决方案。
- 设置复制选项 --> 观看打印屏幕
- 调整 Session 类中的 WorkflowSession 以进行复制
- 复制后关闭 session
- 永远不要关闭工作流程 session
- 清理 crx 中发布商的发件箱 (/var/replication/outbox) [每次,如果出现问题]
- 为反向复制创建和修改创建启动器(条件:cq:distribute!=)
- 为正向复制创建和修改创建启动器(代码示例)
Because I have more than one Forward Replicator, I made an Abstract Class. If you don't use it, put all in one class
Attention: with ReplicationOption setSynchronous(true), the replication was fine to replicate from publisher to publisher. But because I have an administration page on author, I have to unncomment this attribute. Because the changes on Auhtor were not replicated to the publishe
@Component(immediate = true)
@Service(value = WorkflowProcess.class)
public class ReplicateUsergeneratedContentToPublishWorkflow extends AbstractAuthorToPublishWorkflow implements WorkflowProcess{
// OSGI properties
@Property(value = "This workflow replicate usergenerated content from author to publisher")
static final String DESCRIPTION = Constants.SERVICE_DESCRIPTION;
@Property(value = "Titel")
static final String VENDOR = Constants.SERVICE_VENDOR;
@Property(value = "Replicate the usergenerated content from one publisher via author to the ohter publisher")
static final String LABEL = "process.label";
private static final Logger LOGGER = LoggerFactory.getLogger(ReplicateUsergeneratedContentToPublishWorkflow.class);
@Reference
private ResourceResolverFactory resolverFactory;
@Reference
protected Replicator replicator;
@Reference
private SlingRepository repository;
@Reference
SlingSettingsService slingSettingsService;
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
Session session = null;
SimpleCredentials administrator = new SimpleCredentials("username", "password".toCharArray());
try {
java.util.Set<String> runModes = slingSettingsService.getRunModes();
session = repository.login(administrator);
//the replication need to check the payload
String payload = workItem.getWorkflowData().getPayload().toString();
Node node = null;
if (session.itemExists(payload)) {
node = (Node) session.getItem(payload);
}
activateNode(node, workflowSession, replicator);
//save all changes
session.save();
} catch (PathNotFoundException e) {
LOGGER.error("path not found", e);
workflowSession.terminateWorkflow(null);
} catch (ReplicationException e) {
LOGGER.error("error replicating content node", e);
workflowSession.terminateWorkflow(null);
} catch (RepositoryException e) {
LOGGER.error("error reading path to content node", e);
workflowSession.terminateWorkflow(null);
}finally{
if(session != null){
session.logout();
}
}
}
}
public abstract class AbstractAuthorToPublishWorkflow implements WorkflowProcess {
protected void activateNode(Node node, WorkflowSession workflowSession, Replicator replicator) throws RepositoryException, ReplicationException {
ReplicationOptions replicationOptions = new ReplicationOptions();
replicationOptions.setSuppressStatusUpdate(true);
replicationOptions.setSuppressVersions(true);
//replicationOptions.setSynchronous(true);
//the property cq:distribute is settet if the node should be replicated from publisher to author (set it in your own code)
if (node != null) {
node.setProperty("cq:distribute", (Value) null);
//important use WorkflowSession and adapt it to Session class, replication is going to an endless loop, if you doing it without WorkflowSession
replicator.replicate(workflowSession.adaptTo(Session.class), ReplicationActionType.ACTIVATE, node.getPath(), replicationOptions);
}
}
}
专用于用户和组正向复制,不干扰用户管理员对作者的停用操作
//Important that you don't interfer the Deactivate Action from useradmin
//do nothing if the action is deactivate!
if( !userNode.getProperty("cq:lastReplicationAction").getString().equals("Deactivate")) {
activateNode(userNode, workflowSession, replicator);
//save all changes
session.save();
}
对于我修改作者中的节点的代码部分,我添加了这个
//quickfix
//FrameworkUtil.getBundle(NodeManageDAO.class).getBundleContext()
BundleContext bundleContext = FrameworkUtil.getBundle(PhotoNodeManagerDAO.class).getBundleContext();
ServiceReference serviceReference = bundleContext.getServiceReference(SlingSettingsService.class.getName( ));
SlingSettingsService slingSettingsService = (SlingSettingsService)bundleContext.getService(serviceReference);
Set<String> runmode= slingSettingsService.getRunModes();
//just in author mode
if(runmode.contains("author")) {
//attention replication from author is not working without nullable / delete the cq:distribute property
node.setProperty("cq:distribute", (Value)null);
}
If you have a updated your workflow model, than you have to restart the worklflow and clean the failures and the cadaverous from old replication configs. Clean on author and on each publisher seperated, go to crx under /etc/workflow/launcher/config.
对于发布者上的反向复制器,还设置条件:cq:distribute!=
在代码中更改节点的每个部分,添加以下三个属性
node.setProperty("cq:distribute", ValueFactoryImpl.getInstance().createValue("true"));
node.setProperty("cq:lastModifiedBy", ValueFactoryImpl.getInstance().createValue(session.getUserID()));
node.setProperty("cq:lastModified", ValueFactoryImpl.getInstance().createValue(Calendar.getInstance()));
session.save();
启动器示例 [authorserver]/etc/workflow.html --> 启动器
关于java - 具有两个发布者的 AEM 反向复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38056051/