org.opentcs.kernel.extensions.rmi.StandardRemoteNotificationService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentcs-kernel-extension-rmi-services Show documentation
Show all versions of opentcs-kernel-extension-rmi-services Show documentation
openTCS-Kernel-Extension-RMI-Services
/**
* Copyright (c) The openTCS Authors.
*
* This program is free software and subject to the MIT license. (For details,
* see the licensing information (LICENSE.txt) you should have received with
* this copy of the software.)
*/
package org.opentcs.kernel.extensions.rmi;
import static java.util.Objects.requireNonNull;
import jakarta.inject.Inject;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.Predicate;
import org.opentcs.access.rmi.ClientID;
import org.opentcs.access.rmi.factories.SocketFactoryProvider;
import org.opentcs.access.rmi.services.RegistrationName;
import org.opentcs.access.rmi.services.RemoteNotificationService;
import org.opentcs.components.kernel.services.NotificationService;
import org.opentcs.customizations.kernel.KernelExecutor;
import org.opentcs.data.notification.UserNotification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is the standard implementation of the {@link RemoteNotificationService} interface.
*
* Upon creation, an instance of this class registers itself with the RMI registry by the name
* {@link RegistrationName#REMOTE_NOTIFICATION_SERVICE}.
*
*/
public class StandardRemoteNotificationService
extends
KernelRemoteService
implements
RemoteNotificationService {
/**
* This class's logger.
*/
private static final Logger LOG
= LoggerFactory.getLogger(StandardRemoteNotificationService.class);
/**
* The notification service to invoke methods on.
*/
private final NotificationService notificationService;
/**
* The user manager.
*/
private final UserManager userManager;
/**
* Provides configuration data.
*/
private final RmiKernelInterfaceConfiguration configuration;
/**
* Provides socket factories used for RMI.
*/
private final SocketFactoryProvider socketFactoryProvider;
/**
* Provides the registry with which this remote service registers.
*/
private final RegistryProvider registryProvider;
/**
* Executes tasks modifying kernel data.
*/
private final ExecutorService kernelExecutor;
/**
* The registry with which this remote service registers.
*/
private Registry rmiRegistry;
/**
* Whether this remote service is initialized or not.
*/
private boolean initialized;
/**
* Creates a new instance.
*
* @param notificationService The notification service.
* @param userManager The user manager.
* @param configuration This class' configuration.
* @param socketFactoryProvider The socket factory provider used for RMI.
* @param registryProvider The provider for the registry with which this remote service registers.
* @param kernelExecutor Executes tasks modifying kernel data.
*/
@Inject
public StandardRemoteNotificationService(
NotificationService notificationService,
UserManager userManager,
RmiKernelInterfaceConfiguration configuration,
SocketFactoryProvider socketFactoryProvider,
RegistryProvider registryProvider,
@KernelExecutor
ExecutorService kernelExecutor
) {
this.notificationService = requireNonNull(notificationService, "plantModelService");
this.userManager = requireNonNull(userManager, "userManager");
this.configuration = requireNonNull(configuration, "configuration");
this.socketFactoryProvider = requireNonNull(socketFactoryProvider, "socketFactoryProvider");
this.registryProvider = requireNonNull(registryProvider, "registryProvider");
this.kernelExecutor = requireNonNull(kernelExecutor, "kernelExecutor");
}
@Override
public void initialize() {
if (isInitialized()) {
return;
}
rmiRegistry = registryProvider.get();
// Export this instance via RMI.
try {
LOG.debug("Exporting proxy...");
UnicastRemoteObject.exportObject(
this,
configuration.remoteNotificationServicePort(),
socketFactoryProvider.getClientSocketFactory(),
socketFactoryProvider.getServerSocketFactory()
);
LOG.debug("Binding instance with RMI registry...");
rmiRegistry.rebind(RegistrationName.REMOTE_NOTIFICATION_SERVICE, this);
}
catch (RemoteException exc) {
LOG.error("Could not export or bind with RMI registry", exc);
return;
}
initialized = true;
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void terminate() {
if (!isInitialized()) {
return;
}
try {
LOG.debug("Unbinding from RMI registry...");
rmiRegistry.unbind(RegistrationName.REMOTE_NOTIFICATION_SERVICE);
LOG.debug("Unexporting RMI interface...");
UnicastRemoteObject.unexportObject(this, true);
}
catch (RemoteException | NotBoundException exc) {
LOG.warn("Exception shutting down RMI interface", exc);
}
initialized = false;
}
@Override
public List fetchUserNotifications(
ClientID clientId,
Predicate predicate
) {
userManager.verifyCredentials(clientId, UserPermission.READ_DATA);
return notificationService.fetchUserNotifications(predicate);
}
@Override
public void publishUserNotification(ClientID clientId, UserNotification notification) {
userManager.verifyCredentials(clientId, UserPermission.PUBLISH_MESSAGES);
try {
kernelExecutor.submit(() -> notificationService.publishUserNotification(notification)).get();
}
catch (InterruptedException | ExecutionException exc) {
throw findSuitableExceptionFor(exc);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy