blob: d94182be0608f410195b981ab8ec16256fd1eb38 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.servi;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.NoSuchElementException;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.security.auth.login.LoginException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.statet.ecommons.rmi.core.RMIAddress;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.server.RjsComConfig;
import org.eclipse.statet.rj.servi.node.RServiNodeManager;
import org.eclipse.statet.rj.servi.node.RServiPool;
/**
* The class provides utility methods for the work with {@link RServi}.
* <p>
* It is not intend to instance the class.</p>
*/
public class RServiUtil {
public static final String RJ_SERVI_ID= "org.eclipse.statet.rj.servi";
public static final String RJ_CLIENT_ID= "org.eclipse.statet.rj.client";
/**
* Requests a {@link RServi} instance from a pool. The pool must be accessible
* via RMI under the given address.
* <p>
* The R services returned by this method are available for exclusive usage
* by the caller (consumer). The consumer is responsible to return it to the pool
* by {@link RServi#close() closing} the RServi.
*
* For SSL connections, use the prefix <code>ssl:</code>. Note that SSL requires
* the configuration of keystore and truststore at server and client side.
*
* @param address the RMI address of the pool
* @param name a name which can be used to identify the client
* @return a reference to the RServi instance
* @throws CoreException if the operation was failed; the status
* of the exception contains detail about the cause
* @throws NoSuchElementException if there is currently no free RServi
* instance available. A later call with the same configuration
* can be successfully.
* @throws LoginException if the RServi request requires authentication
*/
public static RServi getRServi(final String address, final String name) throws CoreException, NoSuchElementException, LoginException {
try {
RjsComConfig.setRMIClientSocketFactory(null);
RServiPool pool;
try {
final RMIAddress rmiAddress= new RMIAddress(address);
final Registry registry= LocateRegistry.getRegistry(rmiAddress.getHost(), rmiAddress.getPortNum(),
(rmiAddress.isSSL()) ? new SslRMIClientSocketFactory() : null );
pool= (RServiPool) registry.lookup(rmiAddress.getName());
}
catch (final MalformedURLException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Invalid address for the RServi pool.", e));
}
catch (final UnknownHostException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Invalid address for the RServi pool.", e));
}
catch (final NotBoundException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"The address does not point to a valid RServi pool.", e));
}
catch (final ClassCastException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"The address does not point to a valid/compatible RServi pool.", e));
}
catch (final RemoteException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Failed looking for RServi pool in the RMI registry.", e));
}
try {
return pool.getRServi(name, null);
}
catch (final RjException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Failed getting an RServi instance from the RServi pool.", e));
}
catch (final RemoteException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Failed looking for RServi pool in the RMI registry.", e));
}
}
finally {
RjsComConfig.clearRMIClientSocketFactory();
}
}
/**
* Requests a {@link RServi} instance from the given manager. The manager must be
* configured and started.
* <p>
* The R services returned by this method are available for exclusive usage
* by the caller (consumer). The consumer is responsible to return it to the manager
* by {@link RServi#close() closing} the RServi.
*
* @param manager manager for RServi node(s)
* @param name a name which can be used to identify the client
* @return a reference to the RServi instance
* @throws CoreException if the operation was failed; the status
* of the exception contains detail about the cause
* @throws NoSuchElementException if there is currently no free RServi
* instance available. A later call with the same configuration
* can be successfully.
*/
public static RServi getRServi(final RServiNodeManager manager, final String name) throws CoreException, NoSuchElementException {
if (manager == null) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"RServi is not available.", null));
}
try {
return manager.getRServi(name);
}
catch (final RjException e) {
throw new CoreException(new Status(IStatus.ERROR, RJ_SERVI_ID, 0,
"Failed getting an RServi instance.", e));
}
}
private RServiUtil() {
}
}