All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.datacleaner.configuration.RemoteServerConfigurationImpl Maven / Gradle / Ivy
/**
* DataCleaner (community edition)
* Copyright (C) 2014 Neopost - Customer Information Management
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.datacleaner.configuration;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.datacleaner.Version;
import org.datacleaner.descriptors.RemoteDescriptorProvider;
import org.datacleaner.job.concurrent.ScheduledTaskRunner;
import org.datacleaner.job.concurrent.TaskListener;
import org.datacleaner.job.concurrent.TaskRunner;
import org.datacleaner.job.tasks.Task;
import org.datacleaner.restclient.ComponentRESTClient;
import org.datacleaner.restclient.DataCloudUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.client.ClientHandlerException;
/**
* Implementation of {@link RemoteServerConfiguration}.
*/
public class RemoteServerConfigurationImpl implements RemoteServerConfiguration {
private class ServerStatusTask implements Task {
private List stateChanged;
private long iterCounter = 0;
@Override
public void execute() throws Exception {
stateChanged = new ArrayList<>();
if (iterCounter % OK_DELAY_MIN == 0) {
for (final RemoteServerData remoteServerData : remoteServerDataList) {
checkStatus(remoteServerData);
}
} else {
final Set errorServers = getErrorServers();
for (final String errorServer : errorServers) {
final RemoteServerData remoteServerData = getServerConfig(errorServer);
checkStatus(remoteServerData);
}
}
iterCounter++;
}
private void checkStatus(final RemoteServerData remoteServerData) {
final String serverName = remoteServerData.getServerName();
final RemoteServerState state = checkServerAvailability(remoteServerData);
final RemoteServerState oldState = actualStateMap.get(serverName);
if (!state.equals(oldState)) { //old state can be null - new remote server.
actualStateMap.put(serverName, state);
stateChanged.add(serverName);
}
}
public List getStateChanged() {
return stateChanged;
}
}
private class ServerStatusListener implements TaskListener {
@Override
public void onBegin(final Task task) {
}
@Override
public void onComplete(final Task task) {
final ServerStatusTask serverStatusTask = (ServerStatusTask) task;
for (final String changeServerName : serverStatusTask.getStateChanged()) {
notifyAllListeners(changeServerName);
}
}
@Override
public void onError(final Task task, final Throwable throwable) {
logger.error("Error in Remote server status task.", throwable);
}
}
private static final Logger logger = LoggerFactory.getLogger(RemoteServerConfigurationImpl.class);
private static final int TEST_CONNECTION_TIMEOUT = 15 * 1000; // [ms]
private static final long ERROR_DELAY_MIN = 1;
private static final long OK_DELAY_MIN = 5;
protected List remoteServerDataList;
private Map actualStateMap;
private ServerStatusTask serverStatusTask;
private ScheduledTaskRunner scheduledTaskRunner;
private List listeners = Collections.synchronizedList(new ArrayList<>());
public RemoteServerConfigurationImpl(final RemoteServerConfiguration remoteServerConfiguration,
final TaskRunner taskRunner) {
if (remoteServerConfiguration instanceof RemoteServerConfigurationImpl) {
final RemoteServerConfigurationImpl remoteServerConfigurationImpl =
(RemoteServerConfigurationImpl) remoteServerConfiguration;
actualStateMap = remoteServerConfigurationImpl.actualStateMap;
serverStatusTask = remoteServerConfigurationImpl.serverStatusTask;
scheduledTaskRunner = remoteServerConfigurationImpl.scheduledTaskRunner;
listeners = remoteServerConfigurationImpl.listeners;
remoteServerDataList = remoteServerConfigurationImpl.remoteServerDataList;
} else {
init(remoteServerConfiguration.getServerList(), taskRunner);
}
}
public RemoteServerConfigurationImpl(final List serverData, final TaskRunner taskRunner) {
init(serverData, taskRunner);
}
private void init(final List serverData, final TaskRunner taskRunner) {
actualStateMap = new ConcurrentHashMap<>();
remoteServerDataList = new ArrayList<>(serverData);
for (final RemoteServerData remoteServerData : serverData) {
actualStateMap.put(remoteServerData.getServerName(),
new RemoteServerState(RemoteServerState.State.NOT_CONNECTED, remoteServerData.getUsername(), null));
}
if (taskRunner == null || !(taskRunner instanceof ScheduledTaskRunner)) {
logger.info("Task runner isn't ScheduledTaskRunner. Remote server status task won't be scheduled.");
} else {
scheduledTaskRunner = (ScheduledTaskRunner) taskRunner;
}
}
@Override
public List getServerList() {
return Collections.unmodifiableList(remoteServerDataList);
}
@Override
public RemoteServerData getServerConfig(final String serverName) {
if (serverName == null) {
return null;
}
for (final RemoteServerData remoteServerData : remoteServerDataList) {
final String configServerName = remoteServerData.getServerName();
if (configServerName == null) {
continue;
}
if (configServerName.toLowerCase().equals(serverName.toLowerCase())) {
return remoteServerData;
}
}
return null;
}
@Override
public RemoteServerState getActualState(final String remoteServerName) {
scheduleTask();
return actualStateMap.get(remoteServerName);
}
@Override
public void addListener(final RemoteServerStateListener listener) {
scheduleTask();
listeners.add(listener);
}
@Override
public void removeListener(final RemoteServerStateListener listener) {
listeners.remove(listener);
}
private synchronized void scheduleTask() {
if (scheduledTaskRunner != null && serverStatusTask == null) {
serverStatusTask = new ServerStatusTask();
final ServerStatusListener serverStatusListener = new ServerStatusListener();
scheduledTaskRunner
.runScheduled(serverStatusTask, serverStatusListener, 0, ERROR_DELAY_MIN, TimeUnit.MINUTES);
}
}
private RemoteServerState checkServerAvailability(final RemoteServerData remoteServerData) {
if (remoteServerData.getServerName().equals(RemoteDescriptorProvider.DATACLOUD_SERVER_NAME)) {
return checkDataCloudServerAvailability(remoteServerData);
} else {
return checkOtherServerAvailability(remoteServerData);
}
}
private RemoteServerState checkDataCloudServerAvailability(final RemoteServerData remoteServerData) {
DataCloudUser dataCloudUserInfo = null;
try {
final ComponentRESTClient restClient =
new ComponentRESTClient(remoteServerData.getUrl(), remoteServerData.getUsername(),
remoteServerData.getPassword(), Version.getVersion());
dataCloudUserInfo = restClient.getDataCloudUserInfo();
} catch (final ClientHandlerException clientHandleException) {
logger.warn("DataCloud server connection problem: " + clientHandleException.getMessage());
return new RemoteServerState(RemoteServerState.State.ERROR, remoteServerData.getUsername(),
"DataCloud server connection problem.");
} catch (final Exception e) {
logger.warn("DataCloud server connection problem: " + e.getMessage());
return new RemoteServerState(RemoteServerState.State.ERROR, remoteServerData.getUsername(),
getErrorMessage(e));
}
final RemoteServerState.State state;
if (dataCloudUserInfo.getCredit() != null && dataCloudUserInfo.getCredit() > 0) {
state = RemoteServerState.State.OK;
} else {
state = RemoteServerState.State.NO_CREDIT;
}
return new RemoteServerState(state, dataCloudUserInfo.getEmail(), dataCloudUserInfo.getRealName(),
dataCloudUserInfo.getCredit(), dataCloudUserInfo.isEmailConfirmed());
}
private RemoteServerState checkOtherServerAvailability(final RemoteServerData remoteServerData) {
try (Socket socket = new Socket()) {
final URL siteURL = new URL(remoteServerData.getUrl());
int port = siteURL.getPort();
if (port <= 0) {
port = siteURL.getDefaultPort();
}
final InetSocketAddress endpoint = new InetSocketAddress(siteURL.getHost(), port);
socket.connect(endpoint, TEST_CONNECTION_TIMEOUT);
final boolean connectionCheckResult = socket.isConnected();
if (connectionCheckResult) {
return new RemoteServerState(RemoteServerState.State.OK, remoteServerData.getUsername(), null);
} else {
return new RemoteServerState(RemoteServerState.State.ERROR, remoteServerData.getUsername(), null);
}
} catch (final IOException e) {
logger.warn(
"Server '" + remoteServerData.getServerName() + "(" + remoteServerData.getUrl() + ")' is down: " + e
.getMessage());
return new RemoteServerState(RemoteServerState.State.ERROR, remoteServerData.getUsername(),
getErrorMessage(e));
}
}
protected synchronized void addRemoteData(final RemoteServerData remoteServerData) {
final String serverName = remoteServerData.getServerName();
remoteServerDataList.add(remoteServerData);
final RemoteServerState remoteServerState = checkDataCloudServerAvailability(remoteServerData);
actualStateMap.put(serverName, remoteServerState);
notifyAllListeners(serverName);
}
protected void checkStatus(final String serverName, final boolean alwaysNotify) {
final RemoteServerData serverConfig = getServerConfig(serverName);
if (serverConfig != null) {
final RemoteServerState newState = checkDataCloudServerAvailability(serverConfig);
final RemoteServerState serverState = actualStateMap.get(serverName);
if (alwaysNotify || serverState == null || !serverState.getActualState()
.equals(newState.getActualState())) {
actualStateMap.put(serverName, newState);
notifyAllListeners(serverName);
}
}
}
private void notifyAllListeners(final String remoteServerName) {
final RemoteServerState remoteServerState = actualStateMap.get(remoteServerName);
for (final RemoteServerStateListener listener : listeners) {
logger.info("Remote server {} has new state {}", remoteServerName, remoteServerState);
listener.onRemoteServerStateChange(remoteServerName, remoteServerState);
}
}
private String getErrorMessage(final Exception e) {
if (e.getCause() == null) {
return e.getMessage();
} else {
return e.getCause().getMessage();
}
}
private Set getErrorServers() {
final Set errorServers = new HashSet<>();
for (final Map.Entry serverStateEntry : actualStateMap.entrySet()) {
if (serverStateEntry.getValue().getActualState() == RemoteServerState.State.ERROR) {
errorServers.add(serverStateEntry.getKey());
}
}
return errorServers;
}
}