/** * 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.Entities; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.falcon.entity.v0.EntityType; import org.apache.falcon.entity.v0.cluster.ACL; import org.apache.falcon.entity.v0.cluster.Cluster; import org.apache.falcon.entity.v0.cluster.ClusterLocationType; import org.apache.falcon.entity.v0.cluster.Interface; import org.apache.falcon.entity.v0.cluster.Interfaces; import org.apache.falcon.entity.v0.cluster.Interfacetype; import org.apache.falcon.entity.v0.cluster.Location; import org.apache.falcon.entity.v0.cluster.Locations; import org.apache.falcon.entity.v0.cluster.Properties; import org.apache.falcon.entity.v0.cluster.Property; import org.apache.falcon.regression.core.util.Util; import org.apache.log4j.Logger; import org.testng.Assert; import org.testng.asserts.SoftAssert; import javax.xml.bind.JAXBException; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** Class for representing a cluster xml. */ public class ClusterMerlin extends Cluster { private static final Logger LOGGER = Logger.getLogger(ClusterMerlin.class); public ClusterMerlin(String clusterData) { final Cluster cluster = (Cluster) TestEntityUtil.fromString(EntityType.CLUSTER, clusterData); try { PropertyUtils.copyProperties(this, cluster); } catch (ReflectiveOperationException e) { Assert.fail("Can't create ClusterMerlin: " + ExceptionUtils.getStackTrace(e)); } } @Override public String toString() { try { StringWriter sw = new StringWriter(); EntityType.CLUSTER.getMarshaller().marshal(this, sw); return sw.toString(); } catch (JAXBException e) { throw new RuntimeException(e); } } /** * Sets unique names for the cluster. * @return mapping of old name to new name * @param prefix prefix of new name */ public Map<? extends String, ? extends String> setUniqueName(String prefix) { final String oldName = getName(); final String newName = TestEntityUtil.generateUniqueName(prefix, oldName); setName(newName); final HashMap<String, String> nameMap = new HashMap<>(1); nameMap.put(oldName, newName); return nameMap; } /** * Set ACL. */ public void setACL(String owner, String group, String permission) { ACL acl = new ACL(); acl.setOwner(owner); acl.setGroup(group); acl.setPermission(permission); this.setACL(acl); } public void setInterface(Interfacetype interfacetype, String endpoint, String version) { final Interfaces interfaces = this.getInterfaces(); final List<Interface> interfaceList = interfaces.getInterfaces(); for (final Interface anInterface : interfaceList) { if (anInterface.getType() == interfacetype) { anInterface.setEndpoint(endpoint); if (StringUtils.isNotBlank(version)) { anInterface.setVersion(version); } } } } public void setWorkingLocationPath(String path) { for (Location location : getLocations().getLocations()) { if (location.getName() == ClusterLocationType.WORKING) { location.setPath(path); break; } } } public String getInterfaceEndpoint(final Interfacetype interfaceType) { String value = null; for (Interface anInterface : getInterfaces().getInterfaces()) { if (anInterface.getType() == interfaceType) { value = anInterface.getEndpoint(); } } LOGGER.info("Cluster: " + getName() + " interfaceType: " + interfaceType + " value:" + value); return value; } public String getProperty(final String propName) { String value = null; for (Property property : getProperties().getProperties()) { if (property.getName().trim().equals(propName.trim())) { value = property.getValue(); } } LOGGER.info("Cluster: " + getName() + " property: " + propName + " value:" + value); return value; } public String getLocation(final String locationType) { String value = null; for (Location location : getLocations().getLocations()) { if (location.getName().name().trim().equalsIgnoreCase(locationType.trim().toLowerCase())) { value = location.getPath(); } } LOGGER.info("Cluster: " + getName() + " locationType: " + locationType + " value:" + value); return value; } /** * Cleans all properties and returns empty cluster as a draft (as we can't create cluster e.g from empty string). */ public ClusterMerlin getEmptyCluster() { ClusterMerlin clusterMerlin = new ClusterMerlin(this.toString()); clusterMerlin.setName(""); clusterMerlin.setDescription(null); clusterMerlin.setColo(null); clusterMerlin.setTags(null); clusterMerlin.setInterfaces(new Interfaces()); clusterMerlin.setLocations(new Locations()); clusterMerlin.getACL().setGroup(""); clusterMerlin.getACL().setOwner(""); clusterMerlin.setProperties(new Properties()); return clusterMerlin; } public void addLocation(ClusterLocationType type, String path) { Location newLocation = new Location(); newLocation.setName(type); newLocation.setPath(path); getLocations().getLocations().add(newLocation); } /** * Add/replace a property. * @param name name of the property * @param value value of the property * @return this */ public ClusterMerlin withProperty(String name, String value) { final List<Property> properties = getProperties().getProperties(); //if property with same name exists, just replace the value for (Property property : properties) { if (property.getName().equals(name)) { LOGGER.info(String.format("Overwriting property name = %s oldVal = %s newVal = %s", property.getName(), property.getValue(), value)); property.setValue(value); return this; } } //if property is not added already, add it final Property property = new Property(); property.setName(name); property.setValue(value); properties.add(property); return this; } public void addInterface(Interfacetype type, String endpoint, String version) { Interface iface = new Interface(); iface.setType(type); iface.setEndpoint(endpoint); iface.setVersion(version); getInterfaces().getInterfaces().add(iface); } public void assertEquals(ClusterMerlin cluster) { LOGGER.info(String.format("Comparing : source: %n%s%n and cluster: %n%n%s", Util.prettyPrintXml(toString()), Util.prettyPrintXml(cluster.toString()))); SoftAssert softAssert = new SoftAssert(); softAssert.assertEquals(name, cluster.getName(), "Cluster name is different."); softAssert.assertEquals(colo, cluster.getColo(), "Cluster colo is different."); softAssert.assertEquals(description, cluster.getDescription(), "Cluster description is different."); softAssert.assertEquals(tags, cluster.getTags(), "Cluster tags are different."); softAssert.assertTrue(interfacesEqual(interfaces.getInterfaces(), cluster.getInterfaces().getInterfaces()), "Cluster interfaces are different"); softAssert.assertTrue(locationsEqual(locations.getLocations(), cluster.getLocations().getLocations()), "Cluster locations are different"); softAssert.assertEquals(acl.getGroup(), cluster.getACL().getGroup(), "Cluster acl group is different."); softAssert.assertEquals(acl.getOwner(), cluster.getACL().getOwner(), "Cluster acl owner is different."); softAssert.assertEquals(acl.getPermission(), cluster.getACL().getPermission(), "Cluster acl permissions is different."); softAssert.assertTrue(propertiesEqual(properties.getProperties(), cluster.getProperties().getProperties()), "Cluster properties are different."); softAssert.assertAll(); } private static boolean checkEquality(String str1, String str2, String message){ if (!str1.equals(str2)) { LOGGER.info(String.format("Cluster %s are different: %s and %s.", message, str1, str2)); return false; } return true; } private static boolean interfacesEqual(List<Interface> srcInterfaces, List<Interface> trgInterfaces) { if (srcInterfaces.size() == trgInterfaces.size()) { boolean equality = false; for(Interface iface1: srcInterfaces){ for(Interface iface2 : trgInterfaces) { if (iface2.getType().value().equals(iface1.getType().value())) { equality = checkEquality(iface1.getEndpoint(), iface2.getEndpoint(), iface1.getType().value() + " interface endpoints"); equality &= checkEquality(iface1.getVersion(), iface2.getVersion(), iface1.getType().value() + " interface versions"); } } } return equality; } else { return false; } } private static boolean propertiesEqual(List<Property> srcProps, List<Property> trgProps) { if (srcProps.size() == trgProps.size()) { boolean equality = true; for(Property prop1: srcProps){ for(Property prop2 : trgProps) { if (prop2.getName().equals(prop1.getName())) { equality &= checkEquality(prop1.getValue(), prop2.getValue(), prop1.getName() + " property values"); } } } return equality; } else { return false; } } /** * Compares two lists of locations. */ private static boolean locationsEqual(List<Location> srcLocations, List<Location> objLocations) { if (srcLocations.size() != objLocations.size()) { return false; } nextType: for (ClusterLocationType type : ClusterLocationType.values()) { List<Location> locations1 = new ArrayList<>(); List<Location> locations2 = new ArrayList<>(); //get locations of the same type for (int i = 0; i < srcLocations.size(); i++) { if (srcLocations.get(i).getName() == type) { locations1.add(srcLocations.get(i)); } if (objLocations.get(i).getName() == type) { locations2.add(objLocations.get(i)); } } //compare locations of the same type. At least 1 match should be present. if (locations1.size() != locations2.size()) { return false; } for (Location location1 : locations1) { for (Location location2 : locations2) { if (location1.getPath().equals(location2.getPath())) { continue nextType; } } } return false; } return true; } public Location getLocation(ClusterLocationType type) { List<Location> locationsOfType = new ArrayList<>(); for(Location location : locations.getLocations()) { if (location.getName() == type) { locationsOfType.add(location); } } Assert.assertEquals(locationsOfType.size(), 1, "Unexpected number of " + type + " locations in: " + this); return locationsOfType.get(0); } @Override public EntityType getEntityType() { return EntityType.CLUSTER; } }