blob: 01dc698dbfaf0ed8002942ae37041d741227f562 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2022 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.util.NoSuchElementException;
import javax.security.auth.login.LoginException;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.rmi.RMIAddress;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.StatusException;
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>
*/
@NonNullByDefault
public class RServiUtils {
public static final String RJ_SERVI_ID= "org.eclipse.statet.rj.servi";
public static final BundleSpec RJ_SERVI_SPEC= new BundleSpec(RJ_SERVI_ID, RServi.class);
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 StatusException 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 StatusException, NoSuchElementException, LoginException {
try {
RjsComConfig.setRMIClientSocketFactory(null);
RServiPool pool;
try {
final RMIAddress rmiAddress= new RMIAddress(address);
pool= (RServiPool) rmiAddress.lookup();
}
catch (final MalformedURLException | UnknownHostException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"Invalid address for the RServi pool.",
e ));
}
catch (final NotBoundException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"The address does not point to a valid RServi pool.",
e ));
}
catch (final ClassCastException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"The address does not point to a valid/compatible RServi pool.",
e ));
}
catch (final RemoteException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"Failed looking for RServi pool in the RMI registry.",
e ));
}
try {
return pool.getRServi(name, null);
}
catch (final RjException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"Failed getting an RServi instance from the RServi pool.",
e ));
}
catch (final RemoteException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"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 StatusException 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 @Nullable RServiNodeManager manager, final String name)
throws StatusException, NoSuchElementException {
if (manager == null) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"RServi is not available." ));
}
try {
return manager.getRServi(name);
}
catch (final RjException e) {
throw new StatusException(new ErrorStatus(RJ_SERVI_ID,
"Failed getting an RServi instance.",
e ));
}
}
private RServiUtils() {
}
}