use of org.omg.CosNotifyChannelAdmin.ChannelNotFound 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);
}
}
}
Aggregations