SyncronisationJobServerTest.java 11.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.jcr.JcrUtil
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.WCMException
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.nodetype.NodeType
 *  org.apache.sling.api.resource.LoginException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceResolverFactory
 *  org.apache.sling.commons.json.JSONArray
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.event.jobs.JobManager
 *  org.apache.sling.junit.annotations.SlingAnnotationsTestRunner
 *  org.apache.sling.junit.annotations.TestReference
 *  org.junit.After
 *  org.junit.Assert
 *  org.junit.Before
 *  org.junit.Test
 *  org.junit.runner.RunWith
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.aam.client.testing;

import com.adobe.cq.aam.client.AudienceManagerFolderList;
import com.adobe.cq.aam.client.TestData;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.junit.annotations.SlingAnnotationsTestRunner;
import org.apache.sling.junit.annotations.TestReference;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(value=SlingAnnotationsTestRunner.class)
public class SyncronisationJobServerTest {
    private static final int ONE_SECOND = 1000;
    private static final int TWO_SECONDS = 2000;
    private static final int TEN_SECONDS = 10000;
    private static final long ONE_TWENTY_SECONDS = 120000;
    private static final long THIRTY_SECONDS = 30000;
    private static final Logger LOGGER = LoggerFactory.getLogger(SyncronisationJobServerTest.class);
    @TestReference
    private ResourceResolverFactory resourceResolverFactory;
    @TestReference
    private JobManager jobManager;
    private Long instanceId;
    private String configNodePath;
    private ResourceResolver resourceResolver;
    private Session session;
    private boolean notOnServer = false;
    private boolean cleanup;
    private String baseSegmetnationPath;
    private PageManager pageManager;

