/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch 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.elasticsearch.hadoop.integration.rest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.elasticsearch.hadoop.LocalEs; import org.elasticsearch.hadoop.cfg.Settings; import org.elasticsearch.hadoop.rest.RestClient; import org.elasticsearch.hadoop.util.SettingsUtils; import org.elasticsearch.hadoop.util.TestSettings; import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Test; import org.junit.rules.ExternalResource; import org.junit.runner.RunWith; import org.junit.runners.Suite; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; //@RunWith(Suite.class) //@Suite.SuiteClasses({ ConnectionExhaustionSuite.AbstractConnectionExhaustionTest.class }) public class ConnectionExhaustionSuite { @ClassRule public static ExternalResource resource = new LocalEs(); public static class AbstractConnectionExhaustionTest { private static final boolean POOLED = true; private static final boolean SLEEP = !POOLED; private static final boolean CHATTY = false; private static final long MAX_RUN_TIME = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES); private static final long SLEEP_TIME = 1L; private static final Settings SETTINGS = new TestSettings("connection/test"); // Simulate multiple jobs running in the environment at a time private static final String[] JOB_KEYS; static { String job1 = UUID.randomUUID().toString(); String job2 = UUID.randomUUID().toString(); String job3 = UUID.randomUUID().toString(); JOB_KEYS = new String[]{ job1, job1, job2, job3, job3, job3 }; } // @Test public void exhaustConnections() throws InterruptedException { List<Thread> threads = new ArrayList<>(); int workerNum = 0; for (String jobKey : JOB_KEYS) { final Settings workerSettings = SETTINGS.copy(); if (POOLED) { SettingsUtils.setJobTransportPoolingKey(workerSettings, jobKey); } Thread worker = new Thread(new Exhauster(++workerNum, workerSettings)); worker.start(); threads.add(worker); } for (Thread thread : threads) { thread.join(); } } private class Exhauster implements Runnable { private final Log log = LogFactory.getLog(this.getClass()); private final Settings workerSettings; private final String workerId; Exhauster(int workerNumber, Settings workerSettings) { this.workerId = "Worker # " + workerNumber; this.workerSettings = workerSettings; } @Override public void run() { long cycles = 0L; try { long startTime = System.currentTimeMillis(); long lastStatus = startTime; info("Starting time:" + startTime); info("Running until:" + (startTime + MAX_RUN_TIME)); for (long currentTime = System.currentTimeMillis(); currentTime < startTime + MAX_RUN_TIME; currentTime = System.currentTimeMillis()) { if (CHATTY) { info("" + currentTime + ": Executing GET"); } else if (lastStatus + 1000 < currentTime) { lastStatus = currentTime; info("Processing... (Cycles : " + cycles + ")"); } RestClient client = new RestClient(workerSettings); client.remoteEsVersion(); client.close(); cycles++; if (SLEEP) TimeUnit.MILLISECONDS.sleep(SLEEP_TIME); } info("Completed test without exhaustion."); info("Cycles completed: " + cycles); } catch (Exception e) { error("Completed test with example of socket exhaustion. Cycles completed at failure: " + cycles, e); } } private void info(String mesg) { log.info(workerId + ": " + mesg); } private void error(String mesg, Throwable t) { log.error(workerId + ": " + mesg, t); } } } }