BinaryLessTransportHandler.java 10.1 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.auth.oauth.AccessTokenProvider
 *  com.adobe.granite.keystore.KeyStoreService
 *  javax.jcr.Credentials
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.SimpleCredentials
 *  org.apache.commons.httpclient.HttpMethodBase
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.PropertyUnbounded
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferenceCardinality
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.References
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.ResourceResolverFactory
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.ServiceReference
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.replication.impl.transport;

import com.adobe.granite.auth.oauth.AccessTokenProvider;
import com.adobe.granite.keystore.KeyStoreService;
import com.day.cq.replication.Agent;
import com.day.cq.replication.AgentConfig;
import com.day.cq.replication.AgentManager;
import com.day.cq.replication.ReplicationAction;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.ReplicationContent;
import com.day.cq.replication.ReplicationContentFactory;
import com.day.cq.replication.ReplicationException;
import com.day.cq.replication.ReplicationLog;
import com.day.cq.replication.ReplicationResult;
import com.day.cq.replication.ReplicationTransaction;
import com.day.cq.replication.ReverseReplication;
import com.day.cq.replication.TransportContext;
import com.day.cq.replication.TransportHandler;
import com.day.cq.replication.impl.transport.Http;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.jcr.Credentials;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.References;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, inherit=0)
@Service(value={TransportHandler.class})
@Properties(value={@Property(name="disabled.cipher.suites", label="%disabled.cipher.suites.name", description="%disabled.cipher.suites.description", unbounded=PropertyUnbounded.ARRAY), @Property(name="enabled.cipher.suites", label="%enabled.cipher.suites.name", description="%enabled.cipher.suites.description", unbounded=PropertyUnbounded.ARRAY)})
@References(value={@Reference(name="accessTokenProvider", target="(service.pid=*)", referenceInterface=AccessTokenProvider.class, cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC), @Reference(name="keyStoreService", referenceInterface=KeyStoreService.class, cardinality=ReferenceCardinality.MANDATORY_UNARY, policy=ReferencePolicy.STATIC), @Reference(name="rrf", referenceInterface=ResourceResolverFactory.class, cardinality=ReferenceCardinality.MANDATORY_UNARY, policy=ReferencePolicy.STATIC)})
public class BinaryLessTransportHandler
extends Http {
    private final Logger log = LoggerFactory.getLogger(BinaryLessTransportHandler.class);
    @Reference
    private SlingRepository repository;
    private BundleContext bundleContext;
    private AgentManager agentManager;

    @Activate
    @Override
    public void activate(ComponentContext componentContext) throws RepositoryException {
        super.activate(componentContext);
        this.bundleContext = componentContext.getBundleContext();
    }

    private void bindAgentManager() {
        ServiceReference sr = this.bundleContext.getServiceReference(AgentManager.class.getName());
        if (sr != null) {
            this.agentManager = (AgentManager)this.bundleContext.getService(sr);
        }
    }

    @Override
    public boolean canHandle(AgentConfig config) {
        String uri = config == null ? null : config.getTransportURI();
        return uri != null && (uri.startsWith("http://") || uri.startsWith("https://")) && uri.contains("binaryless=true");
    }

    @Override
    protected ReplicationResult createReplicationResult(ReplicationLog log, ReplicationAction action, HttpMethodBase httpMethod, Http.Conversation conv) {
        int statusCode = httpMethod.getStatusCode();
        StringBuilder statusMsg = new StringBuilder();
        log.info("sent. Response: %d %s", statusCode, statusMsg);
        if (statusCode != 200) {
            this.error(log, action, conv, null);
            log.info("Replication (%s) of %s not successful.", new Object[]{action.getType(), action.getPath()});
        } else {
            Iterator<String> citer = conv.messages();
            while (citer.hasNext()) {
                String next = citer.next();
                log.info(next);
                statusMsg.append(next);
            }
            log.info("Replication (%s) of %s successful.", new Object[]{action.getType(), action.getPath()});
        }
        return new ReplicationResult(statusCode == 200, statusCode, statusMsg.toString());
    }

    @Override
    public ReplicationResult deliver(TransportContext ctx, ReplicationTransaction tx) throws ReplicationException {
        ReplicationResult result = super.deliver(ctx, tx);
        List<String> missingPaths = this.parseMissingPaths(result);
        if (this.log.isDebugEnabled()) {
            this.log.debug("{} paths are missing", (Object)missingPaths.size());
        }
        if (missingPaths.size() > 0) {
            result = this.sendMissingBinaries(ctx, tx, missingPaths);
        }
        return result;
    }

    private ReplicationResult sendMissingBinaries(TransportContext ctx, final ReplicationTransaction tx, List<String> missingPaths) throws ReplicationException {
        ReplicationResult result;
        if (this.agentManager == null) {
            this.bindAgentManager();
            if (this.agentManager == null) {
                throw new ReplicationException("BinaryAwareTransportHandler could not get a reference to the AgentManager");
            }
        }
        Session agentSession = null;
        try {
            agentSession = ctx.getConfig().getAgentUserId() != null ? this.repository.impersonateFromService("replicationService", (Credentials)new SimpleCredentials(ctx.getConfig().getAgentUserId(), new char[0]), null) : this.repository.loginService("replicationService", null);
            final ReplicationAction action = tx.getAction();
            HashMap<String, Object> paramaters = new HashMap<String, Object>();
            paramaters.put("missingBinaries", missingPaths);
            Agent agent = this.agentManager.getAgents().get(ctx.getConfig().getAgentId());
            final ReplicationContent newReplicationContent = agent.buildContent(agentSession, action, paramaters);
            result = super.deliver(ctx, new ReplicationTransaction(){

                @Override
                public ReplicationAction getAction() {
                    return action;
                }

                @Override
                public ReplicationContent getContent() {
                    return newReplicationContent;
                }

                @Override
                public ReplicationLog getLog() {
                    return tx.getLog();
                }
            });
        }
        catch (RepositoryException e1) {
            throw new ReplicationException((Exception)e1);
        }
        finally {
            if (agentSession != null) {
                agentSession.logout();
            }
        }
        return result;
    }

    private List<String> parseMissingPaths(ReplicationResult result) {
        LinkedList<String> missingPaths = new LinkedList<String>();
        String s = "FAILED PATHS START";
        String e = "<< FAILED PATHS END";
        String message = result.getMessage();
        int startingIndex = message.indexOf(s);
        int endIndex = message.indexOf(e);
        if (result.isSuccess() && startingIndex > -1 && endIndex > startingIndex) {
            String missingBinariesList = message.substring(startingIndex + s.length(), endIndex);
            for (String line : missingBinariesList.split("<< ")) {
                if (line == null || line.length() <= 1) continue;
                missingPaths.add(line);
                if (!this.log.isDebugEnabled()) continue;
                this.log.debug("path {} is missing", (Object)line);
            }
        }
        return missingPaths;
    }

    @Override
    public ReplicationResult poll(TransportContext ctx, ReplicationTransaction tx, List<ReplicationContent> result, ReplicationContentFactory factory) throws ReplicationException {
        return super.poll(ctx, tx, result, factory);
    }

    @Override
    public ReverseReplication[] poll(TransportContext ctx, ReplicationTransaction tx, ReplicationContentFactory factory) throws ReplicationException {
        return super.poll(ctx, tx, factory);
    }

    protected void bindRepository(SlingRepository slingRepository) {
        this.repository = slingRepository;
    }

    protected void unbindRepository(SlingRepository slingRepository) {
        if (this.repository == slingRepository) {
            this.repository = null;
        }
    }

}