org.kie.server.client.balancer.LoadBalancer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kie-server-client Show documentation
Show all versions of kie-server-client Show documentation
KIE Execution Server Client
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.kie.server.client.balancer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import org.kie.server.client.balancer.impl.RandomBalancerStrategy;
import org.kie.server.client.balancer.impl.RoundRobinBalancerStrategy;
import org.kie.server.common.rest.KieServerHttpRequest;
import org.kie.server.common.rest.KieServerHttpRequestException;
import org.kie.server.common.rest.NoEndpointFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadBalancer {
private static final Logger logger = LoggerFactory.getLogger(LoadBalancer.class);
private static final String URL_SEP = "\\|";
private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private final BalancerStrategy balancerStrategy;
private CopyOnWriteArraySet failedEndpoints = new CopyOnWriteArraySet();
protected LoadBalancer(BalancerStrategy balancerStrategy) {
this.balancerStrategy = balancerStrategy;
}
public String getUrl() throws KieServerHttpRequestException {
try {
String selectedUrl = balancerStrategy.next();
logger.debug("Load balancer {} selected url '{}'", balancerStrategy, selectedUrl);
return selectedUrl;
} catch (NoEndpointFoundException e) {
checkFailedEndpoints();
throw e;
}
}
public String markAsFailed(String url) {
String baseUrl = balancerStrategy.markAsOffline(url);
failedEndpoints.add(baseUrl);
logger.debug("Url '{}' is marked as failed and will be considered offline by {}", url, balancerStrategy);
return baseUrl;
}
public void activate(String url) {
String baseUrl = balancerStrategy.markAsOnline(url);
failedEndpoints.remove(baseUrl);
logger.debug("Url '{}' is marked as activated and will be considered online by {}", url, balancerStrategy);
}
public void close() {
try {
executorService.shutdownNow();
} catch (Exception e) {
logger.debug("Error when shutting down load balancer executor service");
}
}
public List getAvailableEndpoints() {
return this.balancerStrategy.getAvailableEndpoints();
}
public List getFailedEndpoints() {
return new ArrayList(failedEndpoints);
}
/*
* background operations for checking failed endpoints
*/
public Future> checkFailedEndpoints() {
return executorService.submit(new CheckFailedEndpoints());
}
/*
* factory methods
*/
public static LoadBalancer getDefault(String urls) {
String[] endpoints = new String[0];
if (urls != null) {
endpoints = urls.split(URL_SEP);
}
return getDefault(Arrays.asList(endpoints));
}
public static LoadBalancer getDefault(List urls) {
RoundRobinBalancerStrategy strategy = new RoundRobinBalancerStrategy(urls);
return new LoadBalancer(strategy);
}
public static LoadBalancer forStrategy(String urls, BalancerStrategy.Type type) {
String[] endpoints = urls.split(URL_SEP);
return forStrategy(Arrays.asList(endpoints), type);
}
public static LoadBalancer forStrategy(List urls, BalancerStrategy.Type type) {
BalancerStrategy strategy = null;
switch (type) {
case RANDOM_STRATEGY:
strategy = new RandomBalancerStrategy(urls);
break;
case ROUND_ROBIN_STRATEGY:
strategy = new RoundRobinBalancerStrategy(urls);
break;
}
if (strategy == null) {
throw new IllegalArgumentException("Unknown strategy type " + type);
}
return new LoadBalancer(strategy);
}
/*
* Runnable for checks on failed endpoints
*/
private class CheckFailedEndpoints implements Runnable {
@Override
public void run() {
if (failedEndpoints == null || failedEndpoints.isEmpty()) {
return;
}
logger.debug("Starting to scan if any of the failed endpoints is back online");
Iterator iterator = failedEndpoints.iterator();
while(iterator.hasNext()) {
String failedEndpoint = iterator.next();
try {
KieServerHttpRequest httpRequest =
KieServerHttpRequest.newRequest(failedEndpoint).followRedirects(true).timeout(1000);
httpRequest.get();
logger.debug("Url '{}' is back online, adding it to load balancer", failedEndpoint);
// first remove
// iterator.remove();
// then activate to avoid concurrent modifications on the failedEndpoints
activate(failedEndpoint);
} catch (Exception e) {
logger.debug("Url '{}' is still offline due to {}", failedEndpoint, (e.getCause() == null ? e.getMessage() : e.getCause().getMessage()));
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy