/** * This file is protected by Copyright. * Please refer to the COPYRIGHT file distributed with this source distribution. * * This file is part of REDHAWK IDE. * * 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. * */ package nxm.redhawk.prim; import gov.redhawk.sca.util.ORBUtil; import gov.redhawk.sca.util.OrbSession; import java.lang.Thread.UncaughtExceptionHandler; import nxm.redhawk.lib.RedhawkOptActivator; import nxm.sys.lib.MidasException; import nxm.sys.lib.Primitive; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.annotation.NonNull; import org.omg.CORBA.SystemException; import org.omg.CosNaming.NamingContextExt; import org.omg.CosNaming.NamingContextExtHelper; import org.omg.CosNaming.NamingContextPackage.CannotProceed; import org.omg.CosNaming.NamingContextPackage.InvalidName; import org.omg.CosNaming.NamingContextPackage.NotFound; import CF.Port; import CF.PortHelper; import CF.Resource; import CF.ResourceHelper; import CF.PortSupplierPackage.UnknownPort; /** * This class connects to the specified CORBA host and receives the float data * and plots the data. */ public class CorbaPrimitive extends Primitive { /** * @since 8.0 */ public static final String A_PORT_NAME = "PORT_NAME"; /** * @since 8.0 */ public static final String A_RESOURCE = "RESOURCE"; /** * @since 8.0 */ public static final String A_PORT = "PORT"; /** * @since 8.0 */ public static final String A_HOST = "HOST"; /** The maximum number of times to retry the initial ORB connection */ protected static final int MAX_RETRIES = 5; /** {@inheritDoc} */ @Override public int close() { shutdownNonBlocking(); return super.close(); } /** * This is done in another background thread since any CORBA call(s) in {@link #shutdown()} can * block forever. So we do not want to block the Primitive from closing in those cases. * @since 9.0 */ protected final void shutdownNonBlocking() { Thread shutdownThread = new Thread("CorbaPrimitive Shutdown for " + getID()) { @Override public void run() { shutdown(); } }; shutdownThread.setDaemon(true); shutdownThread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { RedhawkOptActivator.log(new Status(Status.ERROR, RedhawkOptActivator.ID, "Error occured while shuting down Corba Primitive", e)); } }); shutdownThread.start(); } /** * This closes all connected ports and cleans up the CORBA connection(s). */ protected void shutdown() { } /** * @since 10.0 */ @NonNull protected String getPortIOR() { // Get the resource to connect to - MA is the argument list // Resource is the component you're trying to connect to final String resourceName = this.MA.getU(CorbaPrimitive.A_RESOURCE); final String portName = this.MA.getU(CorbaPrimitive.A_PORT_NAME); // Make the ORB connection - MA is the argument list final String host = this.MA.getU(CorbaPrimitive.A_HOST); final int port = this.MA.getL(CorbaPrimitive.A_PORT); String retVal; if (resourceName != null && !resourceName.isEmpty() && host != null && !host.isEmpty() && port > 0) { OrbSession session = OrbSession.createSession(); NamingContextExt ncRef = null; Port portRef = null; try { // There are two cases here. First, we are given all the // information to connect to a host and resolve the port. // Second, we're given an IOR to the port. The IOR doesn't // require the NameService so skip all that setup. // get the root naming context // Use NamingContextExt which is part of the Interoperable Naming // Service (INS) specification. final org.omg.CORBA.Object obj = session.getOrb().string_to_object("corbaloc::" + host + ":" + port); ncRef = NamingContextExtHelper.narrow(obj); // Find the Resource from the NameService final org.omg.CORBA.Object ref = ncRef.resolve(ncRef.to_name(name)); final Resource res = ResourceHelper.narrow(ref); // Get the port from the resource - PORT_NAME is the name of the // port you want to connect to portRef = PortHelper.narrow(res.getPort(portName)); retVal = portRef.toString(); } catch (final SystemException e) { throw new MidasException("Failed to find Port.", e); } catch (UnknownPort e) { throw new MidasException("Failed to find Port.", e); } catch (NotFound e) { throw new MidasException("Failed to find Port.", e); } catch (CannotProceed e) { throw new MidasException("Failed to find Port.", e); } catch (InvalidName e) { throw new MidasException("Failed to find Port.", e); } finally { if (ncRef != null) { ORBUtil.release(ncRef); } if (portRef != null) { ORBUtil.release(portRef); } session.dispose(); } } else { // If ncRef was null, we were passed an IOR for the // port. Use this to directly resolve the port. retVal = portName; } if (retVal == null) { throw new IllegalStateException("Failed to resolve port ior"); } return retVal; } }