blob: 177acb9be07d9129d0133da5b565b28a73f6947f [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2018 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*/
package org.eclipse.osbp.xtext.signal.common;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.osbp.xtext.signal.SignalScheduler;
import org.eclipse.osbp.xtext.signal.WatcherWithFileMask;
import org.eclipse.osbp.xtext.signal.WatcherWithFileName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* This class contains all common data to be used either from
* {@link WatcherWithFileMask} or {@link WatcherWithFileName} or
* {@link SignalScheduler}.
*/
public abstract class SignalCommonData {
/** the log */
public static Logger log = LoggerFactory.getLogger("signal");
/** the number of maximum task to be run simultaneously */
private static ArrayList<Integer> maxthreadcountinputs = new ArrayList<>();
/** the maximum thread count for parallel task execution */
private static int maxthreadcount = -1;
/** the number of thread count for parallel task execution */
public static int signalcount = 0;
/** needed for proper synchronization */
private static AtomicBoolean threadCountReady = new AtomicBoolean(false);
/** date formatter for renaming files */
private SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmssa", Locale.US);
/**
* Returns the {@link #maxthreadcount} value.
* @return {@link Integer} the maximum parallel thread count
*/
public int getMaxParallelThreadsCount() {
return maxthreadcount;
}
/**
* Reads and initializes the highest number of parallel thread processing
* allowed during the execution of watcher or a scheduler task.
*/
public void initMaxThreadCount() {
synchronized (threadCountReady) {
if(!threadCountReady.get()){
while (true) {
if (maxthreadcountinputs.size() == signalcount) {
Collections.sort(maxthreadcountinputs);
maxthreadcount = maxthreadcountinputs.get(maxthreadcountinputs.size() - 1);
threadCountReady.set(true);
break;
}
try {
Thread.sleep(SignalConstants.WAITINGTIME_FOR_WATCHER_INIT);
} catch (InterruptedException e) {
// NOSONAR
}
}
}
}
}
/**
* Sets a maximum value for the count of parallel threads to be executed.
*
* @param maxthrcount
* the max count
*/
public synchronized void setMaxParallelThreadsCount(String maxthrcount) {
try {
int value = Integer.valueOf(maxthrcount);
if (value >= 0 && value <= SignalConstants.MAXPARALLELTHREADCOUNT) {
maxthreadcountinputs.add(value);
} else if (value > SignalConstants.MAXPARALLELTHREADCOUNT) {
maxthreadcountinputs.add(SignalConstants.MAXPARALLELTHREADCOUNT);
} else {
maxthreadcountinputs.add(SignalConstants.DEFAULT_PARALLEL_THREADCOUNT);
}
} catch (NumberFormatException e) {
// log.error(String.format("getMaxParallelThreadsCount - the given
// maximum parallel threads count value [%s] is not valid.", maxthrcount));
maxthreadcountinputs.add(SignalConstants.DEFAULT_PARALLEL_THREADCOUNT);
}
}
/**
* Make sure that the given file is deleted.
*
* @param file
* the file to be deleted
* @param logidinfo
* log information from the caller
*/
public void deleteFile(final Path file, String logidinfo) {
try {
if (Files.deleteIfExists(file)) {
if (log.isDebugEnabled()) {
log.info(logidinfo + " [" + file + "] successfuly removed.");
}
} else {
if (log.isDebugEnabled()) {
log.info(logidinfo + " [" + file + "] doesn't exist and could not be removed.");
}
}
} catch (IOException e) {
log.error(logidinfo + " [" + file + "] could not be deleted.\n" + e.getMessage());
}
}
/**
* Renames the given file with the given new name. If a file with the given
* new name already exists then a number offset will be added to it.
* @param file the file to rename
* @param logidinfo information on the caller of this function
*/
public void renameFile(final Path file, String logidinfo) {
try {
if(Files.exists(file)){
String filename = file.getFileName().toString();
String newname = ("FAILEDIMPORT"+ formatter.format(new Date(System.currentTimeMillis())) + filename + ".LOCKED");
int renameTry = 0;
boolean done = false;
String tempname = newname;
String extension = newname.substring(newname.length()-4);
do{
try{
Files.move(file, file.resolveSibling(tempname));
done = true;
}catch (FileAlreadyExistsException ae) {
renameTry ++;
tempname = newname.replace(extension, renameTry+extension);
}
}while(!done);
log.info(String.format("%s file [%s] renamed to %s.", logidinfo, filename, tempname));
}
else{
log.info(String.format("%s file [%s] doesn't exist and could not be renamed.", logidinfo, file));
}
} catch (IOException e) {
log.error(String.format("%s file [%s] could not be renamed.\n%s", logidinfo, file, e.getMessage()));
}
}
/**
* Creates an executor service with the given maximum amount of thread that
* can run in parallel, with no idle thread allowed.
*
* @param poolname
* - the name of the thread pool
* @param maxparallelthreadcount
* - the maximum number of threads to allow in thepool
* @param keepAliveTime
* - when the number of threads is greater thanthe core, this is
* the maximum time that excess idle threadswill wait for new
* tasks before terminating
* @return {@link ExecutorService} the executor service
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public ExecutorService createCustomExecutorService(String poolname, int maxparallelthreadcount, long keepAliveTime) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(maxparallelthreadcount, maxparallelthreadcount, keepAliveTime,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),new ThreadFactoryBuilder().setNameFormat(poolname + "Pool-Thread-%d").build());
return pool;
}
/**
* Gives the {@link #formatter}.
* @return {@link SimpleDateFormat}
*/
public SimpleDateFormat getFormatter(){
return formatter;
}
}