/*
* Copyright 2017 EMC Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* or in the "license" file accompanying this file. This file 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 com.emc.ecs.sync.config.storage;
import com.emc.ecs.sync.config.AbstractConfig;
import com.emc.ecs.sync.config.annotation.*;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.emc.ecs.sync.config.storage.NfsConfig.URI_PREFIX;
@XmlRootElement
@StorageConfig(uriPrefix = URI_PREFIX)
@Label("NFS")
@Documentation("The nfs plugin reads/writes data from/to an nfs file or directory. " +
"It is triggered by the URI:\n" +
"nfs://server/<mount_root_path>, e.g." +
"nfs://myserver/home/user/myfiles.\n" +
"If <code>path</code> refers to a file, only that file will be " +
"synced. If a directory is specified, the contents of " +
"the directory will be synced. Unless the --non-recursive " +
"flag is set, the subdirectories will also be recursively " +
"synced. To preserve object metadata on the target filesystem, " +
"or to read back preserved metadata, use --store-metadata.")
public class NfsConfig extends AbstractConfig {
static final String URI_PREFIX = "nfs:";
private static final Pattern URI_PATTERN = Pattern.compile("^nfs://([^/]+)(/[^?]*)$");
protected String server;
protected String mountPath;
protected String path;
private boolean followLinks = false;
private boolean storeMetadata = false;
private long deleteOlderThan = 0;
private String modifiedSince;
private String[] excludedPaths;
@XmlTransient
@UriGenerator
public String getUri() {
return URI_PREFIX + "//" + bin(server) + bin(mountPath);
}
@UriParser
public void setUri(String uri) {
Matcher matcher = URI_PATTERN.matcher(uri);
if (matcher.matches()) {
setServer(matcher.group(1));
setMountPath(matcher.group(2));
} else {
throw new RuntimeException("invalid file URI");
}
}
@Option(orderIndex = 10, locations = Option.Location.Form, required = true, description = "Nfs mount server.")
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
@Option(orderIndex = 20, locations = Option.Location.Form, required = true, description = "Path to the mount root.")
public String getMountPath() {
return mountPath;
}
public void setMountPath(String path) {
this.mountPath = path;
}
@Option(orderIndex = 30, description = "Path to the primary file or directory from the mount root.")
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Option(orderIndex = 40, advanced = true, description = "Instead of preserving symbolic links, follow them and sync the actual files")
public boolean isFollowLinks() {
return followLinks;
}
public void setFollowLinks(boolean followLinks) {
this.followLinks = followLinks;
}
@Option(orderIndex = 50, advanced = true, description = "When used as a target, stores source metadata in a json file, since NFS filesystems have no concept of user metadata")
public boolean isStoreMetadata() {
return storeMetadata;
}
public void setStoreMetadata(boolean storeMetadata) {
this.storeMetadata = storeMetadata;
}
@Option(orderIndex = 60, advanced = true, valueHint = "delete-age", description = "When --delete-source is used, add this option to only delete files that have been modified more than <delete-age> milliseconds ago")
public long getDeleteOlderThan() {
return deleteOlderThan;
}
public void setDeleteOlderThan(long deleteOlderThan) {
this.deleteOlderThan = deleteOlderThan;
}
@Option(orderIndex = 70, advanced = true, valueHint = "yyyy-MM-ddThh:mm:ssZ", description = "Only look at files that have been modified since the specific date/time. Date/time should be provided in ISO-8601 UTC format (i.e. 2015-01-01T04:30:00Z)")
public String getModifiedSince() {
return modifiedSince;
}
/**
* Date/time should be provided in ISO-8601 UTC format (i.e. 2015-01-01T04:30:00Z)
*/
public void setModifiedSince(String modifiedSince) {
this.modifiedSince = modifiedSince;
}
@Option(orderIndex = 80, valueHint = "regex-pattern", description = "A list of regular expressions to search against the full file path. If the path matches, the file will be skipped. Since this is a regular expression, take care to escape special characters. For example, to exclude all .snapshot directories, the pattern would be .*/\\.snapshot. Specify multiple entries by repeating the CLI option or using multiple lines in the UI form")
public String[] getExcludedPaths() {
return excludedPaths;
}
public void setExcludedPaths(String[] excludedPaths) {
this.excludedPaths = excludedPaths;
}
}