/** * Copyright (c) 2012 - 2018 Data In Motion and others. * All rights reserved. * * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Data In Motion - initial API and implementation */ package org.gecko.rsa.discovery; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import org.gecko.rsa.api.ExportEndpointHandler; import org.osgi.framework.BundleContext; import org.osgi.service.remoteserviceadmin.EndpointEventListener; /** * Basic endpoint description discovery. * It handles the import of service descriptions from foreign frameworks as well as * the export of service descriptions that needs to be exported to other frameworks. * * To export descriptions, the discovery, resp. the {@link ExportingEndpointListener} * registers itself a {@link EndpointEventListener}. * * To import a service we need to listen to other {@link EndpointEventListener} that are * usually either topology managers or other discoveries. But We only want to listen for * topology managers in that case * * @author Mark Hoffmann * @since 29.03.2019 */ public class EndpointDiscovery { private static final Logger logger = Logger.getLogger(EndpointDiscovery.class.getName()); private final AtomicBoolean start = new AtomicBoolean(false); private final String discoveryId; private transient BundleContext bctx; private ExportingEndpointListener exportingEndpointListener; private ImportingEndpointManager importingEndpointManager; private ExportEndpointHandler exportHandler = null; /** * Creates a new instance. * @param the bundle context * @param the name that is distinguish for this discovery */ public EndpointDiscovery(BundleContext bctx, String discoveryId) { this.bctx = bctx; this.discoveryId = discoveryId; } /** * Creates a new instance. * @param the bundle context * @param the name that is distinguish for this discovery */ public EndpointDiscovery(BundleContext bctx, String discoveryId, ExportEndpointHandler exportHandler) { this.bctx = bctx; this.discoveryId = discoveryId; this.exportHandler = exportHandler; } public ImportingEndpointManager getImportingEndpointManager() { return this.importingEndpointManager; } public ExportingEndpointListener getExportingEndpointListener() { return exportingEndpointListener; } /** * Starts the end-point description provider. * It tracks local published from the topology manager as well as remote end-points * that are received from the service registry */ public void start() { if (start.compareAndSet(false, true)) { doStart(); } else { logger.log(Level.INFO, String.format("[%s] Discovery is already started", discoveryId)); } } /** * Stops the messaging adapter discovery */ public void stop() { if (start.compareAndSet(true, false)) { doStop(); } else { logger.log(Level.INFO, String.format("[%s] Discovery was not started yet", discoveryId)); } } /** * Returns true, if the discovery is running * @return true, if the discovery is running */ public boolean isRunning() { return start.get(); } /** * Executes the start logic. */ protected void doStart() { /* * Creation of the manager that handles incoming/importing service descriptions. * It is then responsible to delegate the description to a corresponding topology manager */ importingEndpointManager = new ImportingEndpointManager(discoveryId); /* * Register listener that listens for service descriptions of local services, that needs * to be exported to other frameworks. These are triggered from the topology managers */ exportingEndpointListener = new ExportingEndpointListener(exportHandler, discoveryId); exportingEndpointListener.start(bctx); importingEndpointManager.start(bctx); } /** * Stops and cleans up everything */ protected void doStop() { try { if (importingEndpointManager != null) { importingEndpointManager.close(); } if (exportingEndpointListener != null) { exportingEndpointListener.close(); } } catch (IOException e) { logger.log(Level.SEVERE, "Error stopping MessageAdapter discovery, because of an IO error", e); } catch (Exception e) { logger.log(Level.SEVERE, "Error stopping MessageAdapter discovery", e); } } }