use of javax.jmdns.ServiceInfo in project EngineDriver by JMRI.
the class JmDNSImpl method makeServiceNameUnique.
/**
* Generate a possibly unique name for a service using the information we have in the cache.
*
* @return returns true, if the name of the service info had to be changed.
*/
private boolean makeServiceNameUnique(ServiceInfoImpl info) {
final String originalQualifiedName = info.getKey();
final long now = System.currentTimeMillis();
boolean collision;
do {
collision = false;
// Check for collision in cache
for (DNSEntry dnsEntry : this.getCache().getDNSEntryList(info.getKey())) {
if (DNSRecordType.TYPE_SRV.equals(dnsEntry.getRecordType()) && !dnsEntry.isExpired(now)) {
final DNSRecord.Service s = (DNSRecord.Service) dnsEntry;
if (s.getPort() != info.getPort() || !s.getServer().equals(_localHost.getName())) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("makeServiceNameUnique() JmDNS.makeServiceNameUnique srv collision:" + dnsEntry + " s.server=" + s.getServer() + " " + _localHost.getName() + " equals:" + (s.getServer().equals(_localHost.getName())));
}
info.setName(NameRegister.Factory.getRegistry().incrementName(_localHost.getInetAddress(), info.getName(), NameRegister.NameType.SERVICE));
collision = true;
break;
}
}
}
// Check for collision with other service infos published by JmDNS
final ServiceInfo selfService = _services.get(info.getKey());
if (selfService != null && selfService != info) {
info.setName(NameRegister.Factory.getRegistry().incrementName(_localHost.getInetAddress(), info.getName(), NameRegister.NameType.SERVICE));
collision = true;
}
} while (collision);
return !(originalQualifiedName.equals(info.getKey()));
}
use of javax.jmdns.ServiceInfo in project EngineDriver by JMRI.
the class JmmDNSImpl method inetAddressAdded.
/*
* (non-Javadoc)
* @see javax.jmdns.NetworkTopologyListener#inetAddressAdded(javax.jmdns.NetworkTopologyEvent)
*/
@Override
public void inetAddressAdded(NetworkTopologyEvent event) {
InetAddress address = event.getInetAddress();
try {
if (!_knownMDNS.containsKey(address)) {
synchronized (_knownMDNS) {
if (!_knownMDNS.containsKey(address)) {
final JmDNS dns = JmDNS.create(address);
if (_knownMDNS.putIfAbsent(address, dns) == null) {
// We need to register the services and listeners with the new JmDNS
final Collection<String> types = _serviceTypes;
final Collection<ServiceInfo> infos = _services.values();
final Collection<ServiceTypeListener> typeListeners = _typeListeners;
final Map<String, List<ServiceListener>> serviceListeners = _serviceListeners;
_jmDNSExecutor.submit(new Runnable() {
/**
* {@inheritDoc}
*/
@Override
public void run() {
// Register Types
for (String type : types) {
dns.registerServiceType(type);
}
// Register services
for (ServiceInfo info : infos) {
try {
dns.registerService(info.clone());
} catch (IOException exception) {
// logger.warning("Unexpected unhandled exception: " + exception);
}
}
// Add ServiceType Listeners
for (ServiceTypeListener listener : typeListeners) {
try {
dns.addServiceTypeListener(listener);
} catch (IOException exception) {
// logger.warning("Unexpected unhandled exception: " + exception);
}
}
// Add Service Listeners
for (String type : serviceListeners.keySet()) {
List<ServiceListener> listeners = serviceListeners.get(type);
synchronized (listeners) {
for (ServiceListener listener : listeners) {
dns.addServiceListener(type, listener);
}
}
}
}
});
final NetworkTopologyEvent jmdnsEvent = new NetworkTopologyEventImpl(dns, address);
for (final NetworkTopologyListener listener : this.networkListeners()) {
_listenerExecutor.submit(new Runnable() {
/**
* {@inheritDoc}
*/
@Override
public void run() {
listener.inetAddressAdded(jmdnsEvent);
}
});
}
} else {
dns.close();
}
}
}
}
} catch (Exception e) {
logger.warning("Unexpected unhandled exception: " + e);
}
}
use of javax.jmdns.ServiceInfo in project EngineDriver by JMRI.
the class JmmDNSImpl method list.
/*
* (non-Javadoc)
* @see javax.jmdns.JmmDNS#list(java.lang.String, long)
*/
@Override
public ServiceInfo[] list(final String type, final long timeout) {
final JmDNS[] dnsArray = this.getDNS();
// We need to run this in parallel to respect the timeout.
final Set<ServiceInfo> result = new HashSet<ServiceInfo>(dnsArray.length * 5);
if (dnsArray.length > 0) {
List<Callable<List<ServiceInfo>>> tasks = new ArrayList<Callable<List<ServiceInfo>>>(dnsArray.length);
for (final JmDNS mDNS : dnsArray) {
tasks.add(new Callable<List<ServiceInfo>>() {
@Override
public List<ServiceInfo> call() throws Exception {
return Arrays.asList(mDNS.list(type, timeout));
}
});
}
ExecutorService executor = Executors.newFixedThreadPool(tasks.size(), new NamedThreadFactory("JmmDNS.list"));
try {
List<Future<List<ServiceInfo>>> results = Collections.emptyList();
try {
results = executor.invokeAll(tasks, timeout + 100, TimeUnit.MILLISECONDS);
} catch (InterruptedException exception) {
logger.log(Level.FINE, "Interrupted ", exception);
Thread.currentThread().interrupt();
// Will terminate next loop early.
}
for (Future<List<ServiceInfo>> future : results) {
if (future.isCancelled()) {
continue;
}
try {
result.addAll(future.get());
} catch (InterruptedException exception) {
logger.log(Level.FINE, "Interrupted ", exception);
Thread.currentThread().interrupt();
} catch (ExecutionException exception) {
logger.log(Level.WARNING, "Exception ", exception);
}
}
} finally {
executor.shutdown();
}
}
return result.toArray(new ServiceInfo[result.size()]);
}
use of javax.jmdns.ServiceInfo in project EngineDriver by JMRI.
the class JmmDNSImpl method getServiceInfos.
/*
* (non-Javadoc)
* @see javax.jmdns.JmmDNS#getServiceInfos(java.lang.String, java.lang.String, boolean, long)
*/
@Override
public ServiceInfo[] getServiceInfos(final String type, final String name, final boolean persistent, final long timeout) {
// We need to run this in parallel to respect the timeout.
final JmDNS[] dnsArray = this.getDNS();
final Set<ServiceInfo> result = new HashSet<ServiceInfo>(dnsArray.length);
if (dnsArray.length > 0) {
List<Callable<ServiceInfo>> tasks = new ArrayList<Callable<ServiceInfo>>(dnsArray.length);
for (final JmDNS mDNS : dnsArray) {
tasks.add(new Callable<ServiceInfo>() {
@Override
public ServiceInfo call() throws Exception {
return mDNS.getServiceInfo(type, name, persistent, timeout);
}
});
}
ExecutorService executor = Executors.newFixedThreadPool(tasks.size(), new NamedThreadFactory("JmmDNS.getServiceInfos"));
try {
List<Future<ServiceInfo>> results = Collections.emptyList();
try {
results = executor.invokeAll(tasks, timeout + 100, TimeUnit.MILLISECONDS);
} catch (InterruptedException exception) {
logger.log(Level.FINE, "Interrupted ", exception);
Thread.currentThread().interrupt();
// Will terminate next loop early.
}
for (Future<ServiceInfo> future : results) {
if (future.isCancelled()) {
continue;
}
try {
ServiceInfo info = future.get();
if (info != null) {
result.add(info);
}
} catch (InterruptedException exception) {
logger.log(Level.FINE, "Interrupted ", exception);
Thread.currentThread().interrupt();
} catch (ExecutionException exception) {
logger.log(Level.WARNING, "Exception ", exception);
}
}
} finally {
executor.shutdown();
}
}
return result.toArray(new ServiceInfo[result.size()]);
}
use of javax.jmdns.ServiceInfo in project EngineDriver by JMRI.
the class DNSStateTask method run.
@Override
public void run() {
DNSOutgoing out = this.createOugoing();
try {
if (!this.checkRunCondition()) {
this.cancel();
return;
}
List<DNSStatefulObject> stateObjects = new ArrayList<DNSStatefulObject>();
// send probes for JmDNS itself
synchronized (this.getDns()) {
if (this.getDns().isAssociatedWithTask(this, this.getTaskState())) {
logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + this.getDns().getName());
stateObjects.add(this.getDns());
out = this.buildOutgoingForDNS(out);
}
}
// send probes for services
for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
synchronized (info) {
if (info.isAssociatedWithTask(this, this.getTaskState())) {
logger1.fine(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + info.getQualifiedName());
stateObjects.add(info);
out = this.buildOutgoingForInfo(info, out);
}
}
}
if (!out.isEmpty()) {
logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " #" + this.getTaskState());
this.getDns().send(out);
// Advance the state of objects.
this.advanceObjectsState(stateObjects);
} else {
// Advance the state of objects.
this.advanceObjectsState(stateObjects);
// If we have nothing to send, another timer taskState ahead of us has done the job for us. We can cancel.
cancel();
return;
}
} catch (Throwable e) {
logger1.log(Level.WARNING, this.getName() + ".run() exception ", e);
this.recoverTask(e);
}
this.advanceTask();
}
Aggregations