/*
* 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.fluxmon.impl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
import org.krakenapps.fluxmon.FluxDatabase;
import org.krakenapps.fluxmon.FluxDomain;
import org.krakenapps.fluxmon.FluxHost;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.osgi.service.prefs.PreferencesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(name = "flux-database")
@Provides
public class FluxDatabaseImpl implements FluxDatabase {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ";
private Logger logger = LoggerFactory.getLogger(FluxDatabaseImpl.class.getName());
private Preferences prefs;
public FluxDatabaseImpl(BundleContext bc) {
ServiceReference ref = bc.getServiceReference(PreferencesService.class.getName());
PreferencesService prefsService = (PreferencesService) bc.getService(ref);
prefs = prefsService.getSystemPreferences();
}
@Override
public Collection<String> loadTrackingDomains() {
try {
List<String> domains = new LinkedList<String>();
Preferences root = prefs.node("tracking");
for (String domain : root.childrenNames()) {
domains.add(domain);
}
return domains;
} catch (BackingStoreException e) {
logger.warn("flux database: failed to list tracking domains", e);
return new ArrayList<String>();
}
}
@Override
public void addTrackingDomain(String domain) {
try {
Preferences root = prefs.node("tracking");
if (root.nodeExists(domain))
throw new IllegalStateException("already added: " + domain);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Preferences node = root.node(domain);
node.put("created", dateFormat.format(new Date()));
root.flush();
root.sync();
} catch (BackingStoreException e) {
logger.warn("flux database: add tracking failed", e);
}
}
@Override
public void removeTrackingDomain(String domain) {
try {
Preferences root = prefs.node("tracking");
if (!root.nodeExists(domain))
throw new IllegalStateException("domain not found: " + domain);
root.node(domain).removeNode();
root.flush();
root.sync();
} catch (BackingStoreException e) {
logger.warn("flux database: remove tracking failed", e);
}
}
@Override
public Collection<FluxDomain> loadFluxDomains() {
List<FluxDomain> fluxDomains = new LinkedList<FluxDomain>();
File base = new File(System.getProperty("kraken.data.dir"), "kraken-fluxmon/");
base.mkdirs();
for (File f : base.listFiles()) {
FluxDomain fluxDomain = readFluxDomain(f.getName(), f);
fluxDomains.add(fluxDomain);
}
return fluxDomains;
}
private FluxDomain readFluxDomain(String domain, File f) {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
String line = null;
String header = br.readLine();
String[] headerTokens = header.split(",");
Map<InetAddress, FluxHost> hosts = new HashMap<InetAddress, FluxHost>();
do {
line = br.readLine();
if (line == null)
break;
String[] tokens = line.split(",");
InetAddress address = InetAddress.getByName(tokens[0]);
Date hostCreated = dateFormat.parse(tokens[1]);
Date hostUpdated = dateFormat.parse(tokens[2]);
FluxHost host = new FluxHostImpl(address, hostCreated, hostUpdated);
hosts.put(address, host);
} while (line != null);
Date domainCreated = dateFormat.parse(headerTokens[1]);
Date domainUpdated = dateFormat.parse(headerTokens[2]);
return new FluxDomainImpl(domain, domainCreated, domainUpdated, hosts);
} catch (FileNotFoundException e) {
logger.warn("flux database: file not found", e);
} catch (IOException e) {
logger.warn("flux database: host read error", e);
} catch (ParseException e) {
logger.warn("flux database: header parse error", e);
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
}
}
return null;
}
@Override
public void updateFluxDomain(FluxDomain domain) {
File base = new File(System.getProperty("kraken.data.dir"), "kraken-fluxmon/");
base.mkdirs();
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
BufferedWriter bw = null;
try {
File f = new File(base, domain.getName());
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
bw.append(domain.getName());
bw.append(',');
bw.append(dateFormat.format(domain.getCreateDateTime()));
bw.append(',');
bw.append(dateFormat.format(domain.getUpdateDateTime()));
bw.newLine();
for (FluxHost host : domain.getHosts()) {
bw.append(host.getAddress().getHostAddress());
bw.append(',');
bw.append(dateFormat.format(host.getCreateDateTime()));
bw.append(',');
bw.append(dateFormat.format(host.getUpdateDateTime()));
bw.newLine();
}
} catch (FileNotFoundException e) {
logger.warn("flux database: domain file not found", e);
} catch (IOException e) {
logger.warn("flux database: update domain failed", e);
} finally {
if (bw != null)
try {
bw.close();
} catch (IOException e) {
}
}
}
@Override
public void purgeFluxDomain(FluxDomain domain) {
File base = new File(System.getProperty("kraken.data.dir"), "kraken-fluxmon/");
base.mkdirs();
}
@Override
public void flush() {
}
}