    @Before
    public void setup() throws LoginException, InterruptedException, RepositoryException, WCMException {
        if (this.resourceResolverFactory == null) {
            this.notOnServer = true;
            return;
        }
        boolean running = false;
        try {
            this.createInstanceId();
            this.resourceResolver = this.resourceResolverFactory.getAdministrativeResourceResolver(null);
            this.pageManager = (PageManager)this.resourceResolver.adaptTo(PageManager.class);
            running = true;
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), (Throwable)e);
            throw new RuntimeException(e.getMessage(), e);
        }
        finally {
            if (!running) {
                try {
                    this.resourceResolver.close();
                    this.resourceResolver = null;
                    this.session = null;
                }
                catch (Exception e) {
                    LOGGER.debug(e.getMessage(), (Throwable)e);
                }
            }
        }
    }

    @After
    public void teardown() throws RepositoryException {
        try {
            if (this.notOnServer) {
                return;
            }
            if (this.cleanup) {
                for (String path : new String[]{this.configNodePath, this.baseSegmetnationPath}) {
                    if (!this.session.itemExists(path)) continue;
                    this.session.removeItem(path);
                }
            }
            this.session.save();
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), (Throwable)e);
            throw new RuntimeException(e.getMessage(), e);
        }
        finally {
            try {
                this.resourceResolver.close();
            }
            catch (Exception e) {
                LOGGER.debug(e.getMessage(), (Throwable)e);
            }
            this.deleteInstanceId();
        }
    }

    private synchronized void createInstanceId() throws InterruptedException {
        while (this.instanceId != null) {
            this.wait();
        }
        this.instanceId = System.currentTimeMillis();
    }

    private synchronized void deleteInstanceId() {
        this.instanceId = null;
        this.notify();
    }

    @Test
    public void testStandardSegmentSet() throws InterruptedException, RepositoryException {
        try {
            if (this.notOnServer) {
                return;
            }
            this.runTestSet("com/adobe/cq/aam/client/segment", 30000);
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), (Throwable)e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Test
    public void testLargeSegmentSet() throws InterruptedException, RepositoryException {
        try {
            if (this.notOnServer) {
                return;
            }
            this.runTestSet("com/adobe/cq/aam/client/1000_gen", 120000);
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), (Throwable)e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private void runTestSet(String testSet, long timeout) throws WCMException, RepositoryException, JSONException, IOException, InterruptedException {
        String[] setupData = this.createConfigNode(testSet, String.valueOf(this.instanceId));
        this.configNodePath = setupData[0];
        this.baseSegmetnationPath = setupData[1] + "_0";
        int expected = this.countExpectedNodes(testSet);
        long tupdate = System.currentTimeMillis();
        this.waitForCreateTest(expected, timeout);
        LOGGER.info("Found all expected nodes in tree, sleeping to allow sync Job to complete. ", (Object)expected);
        Thread.sleep(2000);
        tupdate = System.currentTimeMillis() - tupdate;
        this.waitForUpdateTest(expected, tupdate + 10000);
        LOGGER.info("The correct number of nodes was found after an update sync: Test passed Ok ");
    }

    private String[] createConfigNode(String segmentset, String testId) throws WCMException, RepositoryException {
        Page testConfig = this.pageManager.create("/etc/cloudservices/audiencemanager", testId, "/libs/cq/personalization/audiencemanager/templates/audiencemanager", "Test Config " + testId);
        Resource testConfigResource = testConfig.getContentResource();
        Node configNode = (Node)testConfigResource.adaptTo(Node.class);
        JcrUtil.setProperty((Node)configNode, (String)"partner", (Object)String.valueOf(this.instanceId));
        JcrUtil.setProperty((Node)configNode, (String)"container", (Object)"0");
        JcrUtil.setProperty((Node)configNode, (String)"offlineMode", (Object)true);
        JcrUtil.setProperty((Node)configNode, (String)"offlineSet", (Object)segmentset);
        JcrUtil.setProperty((Node)configNode, (String)"oauthExpiresEpoch", (Object)(System.currentTimeMillis() + 3600000));
        JcrUtil.setProperty((Node)configNode, (String)"oauthAccessToken", (Object)"dummyToken");
        this.session = configNode.getSession();
        this.session.save();
        return new String[]{configNode.getPath(), "/etc/segmentation/aam/" + testId};
    }

    private void waitForCreateTest(int expected, long timeout) throws RepositoryException, InterruptedException {
        this.cleanup = false;
        int n = 0;
        long eta = System.currentTimeMillis() + timeout;
        while (System.currentTimeMillis() < eta) {
            Thread.sleep(1000);
            if (this.session.nodeExists(this.baseSegmetnationPath) && (n = this.countNodes(this.session.getNode(this.baseSegmetnationPath), "cq:Page")) >= expected) {
                this.cleanup = true;
                return;
            }
            LOGGER.info("Found {} or {} nodes in segmentation tree ", (Object)n, (Object)expected);
        }
        Assert.fail((String)("Timeout or not enough nodes, visual inspection of  " + this.baseSegmetnationPath + " required once activity dies down"));
    }

    private void waitForUpdateTest(int expected, long sleepFor) throws InterruptedException, RepositoryException {
        for (Node n : new Iterable<Node>(){

            @Override
            public Iterator<Node> iterator() {
                try {
                    return SyncronisationJobServerTest.this.session.getNode(SyncronisationJobServerTest.this.baseSegmetnationPath).getNodes();
                }
                catch (Exception e) {
                    return null;
                }
            }
        }) {
            if (!"cq:Page".equals(n.getPrimaryNodeType().getName())) continue;
            n.remove();
        }
        LOGGER.info("Simulating rapid job triggers, whcih should not cause a problem");
        JcrUtil.setProperty((Node)this.session.getNode(this.configNodePath), (String)"container", (Object)null);
        this.session.save();
        JcrUtil.setProperty((Node)this.session.getNode(this.configNodePath), (String)"container", (Object)"0");
        this.session.save();
        Thread.sleep(sleepFor);
        this.cleanup = false;
        Assert.assertEquals((String)("The Number of cq:PageNodes was not correct, please check " + this.baseSegmetnationPath), (long)expected, (long)this.countNodes(this.session.getNode(this.baseSegmetnationPath), "cq:Page"));
        this.cleanup = true;
    }

    private int countExpectedNodes(String testset) throws JSONException, IOException {
        return this.countFolders(testset) + this.countSegments(testset);
    }

    private int countSegments(String testset) throws JSONException, IOException {
        return new JSONObject(TestData.loadTestData(testset + "_folder_page0.json")).getInt("total");
    }

    private int countFolders(String testset) throws JSONException, IOException {
        AudienceManagerFolderList folders = new AudienceManagerFolderList(new JSONArray(TestData.loadTestData(testset + "_folders.json")), "none");
        return folders.size();
    }

    private int countNodes(final Node node, String type) {
        int c = 0;
        for (Node n : new Iterable<Node>(){

            @Override
            public Iterator<Node> iterator() {
                try {
                    return node.getNodes();
                }
                catch (RepositoryException e) {
                    return new ArrayList().iterator();
                }
            }
        }) {
            try {
                if (type.equals(n.getPrimaryNodeType().getName())) {
                    ++c;
                }
            }
            catch (RepositoryException e) {
                LOGGER.error(e.getMessage(), (Throwable)e);
            }
            c += this.countNodes(n, type);
        }
        return c;
    }

}