/* * Copyright 2011 Future Systems * * 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.araqne.logdb.geoip; import java.net.InetAddress; import java.util.Map; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Invalidate; import org.apache.felix.ipojo.annotations.Requires; import org.apache.felix.ipojo.annotations.Validate; import org.araqne.api.InetAddresses; import org.araqne.geoip.GeoIpLocation; import org.araqne.geoip.GeoIpService; import org.araqne.logdb.LookupHandler2; import org.araqne.logdb.LookupHandlerRegistry; import org.araqne.logdb.LookupTable; import org.araqne.logdb.Row; import org.araqne.logdb.RowBatch; @Component(name = "logdb-geoip") public class GeoipLookupExtender implements LookupHandler2 { @Requires private GeoIpService geoip; @Requires private LookupHandlerRegistry lookup; @Validate public void start() { lookup.addLookupHandler("geoip", this); } @Invalidate public void stop() { if (lookup != null) lookup.removeLookupHandler("geoip"); } @Override public LookupTable newTable(String keyField, Map<String, String> outputFields) { return new GeoIpLookupTable(keyField, outputFields); } @Override public Object lookup(String srcField, String dstField, Object value) { InetAddress ip = null; if (value instanceof InetAddress) ip = (InetAddress) value; if (value instanceof String) { try { ip = InetAddresses.forString((String) value); } catch (Throwable t) { return null; } } if (ip == null) return null; if (dstField.equals("country")) return geoip.locateCountry(ip); GeoIpLocation location = geoip.locate(ip); if (location == null) return null; if (dstField.equals("region")) return location.getRegion(); else if (dstField.equals("city")) return location.getCity(); else if (dstField.equals("latitude")) return location.getLatitude(); else if (dstField.equals("longitude")) return location.getLongitude(); return null; } private class GeoIpLookupTable implements LookupTable { private String keyField; private Map<String, String> outputFields; private boolean countryOnly; private String countryOutputField; public GeoIpLookupTable(String keyField, Map<String, String> outputFields) { this.keyField = keyField; this.outputFields = outputFields; this.countryOnly = outputFields.containsKey("country") && outputFields.size() == 1; this.countryOutputField = outputFields.get("country"); } @Override public void lookup(Row row) { locate(row); } @Override public void lookup(RowBatch rowBatch) { if (rowBatch.selectedInUse) { for (int i = 0; i < rowBatch.size; i++) { int p = rowBatch.selected[i]; Row row = rowBatch.rows[p]; locate(row); } } else { for (int i = 0; i < rowBatch.size; i++) { Row row = rowBatch.rows[i]; locate(row); } } } private void locate(Row row) { Object key = row.get(keyField); InetAddress ip = null; if (key instanceof InetAddress) ip = (InetAddress) key; if (key instanceof String) { try { ip = InetAddresses.forString((String) key); } catch (Throwable t) { } } if (ip == null) return; if (countryOnly) { String country = geoip.locateCountry(ip); row.put(countryOutputField, country); return; } GeoIpLocation location = geoip.locate(ip); if (location == null) return; for (String outputField : outputFields.keySet()) { String renameField = outputFields.get(outputField); if (outputField.equals("country")) row.put(renameField, location.getCountry()); else if (outputField.equals("region")) row.put(renameField, location.getRegion()); else if (outputField.equals("city")) row.put(renameField, location.getCity()); else if (outputField.equals("latitude")) row.put(renameField, location.getLatitude()); else if (outputField.equals("longitude")) row.put(renameField, location.getLongitude()); } } } }