use of alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx in project ACS by ACS-Community.
the class NCSubscriber method notifyFirstSubscription.
/**
* Adds a filter on the server-side supplier proxy that lets the given event type pass through.
* <p>
* Note that we derive the event type name from the simple class name of <code>struct</code>,
* as done in other parts of ACS, which requires IDL event structs to have globally unique names
* across IDL name spaces.
* <p>
* If <code>structClass</code> is <code>null</code> (generic subscription),
* then "<code>*</code>" is used as the event type name,
* which in ETCL is understood as a wildcard for all event type names.
*
* @param structClass
* @throws AcsJEventSubscriptionEx
*/
@Override
protected void notifyFirstSubscription(Class<?> structClass) throws AcsJEventSubscriptionEx {
String eventTypeNameShort = (structClass == null ? "*" : structClass.getSimpleName());
try {
int filterId = addFilter(eventTypeNameShort);
subscriptionsFilters.put(eventTypeNameShort, filterId);
} catch (AcsJCORBAProblemEx e) {
throw new AcsJEventSubscriptionEx(e);
}
}
use of alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx in project ACS by ACS-Community.
the class NCSubscriber method addFilter.
/**
* This method manages the filtering capabilities used to control subscriptions.
* <p>
* A constraint evaluates to true when both of the following conditions are true:
* A member of the constraint's EventTypeSeq matches the message's event type.
* The constraint expression evaluates to true.
*
* @return FilterID (see OMG NotificationService spec 3.2.4.1)
* @throws AcsJCORBAProblemEx
*/
protected int addFilter(String eventTypeName) throws AcsJCORBAProblemEx {
try {
// Create the filter
FilterFactory filterFactory = channel.default_filter_factory();
Filter filter = filterFactory.create_filter(getFilterLanguage());
// Information needed to construct the constraint expression object
// (any domain, THE event type)
// Note that TAO will internally convert the event type name
// to the expression "$type_name=='<our_eventTypeName>'",
// see orbsvcs/Notify/Notify_Constraint_Interpreter.cpp
// The old Consumer class used 'getChannelDomain()' instead of "*"..?
EventType[] t_info = { new EventType("*", eventTypeName) };
// Add constraint expression object to the filter
// no constraints other than the eventTypeName already given above
String constraint_expr = "";
ConstraintExp[] cexp = { new ConstraintExp(t_info, constraint_expr) };
filter.add_constraints(cexp);
// Add the filter to the proxy and return the filter ID
int filterId = proxySupplier.add_filter(filter);
if (logger.isLoggable(AcsLogLevel.DELOUSE)) {
NcFilterInspector insp = new NcFilterInspector(proxySupplier, channelName + "::" + clientName + "::ProxySupplier", logger);
logger.log(AcsLogLevel.DELOUSE, "Added filter for '" + eventTypeName + "'. Current " + insp.getFilterInfo());
// NcFilterInspector insp2 = new NcFilterInspector(
// sharedConsumerAdmin, channelName + "::" + clientName + "::Admin", logger);
// logger.log(AcsLogLevel.DEBUG, "Admin filters: " + insp2.getFilterInfo());
}
return filterId;
} catch (org.omg.CosNotifyFilter.InvalidGrammar e) {
Throwable cause = new Throwable("'" + eventTypeName + "' filter is invalid for the '" + channelName + "' channel: " + e.getMessage());
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(cause);
} catch (org.omg.CosNotifyFilter.InvalidConstraint e) {
Throwable cause = new Throwable("'" + eventTypeName + "' filter is invalid for the '" + channelName + "' channel: " + e.getMessage());
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(cause);
}
}
use of alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx in project ACS by ACS-Community.
the class NCPublisher method publishEvent.
/**
* Takes the given Java object and tries to pack it into a CORBA Any and
* publish it to the notification channel.
* This will fail if the parameter is not
* CORBA-generated from a user-defined IDL struct. In simple terms, trying
* to publish native Java types is impossible because they have no CORBA
* mapping to say Python or C++ types.
*
* @param customStruct
* An instance of the IDL struct (Java class) to be published.
* @throws AcsJPublishEventFailureEx If <code>customStruct</code> is not an IDL struct,
* for which it must be a subclass of IDLEntity.
* @throws AcsJException
* There are an enormous amount of possibilities pertaining to
* why an AcsJException would be thrown by publishEvent.
*/
@Override
public void publishEvent(T customStruct) throws AcsJException {
// Let's first verify that the use of generics between base class and here is OK also for the DDS side.
if (!(customStruct instanceof IDLEntity)) {
String msg = "ACS is using Corba NC as the underlying pub/sub framework. Event data must be IDL-defined structs that inherit from org.omg.CORBA.portable.IDLEntity.";
AcsJPublishEventFailureEx ex = new AcsJPublishEventFailureEx();
ex.setFailureDescription(msg);
ex.setChannelName(channelName);
ex.setEventName(customStruct.getClass().getName());
throw ex;
}
IDLEntity customStructEntity = (IDLEntity) customStruct;
String typeName = customStructEntity.getClass().getSimpleName();
// Event to send
// Header: domain_name = "ALMA", type_name = simple name of IDL struct, event_name = ""
StructuredEvent event = getCORBAEvent(typeName, "");
// Send event meta data (client name, timestamp, counter) in the accompanying EventDescription object,
// which we transmit as the Any field 'remainder_of_body'.
event.remainder_of_body = services.getAdvancedContainerServices().getAny();
EventDescription descrip = new EventDescription(services.getName(), alma.acs.util.UTCUtility.utcJavaToOmg(System.currentTimeMillis()), count.getAndIncrement());
EventDescriptionHelper.insert(event.remainder_of_body, descrip);
// In the 'filterable_data' field, we send our IDL struct coded as an Any
event.filterable_data = new Property[1];
event.filterable_data[0] = new Property(alma.acscommon.DEFAULTDATANAME.value, anyAide.complexObjectToCorbaAny(customStructEntity));
// Check the queue for events from previous failures.
synchronized (eventQueueSync) {
if (eventQueue != null) {
CircularQueue<T>.Data<T> tmp;
try {
while ((tmp = eventQueue.pop()) != null) {
publishCORBAEvent(tmp.corbaData, tmp.userData);
}
} catch (Exception ex) {
Level lev = (isTraceEventsEnabled ? Level.INFO : Level.FINEST);
logger.log(lev, "Failed to flush event queue.", ex);
// go on and try to send the new event, to at least have it inserted into the queue.
}
}
}
try {
publishCORBAEvent(event, customStruct);
} catch (AcsJCORBAProblemEx ex) {
String info = ex.getInfo();
if (false == info.contains("org.omg.CORBA.TRANSIENT")) {
throw ex;
}
}
}
use of alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx in project ACS by ACS-Community.
the class NCPublisher method init.
/**
* Initializes NCPublisher
* @param namingService Naming service
* @throws AcsJException
* There are literally dozens of CORBA exceptions that could be
* thrown by the NCPublisher class. Instead, these are
* converted into an ACS Error System exception for the
* developer's convenience.
*/
protected synchronized void init(NamingContext namingService) throws AcsJException {
helper = new Helper(channelName, channelNotifyServiceDomainName, this.services, namingService);
isTraceEventsEnabled = helper.getChannelProperties().isTraceEventsEnabled(this.channelName);
// get the channel
// @TODO: handle Corba TIMEOUT
channel = helper.getNotificationChannel(getNotificationFactoryName());
// Corba NC spec about adminId: a unique identifier assigned by the target EventChannel instance that is unique among all
// SupplierAdmin instances currently associated with the channel.
// We are currently not using it, but it could be logged to help with NC debugging.
IntHolder adminIdHolder = new IntHolder();
org.omg.CosNotifyChannelAdmin.SupplierAdmin supplierAdminBase = null;
try {
supplierAdminBase = channel.new_for_suppliers(InterFilterGroupOperator.AND_OP, adminIdHolder);
} catch (TIMEOUT ex) {
// found in http://jira.alma.cl/browse/COMP-6312
throw new AcsJCORBAProblemEx(ex);
}
if (supplierAdminBase == null) {
AcsJCORBAReferenceNilEx ex = new AcsJCORBAReferenceNilEx();
ex.setVariable("supplierAdminBase");
ex.setContext("Null reference obtained for the supplier admin for channel " + this.channelName);
throw ex;
}
try {
supplierAdmin = gov.sandia.NotifyMonitoringExt.SupplierAdminHelper.narrow(supplierAdminBase);
} catch (BAD_PARAM ex) {
// This should never happen, since we already enforced the presence of TAO extensions in Helper#initializeNotifyFactory
String specialSupplierAdminId = gov.sandia.NotifyMonitoringExt.SupplierAdminHelper.id();
String standardSupplierAdminId = org.omg.CosNotifyChannelAdmin.SupplierAdminHelper.id();
LOG_NC_TaoExtensionsSubtypeMissing.log(logger, channelName + "-SupplierAdmin", specialSupplierAdminId, standardSupplierAdminId);
AcsJNarrowFailedEx ex2 = new AcsJNarrowFailedEx(ex);
ex2.setNarrowType(specialSupplierAdminId);
throw ex2;
}
int proxyCreationAttempts = 0;
while (proxyConsumer == null) {
String randomizedClientName = Helper.createRandomizedClientName(services.getName());
// Holder for the unique ID assigned by the admin object. It is different from the name we set, and will be discarded.
IntHolder proxyIdHolder = new IntHolder();
proxyCreationAttempts++;
try {
// Create the consumer proxy (to which the published events will be fed) with a name.
// The client type parameter selects a StructuredProxyPushConsumer (based on Structured Events),
// as opposed to ProxyPushConsumer (based on Anys), or SequenceProxyPushConsumer (based on sequences of Structured Events).
org.omg.CORBA.Object tempCorbaObj = supplierAdmin.obtain_named_notification_push_consumer(ClientType.STRUCTURED_EVENT, proxyIdHolder, randomizedClientName.toString());
if (tempCorbaObj == null) {
AcsJCORBAReferenceNilEx ex = new AcsJCORBAReferenceNilEx();
ex.setVariable("tempCorbaObj");
ex.setContext("Null reference obtained for the Proxy Push Consumer for publisher " + services.getName());
// @TODO destroy supplierAdmin
throw ex;
}
proxyConsumer = StructuredProxyPushConsumerHelper.narrow(tempCorbaObj);
LOG_NC_ConsumerProxyCreation_OK.log(logger, proxyIdHolder.value, randomizedClientName, proxyCreationAttempts, services.getName(), channelName, getNotificationFactoryName());
} catch (NameAlreadyUsed e) {
// Hopefully we won't run into this situation. Still, try to go on in the loop,
// with a different client name next time.
logger.fine("Consumer proxy name '" + randomizedClientName + "' already in use. Will try again with different random number appended.");
} catch (NameMapError ex) {
// Default to the unnamed version
try {
proxyConsumer = StructuredProxyPushConsumerHelper.narrow(supplierAdmin.obtain_notification_push_consumer(ClientType.STRUCTURED_EVENT, proxyIdHolder));
LOG_NC_ConsumerProxyCreation_OK.log(logger, proxyIdHolder.value, "-unknown-", proxyCreationAttempts, services.getName(), channelName, getNotificationFactoryName());
} catch (AdminLimitExceeded ex2) {
LOG_NC_ConsumerProxyCreation_FAIL.log(logger, services.getName(), channelName, getNotificationFactoryName(), ex2.getMessage());
// @TODO destroy supplierAdmin
throw new AcsJCORBAProblemEx(ex2);
}
} catch (AdminLimitExceeded e) {
LOG_NC_ConsumerProxyCreation_FAIL.log(logger, services.getName(), channelName, getNotificationFactoryName(), e.getMessage());
// @TODO destroy supplierAdmin
throw new AcsJCORBAProblemEx(e);
}
}
// Avoid future calls from the NC to #subscription_change(EventType[], EventType[]). See Corba spec 3.4.1.3
// @TODO: If we use ALL_NOW_UPDATES_ON then we could actually suppress sending of event types that no consumer wants to get.
proxyConsumer.obtain_subscription_types(ObtainInfoMode.NONE_NOW_UPDATES_OFF);
// see 3.4.4.1 of Notification Service, v1.1
try {
StructuredPushSupplier thisSps = StructuredPushSupplierHelper.narrow(this.services.activateOffShoot(this));
proxyConsumer.connect_structured_push_supplier(thisSps);
} catch (AcsJContainerServicesEx e) {
// @TODO destroy supplierAdmin and proxyConsumer
throw new AcsJCORBAProblemEx(e);
} catch (AlreadyConnected e) {
// @TODO destroy supplierAdmin and proxyConsumer
throw new AcsJCORBAProblemEx(e);
}
reconnectCallback = new AcsNcReconnectionCallback(this, logger);
reconnectCallback.registerForReconnect(services, helper.getNotifyFactory());
}
use of alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx in project ACS by ACS-Community.
the class Consumer method createConsumer.
/**
* Handles the CORBA creation of a consumer.
* Changed to private because only ctor of this class call this method as of Alma 5.0.2
*
* @throws AcsJException
* Any CORBA exceptions encountered are converted to an
* AcsJException for developer's ease of use.
*/
private void createConsumer() throws AcsJException {
IntHolder consumerAdminIDHolder = new IntHolder();
// get the Consumer admin object (no reuse of admin obj. This gets addressed in the new NCSubscriber class)
// We don't need to use the TAO extension method "named_new_for_consumers" because only the proxy object will get a name from us.
m_consumerAdmin = m_channel.new_for_consumers(InterFilterGroupOperator.AND_OP, consumerAdminIDHolder);
// sanity check
if (m_consumerAdmin == null) {
String reason = "The '" + m_channelName + "' channel: null consumer admin";
throw new alma.ACSErrTypeJavaNative.wrappers.AcsJJavaLangEx(reason);
}
// get the Supplier proxy
proxyID = new IntHolder();
gov.sandia.NotifyMonitoringExt.ConsumerAdmin consumerAdminExt = null;
try {
consumerAdminExt = gov.sandia.NotifyMonitoringExt.ConsumerAdminHelper.narrow(m_consumerAdmin);
} catch (BAD_PARAM ex) {
// Don't care, we won't be able to create the proxy with a name, but that's it
// HSO: Actually this should never happen, because without TAO extension present,
// already getting the NotifyFactory reference would have failed.
}
if (consumerAdminExt != null) {
// which could lead to memory leaks
while (m_proxySupplier == null) {
String randomizedClientName = m_helper.createRandomizedClientName(m_clientName);
try {
// Create the push supplier with a name
m_proxySupplier = StructuredProxyPushSupplierHelper.narrow(consumerAdminExt.obtain_named_notification_push_supplier(ClientType.STRUCTURED_EVENT, proxyID, randomizedClientName));
m_logger.fine("Created named proxy supplier '" + randomizedClientName + "'");
} catch (NameAlreadyUsed e) {
// Hopefully we won't run into this situation. Still, try to go on in the loop,
// with a different client name next time.
} catch (NameMapError e) {
// Default to the unnamed version
try {
m_proxySupplier = StructuredProxyPushSupplierHelper.narrow(m_consumerAdmin.obtain_notification_push_supplier(ClientType.STRUCTURED_EVENT, proxyID));
} catch (AdminLimitExceeded e1) {
throw new AcsJCORBAProblemEx(e1);
}
} catch (AdminLimitExceeded e) {
throw new AcsJCORBAProblemEx(e);
}
}
} else {
// Create the push supplier without a name
try {
m_proxySupplier = StructuredProxyPushSupplierHelper.narrow(m_consumerAdmin.obtain_notification_push_supplier(ClientType.STRUCTURED_EVENT, proxyID));
} catch (org.omg.CosNotifyChannelAdmin.AdminLimitExceeded e) {
// convert it into an exception developers care about
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(e);
}
}
// sanity check
if (m_proxySupplier == null) {
String reason = "The '" + m_channelName + "' channel: null proxy supplier";
throw new alma.ACSErrTypeJavaNative.wrappers.AcsJJavaLangEx(reason);
}
LOG_NC_SubscriptionConnect_OK.log(m_logger, m_channelName, m_notifyServiceName);
}
Aggregations