AEM反向复制与两个发布者

时间:2016-06-27 14:04:57

标签: java cq5 aem

我有两个Publisher和一个Author Server。 对于已修改的内容,我使用反向复制来处理已使用的内容。 所以我还有一个正向复制(自制,因为AEM没有)。

问题是,Publisher之间的复制无限循环。所以他们像打乒乓球一样复制。

我可以对发布商的乒乓球游戏做些什么?

我正在使用CQ 6.1,Java 1.7

enter image description here

1 个答案:

答案 0 :(得分:1)

我找到了一个解决方案。

  1. 设置复制选项 - >看printcreen
  2. 在Session类中调整WorkflowSession以复制
  3. 关闭会话后复制
  4. 永远不要关闭工作流会话
  5. 在crx(/ var / replication / outbox)中的发布者上清理发件箱[每次都会失败]
  6. 为反向复制创建启动器创建&修改(条件:cq:distribute!=)
  7. 为正向复制创建启动器创建&修改(代码示例)
  8.   

    因为我有一个以上的前向复制器,所以我做了一个摘要   类。如果您不使用它,请将所有内容放在一个类

    中      

    注意:使用ReplicationOption setSynchronous(true),   复制可以从发布者复制到发布者。但   因为我有一个关于作者的管理页面,我必须取消注释   这个属性。因为Auhtor的变化没有复制到   公共场所

    @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);
        }
    }
    }
    

    特殊用户和组转发复制,不要干扰useradmin对作者的停用操作

                //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);
        }
    
      

    如果您更新了工作流模型,则必须重新启动worklflow并清除旧复制配置中的故障和cadaverous。清除作者和每个分离的发布者,转到/ etc / workflow / launcher / config下的crx。

    对于发布者的反向复制器,还要设置条件: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();
    

    Launchers的样本[authorserver] /etc/workflow.html - &gt;发射

    enter image description here