/** * 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.hadoop.hdfs.protocol; import java.io.IOException; import java.io.DataInput; import java.io.DataOutput; import java.util.Properties; import java.util.Enumeration; import java.util.List; import java.util.ArrayList; import java.lang.Math; import java.text.SimpleDateFormat; import java.util.Comparator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Writable; import org.apache.hadoop.io.WritableFactories; import org.apache.hadoop.io.WritableFactory; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileStatus; /** * Maintains information about one policy */ public class PolicyInfo implements Writable { public static final Log LOG = LogFactory.getLog( "org.apache.hadoop.hdfs.protocol.PolicyInfo"); protected static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); static public class PathInfo { public Path rpath; // the specified path public Properties myproperties; // intended repl factor for file PathInfo(Path rpath, Properties prop) { this.rpath = rpath; this.myproperties = prop; } public String getProperty(String name) { return myproperties.getProperty(name); } public Path getPath() { return rpath; } } private Path srcPath; // the specified src path private String description; // A verbose description of this policy private Configuration conf; // Hadoop configuration private Properties properties; // Policy-dependent properties private List<PathInfo> destPath; // all the destination paths /** * Create the empty object */ public PolicyInfo() { this.conf = null; this.description = ""; this.srcPath = null; this.destPath = null; this.properties = new Properties(); } /** * Create the metadata that describes a policy */ public PolicyInfo(String srcPath, Configuration conf) { this.conf = conf; this.description = ""; this.srcPath = new Path(srcPath); this.destPath = null; this.properties = new Properties(); } /** * Copy fields from another PolicyInfo */ public void copyFrom(PolicyInfo other) throws IOException { if (other.conf != null) { this.conf = other.conf; } if (other.description != null && other.description.length() > 0) { this.description = other.description; } if (other.srcPath != null) { this.srcPath = other.srcPath; } for (Object key : other.properties.keySet()) { String skey = (String) key; this.properties.setProperty(skey, other.properties.getProperty(skey)); } if (other.destPath != null) { for (PathInfo p:destPath) { this.addDestPath(p.rpath.toString(), p.myproperties); } } } /** * Sets the input path on which this policy has to be applied */ public void setSrcPath(String in) throws IOException { srcPath= new Path(in); if (!srcPath.isAbsolute() || !srcPath.toUri().isAbsolute()) { throw new IOException("Path " + in + " is not absolute."); } } /** * Sets the destination path on which this policy has to be applied */ public void addDestPath(String in, Properties repl) throws IOException { Path dPath = new Path(in); if (!dPath.isAbsolute() || !dPath.toUri().isAbsolute()) { throw new IOException("Path " + in + " is not absolute."); } PathInfo pinfo = new PathInfo(dPath, repl); if (this.destPath == null) { this.destPath = new ArrayList<PathInfo>(); } this.destPath.add(pinfo); } /** * Set the description of this policy. */ public void setDescription(String des) { this.description = des; } /** * Sets an internal property. * @param name property name. * @param value property value. */ public void setProperty(String name, String value) { properties.setProperty(name, value); } /** * Returns the value of an internal property. * @param name property name. */ public String getProperty(String name) { return properties.getProperty(name); } /** * Get the srcPath */ public Path getSrcPath() { return srcPath; } /** * Get the destPath */ public List<PathInfo> getDestPaths() throws IOException { return destPath; } /** * Get the Configuration */ public Configuration getConf() throws IOException { return this.conf; } /** * Convert this policy into a printable form */ public String toString() { StringBuffer buff = new StringBuffer(); buff.append("Source Path:\t" + srcPath + "\n"); for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); buff.append( name + ":\t" + properties.getProperty(name) + "\n"); } if (description.length() > 0) { int len = Math.min(description.length(), 80); String sub = description.substring(0, len).trim(); sub = sub.replaceAll("\n", " "); buff.append("Description:\t" + sub + "...\n"); } if (destPath != null) { for (PathInfo p:destPath) { buff.append("Destination Path:\t" + p.rpath + "\n"); for (Enumeration<?> e = p.myproperties.propertyNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); buff.append( name + ":\t\t" + p.myproperties.getProperty(name) + "\n"); } } } return buff.toString(); } /** * Sort Policies based on their srcPath. reverse lexicographical order. */ public static class CompareByPath implements Comparator<PolicyInfo> { public CompareByPath() throws IOException { } public int compare(PolicyInfo l1, PolicyInfo l2) { return 0 - l1.getSrcPath().compareTo(l2.getSrcPath()); } } ////////////////////////////////////////////////// // Writable ////////////////////////////////////////////////// static { // register a ctor WritableFactories.setFactory (PolicyInfo.class, new WritableFactory() { public Writable newInstance() { return new PolicyInfo(); } }); } public void write(DataOutput out) throws IOException { Text.writeString(out, srcPath.toString()); Text.writeString(out, description); out.writeInt(properties.size()); for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); Text.writeString(out, name); Text.writeString(out, properties.getProperty(name)); } out.writeInt(destPath.size()); for (PathInfo p:destPath) { Text.writeString(out, p.rpath.toString()); out.writeInt(p.myproperties.size()); for (Enumeration<?> e = p.myproperties.propertyNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); Text.writeString(out, name); Text.writeString(out, p.myproperties.getProperty(name)); } } } public void readFields(DataInput in) throws IOException { this.srcPath = new Path(Text.readString(in)); this.description = Text.readString(in); for (int n = in.readInt(); n>0; n--) { String name = Text.readString(in); String value = Text.readString(in); properties.setProperty(name,value); } for (int n = in.readInt(); n>0; n--) { String destPath = Text.readString(in); Properties p = new Properties(); for (int m = in.readInt(); m>0; m--) { String name = Text.readString(in); String value = Text.readString(in); p.setProperty(name,value); } this.addDestPath(destPath, p); } } }