/** * 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.service; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TimeZone; import org.apache.falcon.FalconException; import org.apache.falcon.Pair; import org.apache.falcon.entity.AbstractTestBase; import org.apache.falcon.entity.EntityNotRegisteredException; import org.apache.falcon.entity.parser.ValidationException; import org.apache.falcon.entity.v0.EntityType; import org.apache.falcon.entity.v0.Frequency; import org.apache.falcon.entity.v0.SchemaHelper; import org.apache.falcon.entity.v0.cluster.Cluster; import org.apache.falcon.entity.v0.feed.ClusterType; import org.apache.falcon.entity.v0.feed.Clusters; import org.apache.falcon.entity.v0.feed.Feed; import org.apache.falcon.entity.v0.feed.Sla; import org.apache.falcon.entity.v0.feed.Validity; import org.apache.falcon.resource.AbstractSchedulableEntityManager; import org.testng.Assert; import org.testng.annotations.Test; /** * Tests for EntitySLAMonitoring Service. */ public class EntitySLAMonitoringTest extends AbstractTestBase { private static final String CLUSTER_NAME = "testCluster"; private static final String FEED_NAME = "testFeed"; private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); private static final String TAG_CRITICAL = EntitySLAMonitoringService.get().TAG_CRITICAL; @Test public void testSLAStatus() throws FalconException { // sla, start, end, missingInstances Sla sla = new Sla(); sla.setSlaLow(new Frequency("days(1)")); sla.setSlaHigh(new Frequency("days(2)")); Date start = SchemaHelper.parseDateUTC("2014-05-05T00:00Z"); Date end = SchemaHelper.parseDateUTC("2015-05-05T00:00Z"); List<Date> missingInstances = new ArrayList<>(); missingInstances.add(SchemaHelper.parseDateUTC("2013-05-05T00:00Z")); // before start time missingInstances.add(SchemaHelper.parseDateUTC("2014-05-05T00:00Z")); // equal to start time missingInstances.add(SchemaHelper.parseDateUTC("2014-05-06T00:00Z")); // in between missingInstances.add(SchemaHelper.parseDateUTC("2014-05-07T00:00Z")); missingInstances.add(SchemaHelper.parseDateUTC("2015-05-05T00:00Z")); // equal to end time missingInstances.add(SchemaHelper.parseDateUTC("2015-05-06T00:00Z")); // after end time Set<Pair<Date, String>> result = EntitySLAMonitoringService.get().getFeedSLAStatus(sla, start, end, missingInstances); Set<Pair<Date, String>> expected = new HashSet<>(); expected.add(new Pair<>(SchemaHelper.parseDateUTC("2014-05-05T00:00Z"), TAG_CRITICAL)); expected.add(new Pair<>(SchemaHelper.parseDateUTC("2014-05-06T00:00Z"), TAG_CRITICAL)); expected.add(new Pair<>(SchemaHelper.parseDateUTC("2014-05-07T00:00Z"), TAG_CRITICAL)); expected.add(new Pair<>(SchemaHelper.parseDateUTC("2015-05-05T00:00Z"), TAG_CRITICAL)); Assert.assertEquals(result, expected); } @Test(expectedExceptions = EntityNotRegisteredException.class, expectedExceptionsMessageRegExp = ".*\\(FEED\\) not found.*") public void testInvalidFeedName() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("feed", "non-existent", "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); } @Test(expectedExceptions = EntityNotRegisteredException.class, expectedExceptionsMessageRegExp = ".*\\(PROCESS\\) not found.*") public void testInvalidProcessName() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("process", "non-existent", "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "2015-05-00T00:00Z is not a valid UTC string") public void testInvalidStart() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("feed", null, "2015-05-00T00:00Z", "2015-05-05T00:00Z", "*"); AbstractSchedulableEntityManager.validateSlaParams("process", null, "2015-05-00T00:00Z", "2015-05-05T00:00Z", "*"); } @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "start can not be after end") public void testInvalidRange() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("feed", null, "2015-05-05T00:00Z", "2014-05-05T00:00Z", "*"); AbstractSchedulableEntityManager.validateSlaParams("process", null, "2015-05-05T00:00Z", "2014-05-05T00:00Z", "*"); } @Test public void testOptionalName() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("feed", null, "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); AbstractSchedulableEntityManager.validateSlaParams("feed", "", "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); AbstractSchedulableEntityManager.validateSlaParams("process", null, "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); AbstractSchedulableEntityManager.validateSlaParams("process", "", "2015-05-05T00:00Z", "2015-05-05T00:00Z", "*"); } @Test public void testOptionalEnd() throws FalconException { AbstractSchedulableEntityManager.validateSlaParams("feed", null, "2015-05-05T00:00Z", "", "*"); AbstractSchedulableEntityManager.validateSlaParams("feed", null, "2015-05-05T00:00Z", null, "*"); AbstractSchedulableEntityManager.validateSlaParams("process", null, "2015-05-05T00:00Z", "", "*"); AbstractSchedulableEntityManager.validateSlaParams("process", null, "2015-05-05T00:00Z", null, "*"); } private Cluster publishCluster() throws FalconException { Cluster cluster = new Cluster(); cluster.setName(CLUSTER_NAME); cluster.setColo("default"); getStore().publish(EntityType.CLUSTER, cluster); return cluster; } private Feed publishFeed(Cluster cluster, String frequency, String start, String end) throws FalconException, ParseException { Feed feed = new Feed(); feed.setName(FEED_NAME); Frequency f = new Frequency(frequency); feed.setFrequency(f); feed.setTimezone(UTC); Clusters fClusters = new Clusters(); org.apache.falcon.entity.v0.feed.Cluster fCluster = new org.apache.falcon.entity.v0.feed.Cluster(); fCluster.setType(ClusterType.SOURCE); fCluster.setName(cluster.getName()); fCluster.setValidity(getFeedValidity(start, end)); fClusters.getClusters().add(fCluster); feed.setClusters(fClusters); getStore().publish(EntityType.FEED, feed); return feed; } private Validity getFeedValidity(String start, String end) throws ParseException { Validity validity = new Validity(); validity.setStart(getDate(start)); validity.setEnd(getDate(end)); return validity; } private Date getDate(String dateString) throws ParseException { DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm Z"); return format.parse(dateString); } }