/*
* Copyright (c) 2008-2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.client.impl;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DbCheckerFileWriter {
static final String WRITER_STORAGEOS = "StorageOS";
static final String WRITER_GEOSTORAGEOS = "GeoStorageOS";
static final String WRITER_REBUILD_INDEX = "RebuildIndex";
private final static String FILE_PATH = "/tmp/";
static final String CLEANUP_FILE_STORAGEOS = FILE_PATH + "cleanup-StorageOS.cql";
static final String CLEANUP_FILE_GEOSTORAGEOS = FILE_PATH + "cleanup-GeoStorageOS.cql";
static final String CLEANUP_FILE_REBUILD_INDEX = FILE_PATH + "cleanup-RebuildIndex.file";
public static final String COMMENT_CHAR = "--";
private static final String USAGE_COMMON_LINE1 = "This file is inconsistent data generated by Database Consistency Checker, please be much cautious playing with it.";
private static final String USAGE_COMMON_LINE2 = "You can use the following command to clean up these inconsistent data. [Generated Date: %s]";
private static final String USAGE_COMMON_LINE2_WITH_DATE = String.format(USAGE_COMMON_LINE2, new Date());
private static final String USAGE_STORAGEOS = String.format("%s %s\n%s %s\n%s /opt/storageos/bin/cqlsh -k StorageOS -f %s\n",
COMMENT_CHAR, USAGE_COMMON_LINE1, COMMENT_CHAR, USAGE_COMMON_LINE2_WITH_DATE, COMMENT_CHAR, CLEANUP_FILE_STORAGEOS);
private static final String USAGE_GEOSTORAGEOS = String.format(
"%s %s\n%s %s\n%s /opt/storageos/bin/cqlsh -k GeoStorageOS -f %s localhost 9260\n",
COMMENT_CHAR, USAGE_COMMON_LINE1, COMMENT_CHAR, USAGE_COMMON_LINE2_WITH_DATE, COMMENT_CHAR, CLEANUP_FILE_GEOSTORAGEOS);
private static final String USAGE_REBUILDINDEX = String.format("%s %s\n%s %s\n%s /opt/storageos/bin/dbutils rebuild_index %s\n",
COMMENT_CHAR, USAGE_COMMON_LINE1, COMMENT_CHAR, USAGE_COMMON_LINE2_WITH_DATE, COMMENT_CHAR, CLEANUP_FILE_REBUILD_INDEX);
private static final String STORAGEOS_NAME = "storageos";
private static String owner = STORAGEOS_NAME;
private static String group = STORAGEOS_NAME;
private static final Map<String, String> cleanupFiles = new ConcurrentHashMap<>();
private static final Map<String, BufferedWriter> writers = new ConcurrentHashMap<>();
private static final Logger log = LoggerFactory.getLogger(DbCheckerFileWriter.class);
private DbCheckerFileWriter() {
}
static void writeTo(String name, String lineStr) {
try {
BufferedWriter writer = getWriter(name);
writeln(writer, lineStr);
} catch (IOException e) {
System.out.println("Exception: " + e);
log.error("Caught Exception: ", e);
}
}
private static BufferedWriter getWriter(String name) throws IOException {
WriteType type = WriteType.getByType(name);
BufferedWriter writer = writers.get(type.filename);
if (writer == null) {
writer = init(type.filename, type.usage);
writers.put(type.filename, writer);
if (!cleanupFiles.containsKey(name)) {
cleanupFiles.put(name, type.filename);
}
}
return writer;
}
private static BufferedWriter init(String fileName, String usage) throws IOException {
deleteIfExists(fileName);
final Path filePath = FileSystems.getDefault().getPath(fileName);
BufferedWriter writer = Files.newBufferedWriter(filePath, Charset.defaultCharset());
Set<PosixFilePermission> perms = EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE);
setFilePermissions(filePath, owner, group, perms);
writeln(writer, usage);
return writer;
}
private static void writeln(BufferedWriter writer, String str) throws IOException {
writer.write(str);
writer.newLine();
writer.flush();
}
public static void close() {
for (Writer writer : writers.values()) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
log.error("Exception happens when closing file, e=", e);
}
}
writers.clear();
cleanupFiles.clear();
}
public static String getGeneratedFileNames() {
return StringUtils.join(cleanupFiles.values(), " ");
}
public static Map<String, String> getCleanupfileMap() {
return cleanupFiles;
}
private static void deleteIfExists(String fileName) {
File file = new File(fileName);
if (file.exists()) {
file.delete();
}
}
private static void setFilePermissions(Path path, String owner, String groupName,
Set<PosixFilePermission> permissions) throws IOException {
UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
UserPrincipal user = lookupService.lookupPrincipalByName(owner);
GroupPrincipal group = lookupService.lookupPrincipalByGroupName(groupName);
PosixFileAttributeView attributeView = Files.getFileAttributeView(path, PosixFileAttributeView.class);
attributeView.setGroup(group);
attributeView.setOwner(user);
Files.setPosixFilePermissions(path, permissions);
}
public static enum WriteType {
STORAGEOS(WRITER_STORAGEOS, CLEANUP_FILE_STORAGEOS, USAGE_STORAGEOS),
GEOSTORAGEOS(WRITER_GEOSTORAGEOS, CLEANUP_FILE_GEOSTORAGEOS, USAGE_GEOSTORAGEOS),
REBUILD_INDEX(WRITER_REBUILD_INDEX, CLEANUP_FILE_REBUILD_INDEX, USAGE_REBUILDINDEX),
//just for UT
TEST("Test", CLEANUP_FILE_STORAGEOS, USAGE_STORAGEOS);
String type;
String filename;
String usage;
WriteType(String type, String filename, String usage) {
this.type = type;
this.filename = filename;
this.usage = usage;
}
public static WriteType getByType(String type) {
for (WriteType writeType : values()) {
if (writeType.type.equals(type)) {
return writeType;
}
}
throw new RuntimeException("invalid type:" + type);
}
}
}