blob: 912a49f9db4905ef72d121e012da5d3694e0e546 [file] [log] [blame]
/*
* 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.iotdb.commons.executable;
import org.apache.iotdb.commons.trigger.exception.TriggerJarTooLargeException;
import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
public class ExecutableManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ExecutableManager.class);
protected static final String INSTALL_DIR = "install";
protected final String temporaryLibRoot;
protected final String libRoot;
protected final AtomicLong requestCounter;
public ExecutableManager(String temporaryLibRoot, String libRoot) {
this.temporaryLibRoot = temporaryLibRoot;
this.libRoot = libRoot;
requestCounter = new AtomicLong(0);
}
// ======================================================
// region download related
// ======================================================
public ExecutableResource request(List<String> uris) throws URISyntaxException, IOException {
final long requestId = generateNextRequestId();
downloadExecutables(uris, requestId);
return new ExecutableResource(requestId, getDirStringUnderTempRootByRequestId(requestId));
}
private synchronized long generateNextRequestId() throws IOException {
long requestId = requestCounter.getAndIncrement();
while (FileUtils.isDirectory(getDirUnderTempRootByRequestId(requestId))) {
requestId = requestCounter.getAndIncrement();
}
FileUtils.forceMkdir(getDirUnderTempRootByRequestId(requestId));
return requestId;
}
private void downloadExecutables(List<String> uris, long requestId)
throws IOException, URISyntaxException {
// TODO: para download
try {
for (String uriString : uris) {
final URL url = new URI(uriString).toURL();
final String fileName = uriString.substring(uriString.lastIndexOf("/") + 1);
final String destination =
temporaryLibRoot + File.separator + requestId + File.separator + fileName;
FileUtils.copyURLToFile(url, FSFactoryProducer.getFSFactory().getFile(destination));
}
} catch (Exception e) {
removeFromTemporaryLibRoot(requestId);
throw e;
}
}
public void moveFileUnderTempRootToExtLibDir(ExecutableResource resource, String name)
throws IOException {
FileUtils.moveFileToDirectory(
getFileByFullPath(
getDirStringUnderTempRootByRequestId(resource.getRequestId()) + File.separator + name),
getFileByFullPath(libRoot),
false);
}
// endregion
// ======================================================
// region File under LibRoot
// ======================================================
public void copyFileToExtLibDir(String filePath) throws IOException {
FileUtils.copyFileToDirectory(
FSFactoryProducer.getFSFactory().getFile(filePath),
FSFactoryProducer.getFSFactory().getFile(this.libRoot));
}
public void removeFileUnderLibRoot(String fileName) throws IOException {
Path path = Paths.get(this.libRoot + File.separator + fileName);
Files.deleteIfExists(path);
}
public boolean hasFileUnderLibRoot(String fileName) {
return Files.exists(Paths.get(this.libRoot + File.separator + fileName));
}
public boolean hasFileUnderInstallDir(String fileName) {
return Files.exists(
Paths.get(this.libRoot + File.separator + INSTALL_DIR + File.separator + fileName));
}
// endregion
// ======================================================
// region File under temporaryLibRoot
// ======================================================
public boolean hasFileUnderTemporaryRoot(String fileName) {
return Files.exists(Paths.get(this.temporaryLibRoot + File.separator + fileName));
}
private void removeFromTemporaryLibRoot(long requestId) {
FileUtils.deleteQuietly(getDirUnderTempRootByRequestId(requestId));
}
public void saveTextAsFileUnderTemporaryRoot(String text, String fileName) throws IOException {
Path path = Paths.get(this.temporaryLibRoot + File.separator + fileName);
Files.deleteIfExists(path);
Files.write(path, text.getBytes());
}
public void removeFileUnderTemporaryRoot(String fileName) throws IOException {
Path path = Paths.get(this.temporaryLibRoot + File.separator + fileName);
Files.deleteIfExists(path);
}
public String readTextFromFileUnderTemporaryRoot(String fileName) throws IOException {
Path path = Paths.get(this.temporaryLibRoot + File.separator + fileName);
return new String(Files.readAllBytes(path));
}
// endregion
// ======================================================
// region file string and file generation
// ======================================================
public File getDirUnderTempRootByRequestId(long requestId) {
return FSFactoryProducer.getFSFactory()
.getFile(getDirStringUnderTempRootByRequestId(requestId));
}
public String getDirStringUnderTempRootByRequestId(long requestId) {
return temporaryLibRoot + File.separator + requestId + File.separator;
}
public File getDirUnderLibRootByName(String name) {
return FSFactoryProducer.getFSFactory().getFile(getDirStringUnderLibRootByName(name));
}
public String getDirStringUnderLibRootByName(String name) {
return libRoot + File.separator + name + File.separator;
}
public File getFileUnderLibRootByName(String name) {
return FSFactoryProducer.getFSFactory().getFile(getFileStringUnderLibRootByName(name));
}
public String getFileStringUnderLibRootByName(String name) {
return libRoot + File.separator + name;
}
public String getFileStringUnderInstallByName(String name) {
return libRoot + File.separator + INSTALL_DIR + File.separator + name;
}
private File getFileByFullPath(String path) {
return FSFactoryProducer.getFSFactory().getFile(path);
}
// endregion
// ======================================================
// region other functions
// ======================================================
public static ByteBuffer transferToBytebuffer(String filePath) throws IOException {
try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath), StandardOpenOption.READ)) {
long size = fileChannel.size();
if (size > Integer.MAX_VALUE) {
// Max length of Thrift Binary is Integer.MAX_VALUE bytes.
throw new TriggerJarTooLargeException(
String.format("Size of file exceed %d bytes", Integer.MAX_VALUE));
}
ByteBuffer byteBuffer = ByteBuffer.allocate((int) size);
fileChannel.read(byteBuffer);
byteBuffer.flip();
return byteBuffer;
} catch (Exception e) {
LOGGER.warn(
"Error occurred during transferring file{} to ByteBuffer, the cause is {}", filePath, e);
throw e;
}
}
/**
* Create and save the file if the specified file does not exist, or this method will override the
* existing file.
*/
protected void saveToDir(ByteBuffer byteBuffer, String destination) throws IOException {
try {
Path path = Paths.get(destination);
if (!Files.exists(path)) {
Files.createFile(path);
}
// FileOutPutStream is not in append mode by default, so the file will be overridden if it
// already exists.
try (FileOutputStream outputStream = new FileOutputStream(destination)) {
outputStream.getChannel().write(byteBuffer);
outputStream.getFD().sync();
}
} catch (IOException e) {
LOGGER.warn(
"Error occurred during writing bytebuffer to {} , the cause is {}", destination, e);
throw e;
}
}
/**
* @param byteBuffer file
* @param fileName The name of the file. Absolute Path will be libRoot + File_Separator + fileName
*/
public void saveToLibDir(ByteBuffer byteBuffer, String fileName) throws IOException {
String destination = this.libRoot + File.separator + fileName;
saveToDir(byteBuffer, destination);
}
/**
* @param byteBuffer file
* @param fileName Absolute Path will be libRoot + File_Separator + INSTALL_DIR + File.separator +
* fileName
*/
public void saveToInstallDir(ByteBuffer byteBuffer, String fileName) throws IOException {
String destination = this.libRoot + File.separator + INSTALL_DIR + File.separator + fileName;
saveToDir(byteBuffer, destination);
}
// endregion
public String getTemporaryLibRoot() {
return temporaryLibRoot;
}
public String getLibRoot() {
return libRoot;
}
public String getInstallDir() {
return libRoot + File.separator + INSTALL_DIR;
}
}