/*
* Copyright 2010 NCHOVY
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.pcap.live.impl;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.krakenapps.pcap.live.PcapDevice;
import org.krakenapps.pcap.live.PcapDeviceMetadata;
import org.krakenapps.pcap.live.PcapDeviceManager;
import org.krakenapps.pcap.live.PcapStreamEventListener;
import org.krakenapps.pcap.live.PcapStreamManager;
import org.krakenapps.pcap.live.PcapStat;
import org.krakenapps.pcap.live.Promiscuous;
import org.krakenapps.pcap.util.PcapLiveRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author delmitz
*/
public class PcapStreamManagerImpl implements PcapStreamManager {
private final Logger logger = LoggerFactory.getLogger(PcapStreamManagerImpl.class.getName());
private CopyOnWriteArraySet<PcapStreamEventListener> callbacks;
/**
* alias to device mappings
*/
private Map<String, LiveStream> streamMap;
public void validate() {
if (streamMap == null)
streamMap = new ConcurrentHashMap<String, LiveStream>();
callbacks = new CopyOnWriteArraySet<PcapStreamEventListener>();
}
public void invalidate() {
for (String alias : streamMap.keySet()) {
stop(alias);
}
streamMap.clear();
callbacks.clear();
}
@Override
public Collection<String> getStreamKeys() {
return Collections.unmodifiableCollection(streamMap.keySet());
}
@Override
public PcapLiveRunner get(String alias) {
LiveStream stream = streamMap.get(alias);
if (stream == null)
return null;
return stream.runner;
}
@Override
public PcapStat getStat(String alias) {
PcapLiveRunner runner = get(alias);
if (runner == null)
return null;
try {
return runner.getDevice().getStat();
} catch (Exception e) {
return null;
}
}
@Override
public void start(String key, String deviceName, int milliseconds) throws IOException {
start(key, deviceName, milliseconds, Promiscuous.Off, null);
}
@Override
public void start(String key, String deviceName, int milliseconds, Promiscuous promisc) throws IOException {
start(key, deviceName, milliseconds, promisc, null);
}
@Override
public void start(String key, String deviceName, int milliseconds, Promiscuous promisc, String filter)
throws IOException {
PcapDeviceMetadata info = null;
for (PcapDeviceMetadata d : PcapDeviceManager.getDeviceMetadataList()) {
if (d.getName().equals(deviceName)) {
info = d;
break;
}
}
PcapDevice device = PcapDeviceManager.open(info.getName(), promisc, milliseconds);
if (filter != null)
device.setFilter(filter, true);
if (streamMap.containsKey(key))
throw new IllegalArgumentException("duplicated alias of pcap device: " + key);
logger.info("kraken-pcap: starting live runner [{}]", key);
LiveStream stream = new LiveStream();
stream.runner = new PcapLiveRunner(device);
stream.thread = new Thread(stream.runner);
streamMap.put(key, stream);
stream.thread.start();
// fire callbacks
for (PcapStreamEventListener callback : callbacks) {
try {
callback.onOpen(key, stream.runner);
} catch (Exception e) {
logger.warn("kraken pcap: callback should not throw any exception", e);
}
}
}
@Override
public void stop(String alias) {
logger.info("kraken-pcap: stopping live runner [{}]", alias);
LiveStream stream = streamMap.remove(alias);
if (stream != null) {
// fire callbacks
for (PcapStreamEventListener callback : callbacks) {
try {
callback.onClose(alias, stream.runner);
} catch (Exception e) {
logger.warn("kraken pcap: callback should not throw any exception", e);
}
}
stream.thread.interrupt();
stream.runner.stop();
}
}
@Override
public void addEventListener(PcapStreamEventListener callback) {
callbacks.add(callback);
}
@Override
public void removeEventListener(PcapStreamEventListener callback) {
callbacks.remove(callback);
}
private static class LiveStream {
private Thread thread;
private PcapLiveRunner runner;
}
}