/* * Copyright 2015 Eediom Inc. * * 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.cep.query; import java.util.Date; import java.util.concurrent.CopyOnWriteArrayList; import org.araqne.logdb.QueryCommand; import org.araqne.logdb.Row; import org.araqne.logdb.RowBatch; import org.araqne.logdb.ThreadSafe; import org.araqne.logdb.TimeSpan; import org.araqne.logdb.cep.EventContext; import org.araqne.logdb.cep.EventContextStorage; import org.araqne.logdb.cep.EventKey; import org.araqne.logdb.query.expr.Expression; public class EvtCtxAddCommand extends QueryCommand implements ThreadSafe { private EventContextStorage storage; private String topic; private String keyField; private TimeSpan expire; private TimeSpan timeout; private int maxRows; private Expression matcher; // host field for external clock private String hostField; public EvtCtxAddCommand(EventContextStorage storage, String topic, String keyField, TimeSpan expire, TimeSpan timeout, int maxRows, Expression matcher, String hostField) { this.storage = storage; this.topic = topic; this.keyField = keyField; this.expire = expire; this.timeout = timeout; this.maxRows = maxRows; this.matcher = matcher; this.hostField = hostField; } @Override public String getName() { return "evtctxadd"; } @Override public void onPush(Row row) { EventContext context = buildEventContext(row); if (context != null) storage.storeContext(context); pushPipe(row); } @Override public void onPush(RowBatch rowBatch) { CopyOnWriteArrayList<EventContext> batchContexts = new CopyOnWriteArrayList<EventContext>(); if (rowBatch.selectedInUse) { for (int i = 0; i < rowBatch.size; i++) { int p = rowBatch.selected[i]; Row row = rowBatch.rows[p]; EventContext context = buildEventContext(row); if (context != null) batchContexts.add(context); } } else { for (int i = 0; i < rowBatch.size; i++) { Row row = rowBatch.rows[i]; EventContext context = buildEventContext(row); if (context != null) batchContexts.add(context); } } storage.storeContexts(batchContexts); pushPipe(rowBatch); } private EventContext buildEventContext(Row row) { boolean matched = true; Object o = matcher.eval(row); if (o == null) matched = false; if (o instanceof Boolean && !(Boolean) o) matched = false; Object k = row.get(keyField); if (k == null) matched = false; // extract host for log tick String clockHost = null; Object h = null; if (hostField != null) h = row.get(hostField); if (h != null) clockHost = h.toString(); // extract log time long created = 0; Date logTime = null; Object t = row.get("_time"); if (clockHost != null && t instanceof Date) { logTime = (Date) t; created = logTime.getTime(); } else { created = System.currentTimeMillis(); } if (clockHost != null && logTime != null) { Object date = row.get("_time"); if (date instanceof Date) storage.advanceTime(clockHost, logTime.getTime()); } if (matched) { String key = k.toString(); EventKey eventKey = new EventKey(topic, key, clockHost); long expireTime = 0; if (expire != null) expireTime = created + expire.unit.getMillis() * expire.amount; long timeoutTime = 0; if (timeout != null) timeoutTime = created + timeout.unit.getMillis() * timeout.amount; EventContext context = new EventContext(eventKey, created, expireTime, timeoutTime, maxRows); context.getCounter().incrementAndGet(); context.addRow(row); return context; } return null; } @Override public String toString() { String s = "evtctxadd topic=" + topic + " key=" + keyField; if (expire != null) s += " expire=" + expire; if (timeout != null) s += " timeout=" + timeout; if (maxRows != 10) s += " maxrows=" + maxRows; if (hostField != null) s += " logtick=" + hostField; s += " " + matcher; return s; } }