/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.falcon.regression.prism;
import com.jcraft.jsch.JSchException;
import org.apache.falcon.regression.Entities.FeedMerlin;
import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.Frequency;
import org.apache.falcon.entity.v0.feed.ActionType;
import org.apache.falcon.entity.v0.feed.ClusterType;
import org.apache.falcon.regression.core.helpers.ColoHelper;
import org.apache.falcon.regression.core.response.ServiceResponse;
import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.HadoopUtil;
import org.apache.falcon.regression.core.util.InstanceUtil;
import org.apache.falcon.regression.core.util.OSUtil;
import org.apache.falcon.regression.core.util.OozieUtil;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.core.util.Util;
import org.apache.falcon.regression.core.util.XmlUtil;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.oozie.client.CoordinatorAction;
import org.apache.oozie.client.OozieClient;
import org.apache.oozie.client.OozieClientException;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.joda.time.DateTime;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
import org.apache.log4j.Logger;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
/**
* Test updating of feed with custom update time.
*/
@Test(groups = "distributed")
public class UpdateAtSpecificTimeTest extends BaseTestClass {
private static final Logger LOGGER = Logger.getLogger(UpdateAtSpecificTimeTest.class);
private Bundle processBundle;
private ColoHelper cluster1 = servers.get(0);
private ColoHelper cluster2 = servers.get(1);
private ColoHelper cluster3 = servers.get(2);
private OozieClient cluster1OC = serverOC.get(0);
private OozieClient cluster2OC = serverOC.get(1);
private OozieClient cluster3OC = serverOC.get(2);
private FileSystem cluster2FS = serverFS.get(1);
private final String baseTestDir = cleanAndGetTestDir();
private String aggregateWorkflowDir = baseTestDir + "/aggregator";
@BeforeClass(alwaysRun = false)
public void uploadWorkflow() throws Exception {
uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
}
@BeforeMethod(alwaysRun = false)
public void setup() throws IOException {
final Bundle bundle = BundleUtil.readFeedReplicationBundle();
bundles[0] = new Bundle(bundle, cluster1);
bundles[1] = new Bundle(bundle, cluster2);
bundles[2] = new Bundle(bundle, cluster3);
bundles[0].generateUniqueBundle(this);
bundles[1].generateUniqueBundle(this);
bundles[2].generateUniqueBundle(this);
processBundle = new Bundle(BundleUtil.readELBundle(), cluster1);
processBundle.generateUniqueBundle(this);
processBundle.setProcessWorkflow(aggregateWorkflowDir);
}
@AfterMethod(alwaysRun = false)
public void tearDown() {
removeTestClassEntities();
}
@Test(groups = {"singleCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void invalidCharProcess()
throws JAXBException, IOException, URISyntaxException,
AuthenticationException, OozieClientException, InterruptedException {
processBundle.setProcessValidity(TimeUtil.getTimeWrtSystemTime(0),
TimeUtil.getTimeWrtSystemTime(20));
processBundle.submitFeedsScheduleProcess(prism);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, processBundle.getProcessData(), 0);
String oldProcess =
processBundle.getProcessData();
processBundle.setProcessValidity(TimeUtil.getTimeWrtSystemTime(5),
TimeUtil.getTimeWrtSystemTime(100));
ServiceResponse r = prism.getProcessHelper().update(oldProcess,
processBundle.getProcessData(), "abc");
Assert.assertTrue(r.getMessage()
.contains("java.lang.IllegalArgumentException: abc is not a valid UTC string"));
}
@Test(groups = {"singleCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void invalidCharFeed()
throws JAXBException, IOException, URISyntaxException, AuthenticationException,
OozieClientException, InterruptedException {
FeedMerlin feed = new FeedMerlin(submitAndScheduleFeed(processBundle));
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed.toString(), 0);
//update frequency
Frequency f = new Frequency("" + 21, Frequency.TimeUnit.minutes);
FeedMerlin updatedFeed = new FeedMerlin(feed.toString());
updatedFeed.setFrequency(f);
ServiceResponse r = prism.getFeedHelper().update(feed.toString(), updatedFeed.toString(), "abc");
Assert.assertTrue(r.getMessage()
.contains("java.lang.IllegalArgumentException: abc is not a valid UTC string"));
}
@Test(groups = {"singleCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void updateTimeInPastProcess()
throws JAXBException, IOException, URISyntaxException,
OozieClientException, AuthenticationException, InterruptedException {
processBundle.setProcessValidity(TimeUtil.getTimeWrtSystemTime(0),
TimeUtil.getTimeWrtSystemTime(20));
processBundle.submitFeedsScheduleProcess(prism);
//get old process details
String oldProcess = processBundle.getProcessData();
String oldBundleId = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(processBundle.getProcessData()), EntityType.PROCESS);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, oldProcess, 0);
List<String> initialNominalTimes = OozieUtil.getActionsNominalTime(cluster1OC,
oldBundleId, EntityType.PROCESS);
// update process by adding property
processBundle.setProcessProperty("someProp", "someValue");
ServiceResponse r = prism.getProcessHelper().update(oldProcess, processBundle.getProcessData());
AssertUtil.assertSucceeded(r);
//check new coord created with current time
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleId, initialNominalTimes,
processBundle.getProcessData(), true, false);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, oldProcess, 1);
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleId, initialNominalTimes,
processBundle.getProcessData(), true, true);
}
@Test(groups = {"MultiCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void updateTimeInPastFeed()
throws JAXBException, IOException, OozieClientException,
URISyntaxException, AuthenticationException, InterruptedException {
String startTimeClusterSource = TimeUtil.getTimeWrtSystemTime(-10);
String startTimeClusterTarget = TimeUtil.getTimeWrtSystemTime(10);
String feed = getMultiClusterFeed(startTimeClusterSource, startTimeClusterTarget);
LOGGER.info("feed: " + Util.prettyPrintXml(feed));
//submit and schedule feed
ServiceResponse r = prism.getFeedHelper().submitAndSchedule(feed);
TimeUtil.sleepSeconds(10);
AssertUtil.assertSucceeded(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed, 0);
//update frequency
FeedMerlin updatedFeed = new FeedMerlin(feed);
updatedFeed.setFrequency(new Frequency("7", Frequency.TimeUnit.minutes));
r = prism.getFeedHelper().update(feed, updatedFeed.toString());
AssertUtil.assertSucceeded(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed, 1);
//check correct number of coord exists or not
Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(cluster1OC, updatedFeed.getName(), "REPLICATION"), 2);
Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(cluster2OC, updatedFeed.getName(), "RETENTION"), 2);
Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(cluster1OC, updatedFeed.getName(), "RETENTION"), 2);
Assert.assertEquals(OozieUtil.checkIfFeedCoordExist(cluster3OC, updatedFeed.getName(), "RETENTION"), 2);
}
@Test(groups = {"MultiCluster", "0.3.1", "distributed"}, timeOut = 1200000, enabled = false)
public void inNextFewMinutesUpdateRollForwardProcess()
throws JAXBException, IOException, URISyntaxException, JSchException,
OozieClientException, SAXException, AuthenticationException, InterruptedException {
/*
submit process on 3 clusters. Schedule on 2 clusters. Bring down one of
the scheduled cluster. Update with time 5 minutes from now. On running
cluster new coord should be created with start time +5 and no instance
should be missing. On 3rd cluster where process was only submit,
definition should be updated. Bring the down cluster up. Update with same
definition again, now the recently up cluster should also have new
coords.
*/
try {
Util.startService(cluster2.getProcessHelper());
String startTime = TimeUtil.getTimeWrtSystemTime(-15);
processBundle.setProcessValidity(startTime,
TimeUtil.getTimeWrtSystemTime(60));
processBundle.addClusterToBundle(bundles[1].getClusters().get(0),
ClusterType.SOURCE, null, null);
processBundle.addClusterToBundle(bundles[2].getClusters().get(0),
ClusterType.SOURCE, null, null);
processBundle.submitBundle(prism);
//schedule of 2 cluster
cluster1.getProcessHelper().schedule(processBundle.getProcessData());
cluster2.getProcessHelper().schedule(processBundle.getProcessData());
InstanceUtil.waitTillInstancesAreCreated(cluster2OC, processBundle.getProcessData(), 0);
//shut down cluster2
Util.shutDownService(cluster2.getProcessHelper());
// save old data before update
String oldProcess = processBundle.getProcessData();
String oldBundleIDCluster1 = OozieUtil
.getLatestBundleID(cluster1OC,
Util.readEntityName(oldProcess), EntityType.PROCESS);
String oldBundleIDCluster2 = OozieUtil
.getLatestBundleID(cluster2OC,
Util.readEntityName(oldProcess), EntityType.PROCESS);
List<String> oldNominalTimesCluster1 = OozieUtil.getActionsNominalTime(cluster1OC,
oldBundleIDCluster1, EntityType.PROCESS);
List<String> oldNominalTimesCluster2 = OozieUtil.getActionsNominalTime(cluster2OC,
oldBundleIDCluster2, EntityType.PROCESS);
//update process validity
processBundle.setProcessProperty("someProp", "someValue");
//send update request
String updateTime = TimeUtil.getTimeWrtSystemTime(5);
ServiceResponse r = prism.getProcessHelper().update(oldProcess, processBundle.getProcessData());
AssertUtil.assertPartial(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, processBundle.getProcessData(), 1);
//verify new bundle on cluster1 and definition on cluster3
OozieUtil
.verifyNewBundleCreation(cluster1OC, oldBundleIDCluster1, oldNominalTimesCluster1,
oldProcess, true, false);
OozieUtil.verifyNewBundleCreation(cluster2OC, oldBundleIDCluster2,
oldNominalTimesCluster2,
oldProcess, false, false);
String definitionCluster3 = Util.getEntityDefinition(cluster3,
processBundle.getProcessData(), true);
Assert.assertTrue(XmlUtil.isIdentical(definitionCluster3,
processBundle.getProcessData()), "Process definitions should be equal");
//start the stopped cluster2
Util.startService(cluster2.getProcessHelper());
TimeUtil.sleepSeconds(40);
String newBundleIdCluster1 = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(oldProcess), EntityType.PROCESS);
//send second update request
r = prism.getProcessHelper().update(oldProcess, processBundle.getProcessData());
AssertUtil.assertSucceeded(r);
String defCluster2 = Util.getEntityDefinition(cluster2,
processBundle.getProcessData(), true);
LOGGER.info("defCluster2 : " + Util.prettyPrintXml(defCluster2));
// verify new bundle in cluster2 and no new bundle in cluster1 and
OozieUtil.verifyNewBundleCreation(cluster1OC, newBundleIdCluster1,
oldNominalTimesCluster1, oldProcess, false, false);
OozieUtil.verifyNewBundleCreation(cluster2OC, oldBundleIDCluster2,
oldNominalTimesCluster2, oldProcess, true, false);
//wait till update time is reached
TimeUtil.sleepTill(updateTime);
OozieUtil.verifyNewBundleCreation(cluster2OC, oldBundleIDCluster2,
oldNominalTimesCluster2, oldProcess, true, true);
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleIDCluster1,
oldNominalTimesCluster1, oldProcess, true, true);
} finally {
Util.restartService(cluster2.getProcessHelper());
}
}
@Test(groups = {"MultiCluster", "0.3.1", "distributed"}, timeOut = 1200000, enabled = false)
public void inNextFewMinutesUpdateRollForwardFeed()
throws JAXBException, IOException, URISyntaxException, JSchException,
OozieClientException, SAXException, AuthenticationException, InterruptedException {
try {
String startTimeClusterSource = TimeUtil.getTimeWrtSystemTime(-18);
String feed = getMultiClusterFeed(startTimeClusterSource, startTimeClusterSource);
LOGGER.info("feed: " + Util.prettyPrintXml(feed));
//submit feed on all 3 clusters
ServiceResponse r = prism.getFeedHelper().submitEntity(feed);
AssertUtil.assertSucceeded(r);
//schedule feed of cluster1 and cluster2
r = cluster1.getFeedHelper().schedule(feed);
AssertUtil.assertSucceeded(r);
r = cluster2.getFeedHelper().schedule(feed);
AssertUtil.assertSucceeded(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed, 0);
//shutdown cluster2
Util.shutDownService(cluster2.getProcessHelper());
//add some property to feed so that new bundle is created
FeedMerlin updatedFeed = new FeedMerlin(feed).withProperty("someProp", "someVal");
//save old data
String oldBundleCluster1 = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(feed), EntityType.FEED);
List<String> oldNominalTimesCluster1 = OozieUtil.getActionsNominalTime(cluster1OC,
oldBundleCluster1, EntityType.FEED);
//send update command with +5 mins in future
r = prism.getFeedHelper().update(feed, updatedFeed.toString());
AssertUtil.assertPartial(r);
//verify new bundle creation on cluster1 and new definition on cluster3
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleCluster1,
oldNominalTimesCluster1, feed, true, false);
String definition = Util.getEntityDefinition(cluster3, feed, true);
Diff diff = XMLUnit.compareXML(definition, processBundle.getProcessData());
LOGGER.info(diff);
//start stopped cluster2
Util.startService(cluster2.getProcessHelper());
String newBundleCluster1 = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(feed), EntityType.FEED);
//send update again
r = prism.getFeedHelper().update(feed, updatedFeed.toString());
AssertUtil.assertSucceeded(r);
//verify new bundle creation on cluster2 and no new bundle on cluster1
Assert.assertEquals(OozieUtil
.checkIfFeedCoordExist(cluster2OC, Util.readEntityName(feed), "RETENTION"), 2);
OozieUtil.verifyNewBundleCreation(cluster1OC, newBundleCluster1,
oldNominalTimesCluster1, feed, false, false);
//wait till update time is reached
TimeUtil.sleepTill(TimeUtil.getTimeWrtSystemTime(5));
//verify new bundle creation with instance matching
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleCluster1,
oldNominalTimesCluster1, feed, true, true);
} finally {
Util.restartService(cluster2.getProcessHelper());
}
}
@Test(groups = {"multiCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void updateTimeAfterEndTimeProcess()
throws JAXBException, InterruptedException, IOException, URISyntaxException,
OozieClientException, AuthenticationException {
/* submit and schedule process with end time after 60 mins. Set update time
as with +60 from start mins */
LOGGER.info("Running test updateTimeAfterEndTimeProcess");
String startTime = TimeUtil.getTimeWrtSystemTime(-15);
String endTime = TimeUtil.getTimeWrtSystemTime(60);
processBundle.setProcessValidity(startTime, endTime);
processBundle.submitFeedsScheduleProcess(prism);
TimeUtil.sleepSeconds(10);
InstanceUtil.waitTillInstanceReachState(serverOC.get(0),
Util.readEntityName(processBundle.getProcessData()), 0,
CoordinatorAction.Status.WAITING, EntityType.PROCESS);
//save old data
String oldProcess = processBundle.getProcessData();
String oldBundleID = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(oldProcess), EntityType.PROCESS);
List<String> oldNominalTimes = OozieUtil.getActionsNominalTime(cluster1OC, oldBundleID, EntityType.PROCESS);
//update
processBundle.setProcessProperty("someProp", "someVal");
String updateTime = TimeUtil.addMinsToTime(endTime, 60);
LOGGER.info("Original Feed : " + Util.prettyPrintXml(oldProcess));
LOGGER.info("Updated Feed :" + Util.prettyPrintXml(processBundle.getProcessData()));
LOGGER.info("Update Time : " + updateTime);
ServiceResponse r = prism.getProcessHelper().update(oldProcess, processBundle.getProcessData());
AssertUtil.assertSucceeded(r);
//verify new bundle creation with instances matching
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleID, oldNominalTimes,
oldProcess, true, false);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, processBundle.getProcessData(), 1);
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleID, oldNominalTimes,
oldProcess, true, true);
}
@Test(groups = {"multiCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void updateTimeAfterEndTimeFeed()
throws JAXBException, IOException, OozieClientException,
URISyntaxException, AuthenticationException, InterruptedException {
/* submit and schedule feed with end time 60 mins in future and update with +60 in future*/
String startTime = TimeUtil.getTimeWrtSystemTime(-15);
String endTime = TimeUtil.getTimeWrtSystemTime(60);
String feed = processBundle.getDataSets().get(0);
feed = FeedMerlin.fromString(feed).clearFeedClusters().toString();
feed = FeedMerlin.fromString(feed).addFeedCluster(new FeedMerlin.FeedClusterBuilder(
Util.readEntityName(processBundle.getClusters().get(0)))
.withRetention("days(100000)", ActionType.DELETE)
.withValidity(startTime, endTime)
.withClusterType(ClusterType.SOURCE)
.withDataLocation(baseTestDir + "/replication" + MINUTE_DATE_PATTERN)
.build()).toString();
ServiceResponse r = prism.getClusterHelper().submitEntity(
processBundle.getClusters().get(0));
AssertUtil.assertSucceeded(r);
r = prism.getFeedHelper().submitAndSchedule(feed);
AssertUtil.assertSucceeded(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed, 0);
//save old data
String oldBundleID = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(feed), EntityType.FEED);
String updateTime = TimeUtil.addMinsToTime(endTime, 60);
FeedMerlin updatedFeed = new FeedMerlin(feed).withProperty("someProp", "someVal");
LOGGER.info("Original Feed : " + Util.prettyPrintXml(feed));
LOGGER.info("Updated Feed :" + Util.prettyPrintXml(updatedFeed.toString()));
LOGGER.info("Update Time : " + updateTime);
r = prism.getFeedHelper().update(feed, updatedFeed.toString());
AssertUtil.assertSucceeded(r);
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, feed, 1);
//verify new bundle creation
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleID, null, feed, true, false);
}
@Test(groups = {"multiCluster", "0.3.1", "embedded"}, timeOut = 1200000, enabled = false)
public void updateTimeBeforeStartTimeProcess() throws JAXBException, IOException,
URISyntaxException, OozieClientException, AuthenticationException,
InterruptedException {
/* submit and schedule process with start time +10 mins from now. Update with start time
-4 and update time +2 mins */
String startTime = TimeUtil.getTimeWrtSystemTime(10);
String endTime = TimeUtil.getTimeWrtSystemTime(20);
processBundle.setProcessValidity(startTime, endTime);
processBundle.submitFeedsScheduleProcess(prism);
//save old data
String oldProcess = processBundle.getProcessData();
String oldBundleID = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(oldProcess), EntityType.PROCESS);
List<String> oldNominalTimes = OozieUtil.getActionsNominalTime(cluster1OC, oldBundleID,
EntityType.PROCESS);
processBundle.setProcessValidity(TimeUtil.addMinsToTime(startTime, -4), endTime);
ServiceResponse r = prism.getProcessHelper().update(oldProcess, processBundle.getProcessData());
AssertUtil.assertSucceeded(r);
TimeUtil.sleepSeconds(10);
//verify new bundle creation
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleID, oldNominalTimes,
oldProcess, true, false);
}
@Test(groups = {"MultiCluster", "0.3.1"}, timeOut = 1200000, enabled = false)
public void updateDiffClusterDiffValidityProcess()
throws JAXBException, IOException, URISyntaxException, OozieClientException,
AuthenticationException, InterruptedException {
//set start end process time for 3 clusters
String startTimeCluster1 = TimeUtil.getTimeWrtSystemTime(-40);
String endTimeCluster1 = TimeUtil.getTimeWrtSystemTime(3);
String startTimeCluster2 = TimeUtil.getTimeWrtSystemTime(120);
String endTimeCluster2 = TimeUtil.getTimeWrtSystemTime(240);
String startTimeCluster3 = TimeUtil.getTimeWrtSystemTime(-30);
String endTimeCluster3 = TimeUtil.getTimeWrtSystemTime(180);
//create multi cluster bundle
processBundle.setProcessValidity(startTimeCluster1, endTimeCluster1);
processBundle.addClusterToBundle(bundles[1].getClusters().get(0),
ClusterType.SOURCE, startTimeCluster2, endTimeCluster2);
processBundle.addClusterToBundle(bundles[2].getClusters().get(0),
ClusterType.SOURCE, startTimeCluster3, endTimeCluster3);
//submit and schedule
processBundle.submitFeedsScheduleProcess(prism);
//wait for coord to be in running state
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, processBundle.getProcessData(), 0);
InstanceUtil.waitTillInstancesAreCreated(cluster3OC, processBundle.getProcessData(), 0);
//save old info
String oldBundleIdCluster1 = OozieUtil.getLatestBundleID(cluster1OC,
Util.readEntityName(processBundle.getProcessData()), EntityType.PROCESS);
List<String> nominalTimesCluster1 = OozieUtil.getActionsNominalTime(cluster1OC,
oldBundleIdCluster1, EntityType.PROCESS);
String oldBundleIdCluster2 = OozieUtil.getLatestBundleID(cluster2OC,
Util.readEntityName(processBundle.getProcessData()), EntityType.PROCESS);
String oldBundleIdCluster3 = OozieUtil.getLatestBundleID(cluster3OC,
Util.readEntityName(processBundle.getProcessData()), EntityType.PROCESS);
List<String> nominalTimesCluster3 = OozieUtil.getActionsNominalTime(cluster3OC,
oldBundleIdCluster3, EntityType.PROCESS);
//update process
String updateTime = TimeUtil.addMinsToTime(endTimeCluster1, 3);
processBundle.setProcessProperty("someProp", "someVal");
ServiceResponse r = prism.getProcessHelper().update(processBundle.getProcessData(),
processBundle.getProcessData());
AssertUtil.assertSucceeded(r);
//check for new bundle to be created
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleIdCluster1,
nominalTimesCluster1, processBundle.getProcessData(), true, false);
OozieUtil.verifyNewBundleCreation(cluster3OC, oldBundleIdCluster3,
nominalTimesCluster3, processBundle.getProcessData(), true, false);
OozieUtil.verifyNewBundleCreation(cluster2OC, oldBundleIdCluster2,
nominalTimesCluster3, processBundle.getProcessData(), true, false);
//wait till new coord are running on cluster1
InstanceUtil.waitTillInstancesAreCreated(cluster1OC, processBundle.getProcessData(), 1);
OozieUtil.verifyNewBundleCreation(cluster1OC, oldBundleIdCluster1,
nominalTimesCluster1, processBundle.getProcessData(), true, true);
//verify
String coordStartTimeCluster3 = OozieUtil.getCoordStartTime(cluster3OC,
processBundle.getProcessData(), 1);
String coordStartTimeCluster2 = OozieUtil.getCoordStartTime(cluster2OC,
processBundle.getProcessData(), 1);
DateTime updateTimeOozie = TimeUtil.oozieDateToDate(updateTime);
Assert.assertTrue(TimeUtil.oozieDateToDate(coordStartTimeCluster3).isAfter(updateTimeOozie)
|| TimeUtil.oozieDateToDate(coordStartTimeCluster3).isEqual(updateTimeOozie),
"new coord start time is not correct");
Assert.assertFalse(
TimeUtil.oozieDateToDate(coordStartTimeCluster2).isEqual(updateTimeOozie),
"new coord start time is not correct");
TimeUtil.sleepTill(updateTime);
InstanceUtil.waitTillInstancesAreCreated(cluster3OC, processBundle.getProcessData(), 1);
//verify that no instance are missing
OozieUtil.verifyNewBundleCreation(cluster3OC, oldBundleIdCluster3,
nominalTimesCluster3, processBundle.getProcessData(), true, true);
}
private String submitAndScheduleFeed(Bundle b)
throws JAXBException, IOException, URISyntaxException, AuthenticationException,
InterruptedException {
String feed = b.getDataSets().get(0);
feed = FeedMerlin.fromString(feed).clearFeedClusters().toString();
feed = FeedMerlin.fromString(feed)
.addFeedCluster(
new FeedMerlin.FeedClusterBuilder(Util.readEntityName(b.getClusters().get(0)))
.withRetention("days(1000000)", ActionType.DELETE)
.withValidity("2012-10-01T12:10Z", "2099-10-01T12:10Z")
.withClusterType(ClusterType.SOURCE)
.withPartition("")
.withDataLocation("/someTestPath" + MINUTE_DATE_PATTERN)
.build())
.toString();
ServiceResponse r = prism.getClusterHelper().submitEntity(
b.getClusters().get(0));
AssertUtil.assertSucceeded(r);
r = prism.getFeedHelper().submitAndSchedule(feed);
AssertUtil.assertSucceeded(r);
return feed;
}
private String getMultiClusterFeed(String startTimeClusterSource, String startTimeClusterTarget)
throws IOException, URISyntaxException, AuthenticationException, InterruptedException {
String testDataDir = baseTestDir + "/replication";
//create desired feed
String feed = bundles[0].getDataSets().get(0);
//cluster1 is target, cluster2 is source and cluster3 is neutral
feed = FeedMerlin.fromString(feed).clearFeedClusters().toString();
feed = FeedMerlin.fromString(feed).addFeedCluster(
new FeedMerlin.FeedClusterBuilder(Util.readEntityName(bundles[2].getClusters().get(0)))
.withRetention("days(100000)", ActionType.DELETE)
.withValidity(startTimeClusterSource, "2099-10-01T12:10Z")
.build())
.toString();
feed = FeedMerlin.fromString(feed).addFeedCluster(
new FeedMerlin.FeedClusterBuilder(Util.readEntityName(bundles[0].getClusters().get(0)))
.withRetention("days(100000)", ActionType.DELETE)
.withValidity(startTimeClusterTarget, "2099-10-01T12:25Z")
.withClusterType(ClusterType.TARGET)
.withDataLocation(testDataDir + MINUTE_DATE_PATTERN)
.build())
.toString();
feed = FeedMerlin.fromString(feed).addFeedCluster(
new FeedMerlin.FeedClusterBuilder(Util.readEntityName(bundles[1].getClusters().get(0)))
.withRetention("days(100000)", ActionType.DELETE)
.withValidity(startTimeClusterSource, "2099-01-01T00:00Z")
.withClusterType(ClusterType.SOURCE)
.withDataLocation(testDataDir + MINUTE_DATE_PATTERN)
.build())
.toString();
//submit clusters
Bundle.submitCluster(bundles[0], bundles[1], bundles[2]);
//create test data on cluster2
List<String> dataDates = TimeUtil.getMinuteDatesOnEitherSide(startTimeClusterSource,
TimeUtil.getTimeWrtSystemTime(60), 1);
HadoopUtil.flattenAndPutDataInFolder(cluster2FS, OSUtil.SINGLE_FILE,
testDataDir + "/", dataDates);
return feed;
}
}