br.unb.cic.bionimbuz.plugin.AbstractPlugin.java Source code

Java tutorial

Introduction

Here is the source code for br.unb.cic.bionimbuz.plugin.AbstractPlugin.java

Source

/*
 * BioNimbuZ is a federated cloud platform.
 * Copyright (C) 2012-2015 Laboratory of Bioinformatics and Data (LaBiD),
 * Department of Computer Science, University of Brasilia, Brazil
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package br.unb.cic.bionimbuz.plugin;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import com.google.inject.Inject;

import br.unb.cic.bionimbuz.config.BioNimbusConfig;
import br.unb.cic.bionimbuz.model.FileInfo;
import br.unb.cic.bionimbuz.model.Workflow;
import br.unb.cic.bionimbuz.services.messaging.CloudMessageService;
import br.unb.cic.bionimbuz.utils.Pair;

public abstract class AbstractPlugin implements Plugin, Runnable {

    private final String id;

    private Future<PluginInfo> futureInfo = null;

    private PluginInfo myInfo = null;

    private int myCount = 0;

    private final ScheduledExecutorService schedExecutorService = Executors.newScheduledThreadPool(1,
            new BasicThreadFactory.Builder().namingPattern("bionimbus-plugin-%d").build());

    private final ConcurrentMap<String, Pair<PluginTask, Future<PluginTask>>> executingTasks = new ConcurrentHashMap<>();

    private final ConcurrentMap<String, Pair<PluginTask, Integer>> endingTasks = new ConcurrentHashMap<>();

    private final List<Future<PluginFile>> pendingSaves = new CopyOnWriteArrayList<>();

    private final List<Future<PluginGetFile>> pendingGets = new CopyOnWriteArrayList<>();

    private final ConcurrentMap<String, Pair<String, Integer>> inputFiles = new ConcurrentHashMap<>();

    private final ConcurrentMap<String, PluginFile> pluginFiles = new ConcurrentHashMap<>();

    @Inject
    public AbstractPlugin() throws IOException {
        // id provisrio
        this.id = BioNimbusConfig.get().getId();
    }

    public Map<String, Pair<String, Integer>> getInputFiles() {
        return this.inputFiles;
    }

    protected abstract Future<PluginInfo> startGetInfo();

    public abstract Future<PluginTask> startTask(PluginTask task, CloudMessageService cms, Workflow workflow);

    // private String getId() {
    public String getId() {

        return this.id;
    }

    private Future<PluginInfo> getFutureInfo() {
        return this.futureInfo;
    }

    private void setFutureInfo(Future<PluginInfo> futureInfo) {
        this.futureInfo = futureInfo;
    }

    public PluginInfo getMyInfo() {
        return this.myInfo;
    }

    // private void setMyInfo(PluginInfo info) {
    public void setMyInfo(PluginInfo info) {
        this.myInfo = info;

    }

    @Override
    public void start() {

        this.schedExecutorService.scheduleAtFixedRate(this, 0, 3, TimeUnit.MINUTES);
    }

    @Override
    public void shutdown() {
        this.schedExecutorService.shutdown();
        // service.remove(this);
    }

    @Override
    public void run() {
        this.checkGetInfo();
        this.checkFinishedTasks();
        this.checkPendingSaves();
        this.checkPendingGets();
    }

    private void checkGetInfo() {
        this.myCount++;
        if (this.myCount < 10) {
            return;
        }
        this.myCount = 0;
        // Future<PluginInfo> futureinfo = getFutureInfo(); HAVE TO CHECK
        this.futureInfo = this.getFutureInfo();
        if (this.futureInfo == null) {
            this.setFutureInfo(this.startGetInfo());
            return;
        }
        if (!this.futureInfo.isDone()) {
            return;
        }
        try {
            final PluginInfo newInfo = this.futureInfo.get();
            newInfo.setId(this.getId());

            this.setMyInfo(newInfo);
        } catch (InterruptedException | ExecutionException e) {
            this.setMyInfo(null);
        }
        this.setFutureInfo(null);
    }

    private void checkFinishedTasks() {
        Future<PluginTask> futureTask;
        PluginTask task;
        for (final Pair<PluginTask, Future<PluginTask>> pair : this.executingTasks.values()) {
            futureTask = pair.second;
            if (!futureTask.isDone()) {
                continue;
            }
            try {
                task = futureTask.get();
            } catch (InterruptedException | ExecutionException e) {
                task = pair.first;
                continue;
            }
            this.executingTasks.remove(task.getId());
            if (task.getJobInfo().getOutputs().size() > 0) {
                int count = 0;
                for (final String output : task.getJobInfo().getOutputs()) {
                    final File file = new File(output);
                    final FileInfo info = new FileInfo();
                    info.setName(output);
                    info.setSize(file.length());
                    count++;
                }
                this.endingTasks.put(task.getId(), new Pair<>(task, count));
            }
        }
    }

    private void checkPendingSaves() {
        for (final Future<PluginFile> f : this.pendingSaves) {
            if (!f.isDone()) {
                continue;
            }
            try {
                final PluginFile file = f.get();
                final List<String> pluginIds = new ArrayList<>();
                pluginIds.add(this.getId());
                file.setPluginId(pluginIds);
                this.pendingSaves.remove(f);
                this.pluginFiles.put(file.getId(), file);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
                // TODO criar mensagem de erro?
            }
        }
    }

    private void checkPendingGets() {

        for (final Future<PluginGetFile> f : this.pendingGets) {
            if (f.isDone()) {
                this.pendingGets.remove(f);
            }
        }
    }
}