/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you 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 com.ning.metrics.goodwill.store;
import au.com.bytecode.opencsv.CSVReader;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.ning.metrics.goodwill.access.GoodwillSchema;
import com.ning.metrics.goodwill.access.GoodwillSchemaField;
import com.ning.metrics.goodwill.binder.config.GoodwillConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@Singleton
public class CSVFileStore extends GoodwillStore
{
private final Logger log = Logger.getLogger(CSVFileStore.class);
private String fileName;
@Inject
public CSVFileStore(
GoodwillConfig config
) throws IOException
{
fileName = config.getCSVFilePath();
parseFile();
}
public void parseFile() throws IOException
{
CSVReader reader = new CSVReader(new FileReader(fileName));
log.info(String.format("Read CSV file: %s", fileName));
List<String[]> entries = reader.readAll();
GoodwillSchema currentSchema = null;
String currentSchemaName = null;
/**
* CSV file format:
*
* "TermFrequency",1,"i64","app_id",1,2147483647
* "TermFrequency",2,"string","subdomain",1,2147483647
* "TermFrequency",3,"string","term_freq_json",1,2147483647
* "SpamMarkEvent",19,"string","abuse_type",8,2147483647
* ...
*
* TODO: extend file format with extra sql fields
*/
HashMap<String, GoodwillSchema> schemata = new HashMap<String, GoodwillSchema>();
for (Object entry : entries) {
short position;
GoodwillSchemaField thriftField;
String[] line = (String[]) entry;
try {
position = Short.valueOf(line[1]);
}
catch (NumberFormatException e) {
log.warn(String.format("Ignoring malformed line: %s", StringUtils.join(line, ",")));
continue;
}
try {
thriftField = new GoodwillSchemaField(line[3], line[2], position, null, null, null, null, null);
}
catch (IllegalArgumentException e) {
log.warn(String.format("Ignoring unsupported type <%s>: %s", line[2], StringUtils.join(line, ",")));
continue;
}
if (currentSchemaName == null || !line[0].equals(currentSchemaName)) {
currentSchemaName = line[0];
currentSchema = new GoodwillSchema(currentSchemaName, new ArrayList<GoodwillSchemaField>());
schemata.put(currentSchemaName, currentSchema);
log.debug(String.format("Found new ThriftType thriftField to: %s", currentSchemaName));
}
currentSchema.addThriftField(thriftField);
log.debug(String.format("Added ThriftField to %s: %s", currentSchemaName, thriftField.toString()));
}
this.goodwillSchemata = schemata;
}
@Override
public Collection<GoodwillSchema> getTypes() throws IOException
{
parseFile();
final ArrayList<GoodwillSchema> thriftTypesList = new ArrayList(goodwillSchemata.values());
Collections.sort(thriftTypesList, new Comparator<GoodwillSchema>()
{
@Override
public int compare(GoodwillSchema o, GoodwillSchema o1)
{
return o.getName().compareTo(o1.getName());
}
});
if (sink != null) {
for (int i = 0; i < thriftTypesList.size(); i++) {
GoodwillSchema schema = thriftTypesList.get(i);
schema.setSinkAddInfo(sink.addTypeInfo(schema));
thriftTypesList.set(i, schema);
}
}
return thriftTypesList;
}
/**
* Add a new type to the store
*
* @param schema GoodwillSchema to add
*/
@Override
public void addType(GoodwillSchema schema)
{
goodwillSchemata.put(schema.getName(), schema);
}
/**
* Update a type to the store
*
* @param schema GoodwillSchema to update
*/
@Override
public boolean updateType(GoodwillSchema schema)
{
// Seek etc. Painful here
return false;
}
/**
* Delete a type
*
* @param schema GoodwillSchema to delete
* @return true is success, false otherwise
*/
@Override
public boolean deleteType(GoodwillSchema schema)
{
return false;
}
}