Example: Replication Helper Class
package com.wemblog;
import java.util.Iterator;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.dam.api.Asset;
import com.day.cq.replication.Agent;
import com.day.cq.replication.AgentManager;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.ReplicationException;
import com.day.cq.replication.ReplicationQueue;
import com.day.cq.replication.ReplicationStatus;
import com.day.cq.replication.Replicator;
import com.day.cq.wcm.api.Page;
/**
* Helper Method to do tree activation
*
* @author Yogesh Upadhyay
* @since 1.0.12
*
*/
public class ReplicationHelper {
private Logger logger = LoggerFactory.getLogger(ReplicationHelper.class);
private final Replicator replicator;
private final ResourceResolver resolver;
private final Session session;
private boolean onlyModified=false;
private boolean reactivate=false;
private boolean ignoreDeactivated=false;
private boolean dryRun;
private long lastUpdate;
private long tCount = 0;
private long aCount = 0;
private AgentManager agentManager;
private ReplicationActionType replicationActionType = ReplicationActionType.ACTIVATE;
/**
* Default Constructor
*
* @param replicator
* @param resolver
* @param agentManager
*/
public ReplicationHelper(final Replicator replicator, final ResourceResolver resolver,
final AgentManager agentManager) {
this.replicator = replicator;
this.resolver = resolver;
this.session = resolver.adaptTo(Session.class);
this.agentManager = agentManager;
}
public void setOnlyModified(final boolean onlyModified) {
this.onlyModified = onlyModified;
}
public void setReactivate(final boolean reactivate) {
this.reactivate = reactivate;
}
public void setIgnoreDeactivated(final boolean ignoreDeactivated) {
this.ignoreDeactivated = ignoreDeactivated;
}
public void setReplicationActionType(final ReplicationActionType actionType){
this.replicationActionType = actionType;
}
/**
* Process Replication based on path
*
* @param path
*/
public void process(String path) {
if (path == null || path.length() == 0) {
return;
}
// snip off all trailing slashes
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
// reject root and 1 level paths
if (path.lastIndexOf('/') <= 0) {
if (path.length() == 0) {
path = "/";
}
return;
}
Resource res = resolver.getResource(path);
if (res == null) {
return;
}
long startTime = System.currentTimeMillis();
try {
process(res);
long endTime = System.currentTimeMillis();
logger.debug("Time taken to do tree activation ", endTime - startTime);
} catch (Exception e) {
logger.error("Error during tree activation of " + path, e);
}
}
/**
* Get all throttled Agents
*
* @return
*/
private Agent getThrottleAgent() {
// get the first enabled agents
AgentManager agentMgr = this.agentManager;
for (Agent agent : agentMgr.getAgents().values()) {
if (agent.isEnabled()) {
return agent;
}
}
return null;
}
/**
* Process replication Job based on resource
*
* @param res
* @return
* @throws RepositoryException
* @throws ReplicationException
*/
private boolean process(Resource res) throws RepositoryException,
ReplicationException {
// we can only tree-activate hierarchy nodes
Node node = res.adaptTo(Node.class);
if (!node.isNodeType("nt:hierarchyNode")) {
return false;
}
Page page = res.adaptTo(Page.class);
Asset asset = res.adaptTo(Asset.class);
long lastModified;
if (page != null) {
lastModified = page.getLastModified() == null ? -1 : page
.getLastModified().getTimeInMillis();
} else if (asset != null) {
lastModified = asset.getLastModified() == 0 ? -1 : asset
.getLastModified();
} else {
ResourceMetadata data = res.getResourceMetadata();
lastModified = data.getModificationTime();
}
ReplicationStatus rs = res.adaptTo(ReplicationStatus.class);
long lastPublished = 0;
boolean isDeactivated = false;
boolean isActivated = false;
if (rs != null && rs.getLastPublished() != null) {
lastPublished = rs.getLastPublished().getTimeInMillis();
isDeactivated = rs.isDeactivated();
isActivated = rs.isActivated();
}
boolean isModified = lastModified > lastPublished;
boolean doActivate = false;
if (!isModified && onlyModified) {
doActivate = false;
}else {
try {
replicator.checkPermission(this.session,
this.replicationActionType, res.getPath());
doActivate = true;
} catch (ReplicationException e) {
logger.error(e.getMessage());
}
}
tCount++;
Agent agent = getThrottleAgent();
ReplicationQueue queue = agent == null ? null : agent.getQueue();
int num = queue == null ? 0 : queue.entries().size();
int test = 0;
//Check for queue full or not
while (num > 3) {
try {
logger.error("Queue is Full waiting for queue to be empty");
Thread.sleep(500);
} catch (InterruptedException e) {
// ignore
}
num = queue.entries().size();
test++;
}
if (doActivate) {
if (!dryRun) {
try {
logger.debug("Replicating file "+res.getPath());
replicator.replicate(session, this.replicationActionType,
res.getPath());
} catch (ReplicationException e) {
logger.error("Error during tree activation of " + res.getPath(), e);
}
}
aCount++;
}
long now = System.currentTimeMillis();
if (now - lastUpdate > 1000L) {
lastUpdate = now;
}
Iterator<Resource> iter = resolver.listChildren(res);
while (iter.hasNext()) {
process(iter.next());
}
return true;
}
}
Tree Activation Service
package com.wemblog.utility;
import java.util.List;
import org.apache.sling.api.resource.ResourceResolver;
import com.day.cq.replication.Agent;
import com.day.cq.replication.ReplicationActionType;
/**
* Replication Utility Method for some common replication task
* All task are performed using ADMIN user, use
* @author Yogesh Upadhyay
* @since 1.0.12
*
*/
public interface ReplicationUtilService {
/**
* Tree replicate based on given path.
* It is recommended to use more refined path rather than activating parent with a lot of nodes
* Note that all resources under this tree will get activated. Use other settings to make sure that only modified is activated.
* @param parent_path
* @param {@link ResourceResolver}
*/
public void treeReplicate(String parent_path,ResourceResolver resolver);
/**
* Tree replication with {@link ReplicationActionType}
* This will activate or deactivate entire tree
* @param parent_path
* @param {@link ReplicationActionType}
* @param {@link ResourceResolver}
*/
public void treeReplicate(String parent_path, ReplicationActionType actionType, ResourceResolver resolver);
/**
* Tree activation for only modified content
* @param parent_path
* @param onlyModified
* @param {@link ResourceResolver}
*/
public void treeReplicate(String parent_path,boolean onlyModified, ResourceResolver resolver);
/**
* Tree activation for modified and ignore deactivate setting.
* @param parent_path
* @param onlyModified
* @param ignoreDeactivated
* @param {@link ResourceResolver}
*/
public void treeReplicate(String parent_path,boolean onlyModified, boolean ignoreDeactivated, ResourceResolver resolver);
/**
* Method to get all Active Agents
* This include both replication and dispatcher agent
* @return {@link List<Agent>}
*/
public List<Agent> getAllActiveAgents();
/**
* Method to get all active publish agents
* @return
*/
public List<Agent> getAllPublishAgent();
/**
* Method to get all active dispatcher agents
* @return
*/
public List<Agent> getAllDispatcherAgent();
/**
* Simple method to activate a content path
* @param resource_path
* @param {@link ResourceResolver}
*/
public void activate(String resource_path, ResourceResolver resolver);
/**
* Method to deactive a path
* @param resource_path
* @param {@link ResourceResolver}
*/
public void deactivate(String resource_path, ResourceResolver resolver);
}
Tree Activation Impl
package com.wemblog.utility.impl;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.replication.Agent;
import com.day.cq.replication.AgentManager;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.Replicator;
import com.wemblog.ReplicationHelper;
import com.wemblog.ReplicationUtilService;
/**
*
* @author Yogesh Upadhyay
* @since 1.0.12
*
*/
@Service
@Component
public class ReplicationUtilServiceImpl implements ReplicationUtilService {
private Logger logger = LoggerFactory.getLogger(ReplicationUtilServiceImpl.class);
@Reference
private Replicator replicator;
@Reference
private ResourceResolverFactory resourceResolverFactory;
@Reference
private AgentManager agentManager;
private ResourceResolver resourceResolver = null;
private Session session;
/**
* Tree Replicate based on path
*/
@Override
public void treeReplicate(final String parent_path, final ResourceResolver resolver) {
treeReplicate(parent_path, ReplicationActionType.ACTIVATE, resolver);
}
@Override
public void treeReplicate(final String parent_path,
final ReplicationActionType actionType,final ResourceResolver resolver) {
try {
if (null == resolver) {
logger.error("Resolver is null can not tree activate " + parent_path);
return;
}
if (resolver.resolve(parent_path) instanceof NonExistingResource) {
logger.error("Parent path does not exist can not activate "
+ parent_path);
return;
}
this.resourceResolver = resolver;
ReplicationHelper replicationHelper = new ReplicationHelper(replicator,
resourceResolver, agentManager);
replicationHelper.setReplicationActionType(actionType);
replicationHelper.process(parent_path);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public void treeReplicate(final String parent_path, final boolean onlyModified,
final ResourceResolver resolver) {
treeReplicate(parent_path, onlyModified, false, resolver);
}
@Override
public void treeReplicate(final String parent_path, final boolean onlyModified,
final boolean ignoreDeactivated, final ResourceResolver resolver) {
try {
if (null == resolver) {
logger.error("Resolver is null can not tree activate " + parent_path);
return;
}
if (resolver.resolve(parent_path) instanceof NonExistingResource) {
logger.error("Parent path does not exist can not activate "
+ parent_path);
return;
}
resourceResolver = resolver;
ReplicationHelper replicationHelper = new ReplicationHelper(replicator,
resourceResolver, agentManager);
replicationHelper.setOnlyModified(onlyModified);
replicationHelper.setIgnoreDeactivated(ignoreDeactivated);
replicationHelper.process(parent_path);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public List<Agent> getAllActiveAgents() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public List<Agent> getAllPublishAgent() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled() && !agent.isCacheInvalidator()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public List<Agent> getAllDispatcherAgent() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled() && agent.isCacheInvalidator()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public void activate(final String resource_path, final ResourceResolver resolver) {
try {
resourceResolver = resolver;
if (resolver == null) {
logger.error("Resolver is null can not activate " + resource_path);
return;
}
this.session = resourceResolver.adaptTo(Session.class);
if (!(resourceResolver.resolve(resource_path) instanceof NonExistingResource)) {
replicator.replicate(this.session, ReplicationActionType.ACTIVATE,
resource_path);
} else {
logger.error("Resource you are trying to replicate does not exist "
+ resource_path);
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public void deactivate(final String resource_path, final ResourceResolver resolver) {
try {
if (resolver == null) {
logger.error("Resolver is null can not activate " + resource_path);
return;
}
this.resourceResolver = resolver;
this.session = resourceResolver.adaptTo(Session.class);
if (!(resourceResolver.resolve(resource_path) instanceof NonExistingResource)) {
replicator.replicate(this.session, ReplicationActionType.DEACTIVATE,
resource_path);
} else {
logger.error("Resource you are trying to replicate does not exist "
+ resource_path);
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
}
Note: In the above example replication action is performed using admin user. You could also create a replication user and use that user to replicate instead.
package com.wemblog.utility.impl;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.replication.Agent;
import com.day.cq.replication.AgentManager;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.Replicator;
import com.wemblog.ReplicationHelper;
import com.wemblog.ReplicationUtilService;
/**
*
* @author Yogesh Upadhyay
* @since 1.0.12
*
*/
@Service
@Component
public class ReplicationUtilServiceImpl implements ReplicationUtilService {
private Logger logger = LoggerFactory.getLogger(ReplicationUtilServiceImpl.class);
@Reference
private Replicator replicator;
@Reference
private ResourceResolverFactory resourceResolverFactory;
@Reference
private AgentManager agentManager;
private ResourceResolver resourceResolver = null;
private Session session;
/**
* Tree Replicate based on path
*/
@Override
public void treeReplicate(final String parent_path, final ResourceResolver resolver) {
treeReplicate(parent_path, ReplicationActionType.ACTIVATE, resolver);
}
@Override
public void treeReplicate(final String parent_path,
final ReplicationActionType actionType,final ResourceResolver resolver) {
try {
if (null == resolver) {
logger.error("Resolver is null can not tree activate " + parent_path);
return;
}
if (resolver.resolve(parent_path) instanceof NonExistingResource) {
logger.error("Parent path does not exist can not activate "
+ parent_path);
return;
}
this.resourceResolver = resolver;
ReplicationHelper replicationHelper = new ReplicationHelper(replicator,
resourceResolver, agentManager);
replicationHelper.setReplicationActionType(actionType);
replicationHelper.process(parent_path);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public void treeReplicate(final String parent_path, final boolean onlyModified,
final ResourceResolver resolver) {
treeReplicate(parent_path, onlyModified, false, resolver);
}
@Override
public void treeReplicate(final String parent_path, final boolean onlyModified,
final boolean ignoreDeactivated, final ResourceResolver resolver) {
try {
if (null == resolver) {
logger.error("Resolver is null can not tree activate " + parent_path);
return;
}
if (resolver.resolve(parent_path) instanceof NonExistingResource) {
logger.error("Parent path does not exist can not activate "
+ parent_path);
return;
}
resourceResolver = resolver;
ReplicationHelper replicationHelper = new ReplicationHelper(replicator,
resourceResolver, agentManager);
replicationHelper.setOnlyModified(onlyModified);
replicationHelper.setIgnoreDeactivated(ignoreDeactivated);
replicationHelper.process(parent_path);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public List<Agent> getAllActiveAgents() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public List<Agent> getAllPublishAgent() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled() && !agent.isCacheInvalidator()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public List<Agent> getAllDispatcherAgent() {
List<Agent> all_active_agent = new ArrayList<Agent>();
for (Agent agent : agentManager.getAgents().values()) {
if (agent.isEnabled() && agent.isCacheInvalidator()) {
all_active_agent.add(agent);
}
}
return all_active_agent;
}
@Override
public void activate(final String resource_path, final ResourceResolver resolver) {
try {
resourceResolver = resolver;
if (resolver == null) {
logger.error("Resolver is null can not activate " + resource_path);
return;
}
this.session = resourceResolver.adaptTo(Session.class);
if (!(resourceResolver.resolve(resource_path) instanceof NonExistingResource)) {
replicator.replicate(this.session, ReplicationActionType.ACTIVATE,
resource_path);
} else {
logger.error("Resource you are trying to replicate does not exist "
+ resource_path);
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
@Override
public void deactivate(final String resource_path, final ResourceResolver resolver) {
try {
if (resolver == null) {
logger.error("Resolver is null can not activate " + resource_path);
return;
}
this.resourceResolver = resolver;
this.session = resourceResolver.adaptTo(Session.class);
if (!(resourceResolver.resolve(resource_path) instanceof NonExistingResource)) {
replicator.replicate(this.session, ReplicationActionType.DEACTIVATE,
resource_path);
} else {
logger.error("Resource you are trying to replicate does not exist "
+ resource_path);
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
// we do not close resource resolver here because it's passed as reference
}
}
}
Note: In the above example replication action is performed using admin user. You could also create a replication user and use that user to replicate instead.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.