use of org.omg.CosNotifyChannelAdmin.EventChannel in project ACS by ACS-Community.
the class EventModel method discoverChannels.
/**
* Checks the naming service for NC instances and stores / updates them under the matching service from {@link #notifyServices}.
* It does not query the NCs for consumers etc. though.
* <p>
* This method is broken out from {@link #discoverNotifyServicesAndChannels(boolean)} to make it more readable.
* It should be called only from there, to keep services and NCs aligned.
*
* @param bindingMap Name service bindings in the form key = bindingName, value = bindingKind
*/
private synchronized void discoverChannels(Map<String, String> bindingMap) {
// known NC names, used to detect NCs that have disappeared.
Set<String> oldNcNames = new HashSet<String>();
for (NotifyServiceData nsData : notifyServices.values()) {
for (ChannelData channelData : nsData.getChannels()) {
oldNcNames.add(channelData.getQualifiedName());
}
}
// with the NC ref coming either from the naming service or perhaps from the notify service directly if we can match ncIDs with the MC data.
for (String bindingName : bindingMap.keySet()) {
String bindingKind = bindingMap.get(bindingName);
if (bindingKind.equals(alma.acscommon.NC_KIND.value)) {
try {
String channelName = Helper.extractChannelName(bindingName);
String domainName = Helper.extractDomainName(bindingName);
// Check if we already know this NC.
ChannelData channelData = getNotifyServicesRoot().findChannel(channelName);
if (channelData != null) {
oldNcNames.remove(channelData.getQualifiedName());
channelData.setIsNewNc(false);
} else {
m_logger.fine("New NC '" + channelName + "'.");
// A new NC. This will happen at startup, and later as NCs get added.
// The NC-to-service mapping is based on conventions and CDB data, implemented in the Helper class from jcontnc.
Helper notifyHelper = new Helper(channelName, domainName, cs, nctx);
String serviceId = notifyHelper.getNotificationFactoryNameForChannel();
NotifyServiceData service = notifyServices.get(serviceId);
if (service == null) {
// This should never happen because since ACS 12.1 we always auto-discover services as part of refreshing NCs.
// We read the service and NC bindings only once from the naming service, which avoids timing issues with NCs visible now
// even though their notify service would not have been registered before.
// Just in case we leave this code here, but log it as a warning.
discoverNotifyServices(bindingMap);
service = notifyServices.get(serviceId);
String msg = "Unknown notify service '" + simplifyNotifyServiceName(serviceId) + "' required for NC '" + channelName + "'. ";
if (service != null) {
m_logger.warning(msg + "Added the new service.");
} else {
m_logger.warning(msg + "Failed to add the new service.");
}
}
if (service != null) {
EventChannel nc = resolveNotificationChannel(bindingName);
ChannelData cdata = new ChannelData(nc, channelName, service);
cdata.setIsNewNc(true);
// The system NCs for logging and monitor point archiving use custom event formats and cannot be subscribed to using the normal NCSubscriber.
if (domainName.equals(ACS_NC_DOMAIN_LOGGING.value) || domainName.equals(ACS_NC_DOMAIN_ARCHIVING.value)) {
cdata.markUnsubscribable();
}
service.addChannel(channelName, cdata);
}
}
} catch (Exception ex) {
m_logger.log(Level.WARNING, "Failed to map NC '" + bindingName + "' to its notify service.", ex);
}
}
}
// just in case there are non-standard NCs created by someone without proper naming service bindings.
for (NotifyServiceData service : notifyServices.values()) {
if (!service.isReachable()) {
// we skip services that were unreachable already before
continue;
}
// First set the missing ncId on new ChannelData objects
if (!service.getNewChannels().isEmpty()) {
// check first if we can avoid the get_all_channels() remote call
int[] ncIds = service.getEventChannelFactory().get_all_channels();
for (int ncId : ncIds) {
if (service.getChannelById(ncId) == null) {
// our ncId is new... try to find matching known new NC
EventChannel newNc = null;
try {
newNc = service.getEventChannelFactory().get_event_channel(ncId);
} catch (ChannelNotFound ex) {
// should never happen since we just got this Id from the service
ex.printStackTrace();
}
ChannelData matchedNc = service.getChannelByCorbaRef(newNc);
if (matchedNc != null) {
if (matchedNc.isNewNc()) {
matchedNc.setNcId(ncId);
m_logger.fine("Service " + service.getName() + ": Matched ncId=" + ncId + " to new NC '" + matchedNc.getName() + "'.");
} else {
m_logger.warning("Service " + service.getName() + ": Matched ncId=" + ncId + " to NC '" + matchedNc.getName() + "', but expect this NC to be new, which it isn't.");
}
} else {
// ncId is the Id of a new NC that was not registered in the naming service (unless the corberef-based match failed).
// We don't create a ChannelData object yet, because we may get its real name below from the MC.
}
}
}
}
// Then check the service's MC object for new (hopefully named) NCs.
MCProxy mcProxy = new MCProxy(service, m_logger);
List<String> ncNamesFromMc = mcProxy.listChannels();
for (String ncNameFromMc : ncNamesFromMc) {
if (service.getChannelByName(ncNameFromMc) == null) {
// and therefore we get only its integer ID from the MC API.
try {
// Try if we have an ID instead of a name
// see NumberFormatException catch below
int ncId = Integer.parseInt(ncNameFromMc);
// see ChannelNotFound catch below
service.getEventChannelFactory().get_event_channel(ncId);
// The NC was created without TAO extension name.
// Check if we know this NC already from the naming service or from a previous round here.
ChannelData channelData = service.getChannelById(ncId);
if (channelData == null) {
// First time we see this NC. It is not in the naming service and there is nowhere we can get a decent name for it.
// We simply use the Id as its name.
// If this is a problem, then this NC should be created with TAO extension name, or should be registered in the NS.
m_logger.info("Service " + service.getName() + ": Found unnamed NC with ID='" + ncId + "' that is not registered in the naming service.");
String newNcName = Integer.toString(ncId);
EventChannel unnamedNcCorbaRef = null;
try {
unnamedNcCorbaRef = service.getEventChannelFactory().get_event_channel(ncId);
} catch (ChannelNotFound ex) {
// should not happen since we just got the ncId from the service
ex.printStackTrace();
}
ChannelData newNcData = new ChannelData(unnamedNcCorbaRef, Integer.toString(ncId), service);
newNcData.markUnsubscribable();
newNcData.setIsNewNc(true);
newNcData.setNcId(ncId);
service.addChannel(newNcName, newNcData);
}
} catch (NumberFormatException ex) {
// The name was not an integer, and therefore also for sure not an ID.
// This means the NC was created using the TAO extensions, and yet it was not registered in the naming service.
m_logger.info("Service " + service.getName() + ": Found NC with name='" + ncNameFromMc + "' that is not registered in the naming service. This case was thought to not exist in practice and is therefore not supported yet by the eventGUI. Please inform ACS.");
} catch (ChannelNotFound ex) {
m_logger.warning("Strange NC '" + service.getName() + "/" + ncNameFromMc + "' reported by MC is not listed in the naming service and has an integer name that is not a channel ID.");
}
} else if (!bindingMap.containsKey(ncNameFromMc)) {
// The NC is not in the naming service, but was added based on MC data in a previous round.
ChannelData nc = service.getChannelByName(ncNameFromMc);
nc.setIsNewNc(false);
oldNcNames.remove(nc.getQualifiedName());
}
}
// for (String statName : nsData.getMc().get_statistic_names()) {
// System.out.println(statName);
// }
}
if (!oldNcNames.isEmpty()) {
// TODO: Change this when the eventGUI or other tools offers manual NC destruction
// Actually it could also be that an additional NotifyService with unused NCs was stopped, but in practice this does not happen.
m_logger.warning("Lost " + oldNcNames.size() + " NCs, which should not happen as we never destroy an NC even if it no longer gets used: " + StringUtils.join(oldNcNames, ' '));
for (String oldNcQualifiedName : oldNcNames) {
String oldNcName = oldNcQualifiedName.substring(oldNcQualifiedName.indexOf('#') + 1);
NotifyServiceData oldNcService = getNotifyServicesRoot().findHostingService(oldNcName);
ChannelData oldNcData = oldNcService.getChannelByName(oldNcName);
closeSelectedConsumer(oldNcData);
oldNcService.removeChannel(oldNcName);
}
}
}
use of org.omg.CosNotifyChannelAdmin.EventChannel in project ACS by ACS-Community.
the class EventModel method getChannelStatistics.
/**
* Called by NotifyServiceUpdateJob (single/periodic refresh of service summary / channel tree).
*/
public synchronized boolean getChannelStatistics() {
if (false == discoverNotifyServicesAndChannels()) {
return false;
}
for (NotifyServiceData nsData : notifyServices.values()) {
if (!nsData.isReachable()) {
// we skip services that were unreachable already in the above discoverNotifyServicesAndChannels call
continue;
}
// especially if we don't want to display the admin objects as tree nodes to show consumer allocation to the shared admins.
for (ChannelData channelData : nsData.getChannels()) {
String channelName = channelData.getQualifiedName();
EventChannel ec = channelData.getCorbaRef();
// initial or previous count of consumers / suppliers
int[] consAndSupp = { 0, 0 };
if (channelData.isNewNc()) {
lastConsumerAndSupplierCount.put(channelName, consAndSupp);
} else if (lastConsumerAndSupplierCount.containsKey(channelName)) {
consAndSupp = lastConsumerAndSupplierCount.get(channelName);
}
// for consumers we must count the proxies, cannot just deduce their number from the consumer admins
int consumerCount = 0;
for (int consumerAdminId : ec.get_all_consumeradmins()) {
try {
ConsumerAdmin consumerAdmin = ec.get_consumeradmin(consumerAdminId);
int[] push_suppliers_ids = consumerAdmin.push_suppliers();
for (int proxyID : push_suppliers_ids) {
try {
ProxySupplier proxy = consumerAdmin.get_proxy_supplier(proxyID);
if (!NCSubscriber.AdminReuseCompatibilityHack.isDummyProxy(proxy)) {
consumerCount++;
}
} catch (ProxyNotFound ex) {
m_logger.log(AcsLogLevel.NOTICE, "Proxy with ID='" + proxyID + "' not found for consumer admin with ID='" + consumerAdminId + "', " + "even though this Id got listed a moment ago.", ex);
}
}
} catch (AdminNotFound ex) {
ex.printStackTrace();
}
}
final String[] roleNames = { "consumer", "supplier" };
int[] proxyCounts = new int[2];
int[] proxyDeltas = new int[2];
proxyCounts[0] = consumerCount;
// currently for suppliers we have 1 admin object per supplier
proxyCounts[1] = ec.get_all_supplieradmins().length;
// same code for consumer and supplier
for (int i = 0; i < proxyCounts.length; i++) {
String cstr = channelName;
int cdiff = proxyCounts[i] - consAndSupp[i];
if (cdiff != 0) {
if (cdiff > 0) {
cstr += " has added " + cdiff + " " + roleNames[i];
} else if (cdiff < 0) {
cstr += " has removed " + (-cdiff) + " " + roleNames[i];
}
cstr += (Math.abs(cdiff) != 1 ? "s." : ".");
m_logger.info(cstr);
}
proxyDeltas[i] = cdiff;
}
lastConsumerAndSupplierCount.put(channelName, proxyCounts);
//m_logger.info("Channel: " + channelName + " has " + adminCounts[0] + " consumers and " + adminCounts[1] + " suppliers.");
channelData.setNumberConsumers(proxyCounts[0]);
channelData.setNumberSuppliers(proxyCounts[1]);
channelData.setDeltaConsumers(proxyDeltas[0]);
channelData.setDeltaSuppliers(proxyDeltas[1]);
}
}
return true;
}
use of org.omg.CosNotifyChannelAdmin.EventChannel in project ACS by ACS-Community.
the class EventModel method resolveNotificationChannel.
/**
* Resolves a notification channel in the naming service.
*
* @return Reference to the event channel specified by channelName.
* @param bindingName
* Name of the event channel and trailing domain name, as the NC is registered with the CORBA Naming Service
* @throws AcsJException
* Standard ACS Java exception.
*/
protected EventChannel resolveNotificationChannel(String bindingName) throws AcsJException {
EventChannel retValue = null;
String nameServiceKind = alma.acscommon.NC_KIND.value;
//m_logger.info("Will call 'nctx.resolve' for binding='" + bindingName + "', kind='" + nameServiceKind + "'.");
try {
NameComponent[] t_NameSequence = { new NameComponent(bindingName, nameServiceKind) };
retValue = EventChannelHelper.narrow(nctx.resolve(t_NameSequence));
} catch (OBJECT_NOT_EXIST ex) {
m_logger.severe("The NC '" + bindingName + "' no longer exists, probably because its notify service was restarted. The naming service still lists this NC.");
throw new AcsJUnexpectedExceptionEx(ex);
} catch (org.omg.CosNaming.NamingContextPackage.NotFound e) {
// No other suppliers have created the channel yet
m_logger.info("The '" + bindingName + "' channel has not been created yet.");
throw new AcsJUnexpectedExceptionEx(e);
} catch (org.omg.CosNaming.NamingContextPackage.CannotProceed e) {
// Think there is virtually no chance of this every happening but...
throw new AcsJUnexpectedExceptionEx(e);
} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
// Think there is virtually no chance of this every happening but...
throw new AcsJUnexpectedExceptionEx(e);
}
return retValue;
}
Aggregations