java - 具有两个发布者的 AEM 反向复制

标签 java aem

我有两个发布者和一个作者服务器。 我对用户生成的内容和修改的内容使用反向复制。 所以我还有一个正向复制(自制,因为 AEM 没有)。

问题是,发布者之间的复制陷入无限循环。所以它们就像打乒乓球一样复制。

对于发行商的乒乓球比赛我能做些什么?

我正在使用 CQ 6.1、Java 1.7

enter image description here

最佳答案

我找到了解决方案。

  1. 设置复制选项 --> 观看打印屏幕
  2. 调整 Session 类中的 WorkflowSession 以进行复制
  3. 复制后关闭 session
  4. 永远不要关闭工作流程 session
  5. 清理 crx 中发布商的发件箱 (/var/replication/outbox) [每次,如果出现问题]
  6. 为反向复制创建和修改创建启动器(条件:cq:distribute!=)
  7. 为正向复制创建和修改创建启动器(代码示例)

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 --> 启动器

enter image description here

关于java - 具有两个发布者的 AEM 反向复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38056051/

相关文章:

java - 如何从包含唯一键的 firebase 实时数据库中获取字符串

java - 如何从 Java Swing 计时器计算耗时

Java输入流

java - 用C++做游戏还是用java做游戏?

javascript - 通过外部 javascript 获取 AEM 子节点

aem - CQ-调度员: How to use allowAuthorized

aem - 如何将 order by 与多个 isdescendantnode 一起使用

javascript - OrientDB javascript函数返回错误400

adobe - Adobe Experience Manager (AEM) 6.2/6.3 使用什么版本的 Apache Sling?

aem - 吊索网址中后缀的用途是什么