/*
* Copyright 2012 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.krakenapps.eventstorage.script;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Random;
import org.krakenapps.api.DateFormat;
import org.krakenapps.api.Script;
import org.krakenapps.api.ScriptArgument;
import org.krakenapps.api.ScriptContext;
import org.krakenapps.api.ScriptUsage;
import org.krakenapps.confdb.ConfigService;
import org.krakenapps.eventstorage.Event;
import org.krakenapps.eventstorage.EventRecord;
import org.krakenapps.eventstorage.EventStorage;
import org.krakenapps.eventstorage.EventTableRegistry;
import org.krakenapps.eventstorage.engine.GlobalConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EventStorageScript implements Script {
private Logger logger = LoggerFactory.getLogger(EventStorageScript.class);
private ScriptContext context;
private ConfigService confsvc;
private EventTableRegistry tableRegistry;
private EventStorage storage;
public EventStorageScript(ConfigService confsvc, EventTableRegistry tableRegistry, EventStorage storage) {
this.confsvc = confsvc;
this.tableRegistry = tableRegistry;
this.storage = storage;
}
@Override
public void setScriptContext(ScriptContext context) {
this.context = context;
}
public void tables(String[] args) {
context.println("Tables");
context.println("---------------");
for (String name : tableRegistry.getTableNames())
context.println(name);
}
@ScriptUsage(description = "create new table", arguments = { @ScriptArgument(name = "name", type = "string", description = "event table name") })
public void createTable(String[] args) {
try {
storage.createTable(args[0]);
context.println("table created");
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "rename table", arguments = {
@ScriptArgument(name = "current table name", type = "string", description = "current event table name"),
@ScriptArgument(name = "new table name", type = "string", description = "new event table name") })
public void renameTable(String[] args) {
try {
tableRegistry.renameTable(args[0], args[1]);
context.println("table renamed");
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "drop event table", arguments = { @ScriptArgument(name = "name", type = "string", description = "event table name") })
public void dropTable(String[] args) {
try {
storage.dropTable(args[0]);
context.println("table dropped");
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "get events", arguments = {
@ScriptArgument(name = "table name", type = "string", description = "table name"),
@ScriptArgument(name = "id", type = "int", description = "event id") })
public void event(String[] args) {
try {
String tableName = args[0];
int id = Integer.valueOf(args[1]);
Event event = storage.getEvent(tableName, id);
context.println((event == null) ? "not found" : event);
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "get events", arguments = {
@ScriptArgument(name = "table name", type = "string", description = "table name"),
@ScriptArgument(name = "offset", type = "int", description = "offset"),
@ScriptArgument(name = "limit", type = "int", description = "limit") })
public void events(String[] args) {
try {
String tableName = args[0];
int offset = Integer.valueOf(args[1]);
int limit = Integer.valueOf(args[2]);
Collection<Event> events = storage.getEvents(tableName, offset, limit);
for (Event event : events)
context.println(event);
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "get events", arguments = {
@ScriptArgument(name = "table name", type = "string", description = "table name"),
@ScriptArgument(name = "id", type = "int", description = "event id"),
@ScriptArgument(name = "count", type = "int", description = "new event count"),
@ScriptArgument(name = "data", type = "string", description = "event data", optional = true) })
public void write(String[] args) {
try {
String tableName = args[0];
long id = Long.valueOf(args[1]);
Date date = new Date();
int count = Integer.valueOf(args[2]);
byte[] data = (args.length > 3) ? args[3].getBytes() : null;
EventRecord record = new EventRecord(id, date, count, data);
storage.write(tableName, record);
context.println("write");
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "get events", arguments = {
@ScriptArgument(name = "table name", type = "string", description = "table name"),
@ScriptArgument(name = "id", type = "int", description = "event id") })
public void remove(String[] args) {
try {
String tableName = args[0];
long id = Long.valueOf(args[1]);
storage.remove(tableName, id);
context.println("removed");
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
@ScriptUsage(description = "get events", arguments = {
@ScriptArgument(name = "table name", type = "string", description = "table name"),
@ScriptArgument(name = "date", type = "string", description = "event date") })
public void removes(String[] args) {
try {
String tableName = args[0];
Date day = DateFormat.parse("yyyyMMdd", args[1]);
storage.remove(tableName, day);
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
public void flush(String[] args) {
try {
storage.flush();
} catch (Throwable e) {
context.println(e);
logger.debug("kraken eventstorage: " + e, e);
}
}
public void parameters(String[] args) {
for (GlobalConfig.Key key : GlobalConfig.Key.values()) {
if (key == GlobalConfig.Key.NextEventId)
continue;
Object value = GlobalConfig.get(confsvc, key);
context.println(key.getName() + " = " + value);
}
}
@ScriptUsage(description = "start benchmark", arguments = { @ScriptArgument(name = "count", type = "int", description = "event count", optional = true) })
public void benchmark(String[] args) {
long count = (args.length > 0) ? Long.parseLong(args[0]) : 1000000;
String tableName = "benchmark";
storage.createTable(tableName);
try {
long time = System.currentTimeMillis() - count * 200L;
{ // sequential id write (new event)
byte[] data = new byte[300];
Arrays.fill(data, (byte) 0xCC);
long begin = System.currentTimeMillis();
for (long id = 1; id <= count; id++) {
Date date = new Date(time);
time += 100L;
storage.write(tableName, new EventRecord(id, date, 1, data));
}
long end = System.currentTimeMillis();
context.printf("new event write (incl. data): %d ms (%d events/s)\n", end - begin, count * 1000L / (end - begin));
}
{ // random id write (exist event)
Random r = new Random();
long begin = System.currentTimeMillis();
for (long i = 1; i <= count; i++) {
Date date = new Date(time);
time += 100L;
storage.write(tableName, new EventRecord((long) r.nextInt((int) (count & 0x7FFFFFFF)) + 1, date, 2));
}
long end = System.currentTimeMillis();
context.printf("random event write (excl. data): %d ms (%d events/s)\n", end - begin, count * 1000L
/ (end - begin));
}
{
long begin = System.currentTimeMillis();
Collection<Event> events = storage.getEvents(tableName, (int) (count) - 4, 5);
boolean valid = (events.size() == 4);
long end = System.currentTimeMillis();
context.printf("event read: %d ms (%d events/s) %s\n", end - begin, count * 1000L / (end - begin), valid ? ""
: ("(error " + events.size() + ")"));
}
} finally {
storage.dropTable(tableName);
}
}
}