Java tutorial
/* * Copyright 2015 Adobe. * * Licensed 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 com.adobe.ags.curly.controller; import com.adobe.ags.curly.ApplicationState; import com.adobe.ags.curly.xml.Action; import com.adobe.ags.curly.model.BatchRunnerResult; import com.adobe.ags.curly.model.RunnerResult; import com.adobe.ags.curly.model.TaskRunner; import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.beans.property.StringProperty; import org.apache.http.impl.client.CloseableHttpClient; public class BatchRunner implements TaskRunner { BatchRunnerResult result; BlockingQueue<Runnable> tasks; ThreadPoolExecutor executor; int concurrency; ThreadLocal<CloseableHttpClient> clientThread; Runnable buildWorkerPool; public BatchRunner(AuthHandler auth, int concurrency, List<Action> actions, List<Map<String, String>> batchData, Map<String, StringProperty> defaultValues, Set<String> displayColumns) { clientThread = ThreadLocal.withInitial(auth::getAuthenticatedClient); result = new BatchRunnerResult(); tasks = new ArrayBlockingQueue<>(batchData.size()); this.concurrency = concurrency; defaultValues.put("server", new ReadOnlyStringWrapper(auth.getUrlBase())); buildWorkerPool = () -> buildTasks(actions, batchData, defaultValues, displayColumns); } @Override public RunnerResult getResult() { return result; } @Override public void run() { try { ApplicationState.getInstance().runningProperty().set(true); executor = new ThreadPoolExecutor(concurrency, concurrency, 1, TimeUnit.DAYS, tasks); executor.allowCoreThreadTimeOut(true); result.start(); buildWorkerPool.run(); executor.shutdown(); executor.awaitTermination(1, TimeUnit.DAYS); result.stop(); } catch (InterruptedException ex) { Logger.getLogger(BatchRunner.class.getName()).log(Level.SEVERE, null, ex); if (!executor.isShutdown()) { executor.getQueue().clear(); } } result.stop(); } private void buildTasks(List<Action> actions, List<Map<String, String>> batchData, Map<String, StringProperty> defaultValues, Set<String> displayColumns) { int row = 0; for (Map<String, String> data : batchData) { row++; try { Map<String, String> values = new HashMap<>(data); defaultValues.forEach((key, value) -> { if (values.get(key) == null || values.get(key).isEmpty()) { values.put(key, value.get()); } }); ActionGroupRunner runner = new ActionGroupRunner("Row " + row, this::getConnection, actions, values, displayColumns); result.addDetail(runner.results); executor.execute(runner); } catch (ParseException ex) { Logger.getLogger(BatchRunner.class.getName()).log(Level.SEVERE, null, ex); } } } private CloseableHttpClient getConnection(boolean getNewOne) { if (getNewOne) { clientThread.remove(); } return clientThread.get(); } }