Writing a Custom Function
Siddhi Function Extension consumes zero or more parameters for each event and output a single attribute as an output. This could be used to manipulate event attributes to generate new attribute like Function operator.Â
To implement a custom function extension, create a class extending "org.wso2.siddhi.core.executor.function.FunctionExecutor" and create an appropriate .siddhiext extension mapping file, compile the class, and build the jar containing the .class
and .siddhiext
files. Add them to the Siddhi class path. In a scenario where they are run on WSO2 CEP add the jar to the <CEP_HOME>/repository/components/lib
directory.
For example, if you have created with namespace "math"Â and function name "sin"Â can be referred in the query as follows:Â
from InValueStream select math:sin(inValue) as sinValue insert into OutMediationStream;
Note
From CEP 3.0.0 onwards, FunctionExecutor is supposed to be used for writing both custom expressions and conditions.
Sample implementation of a custom function extension can be found below;
/* * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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 org.wso2.siddhi.extension.math; import org.wso2.siddhi.core.config.ExecutionPlanContext; import org.wso2.siddhi.core.exception.ExecutionPlanRuntimeException; import org.wso2.siddhi.core.executor.ExpressionExecutor; import org.wso2.siddhi.core.executor.function.FunctionExecutor; import org.wso2.siddhi.query.api.definition.Attribute; import org.wso2.siddhi.query.api.exception.ExecutionPlanValidationException; /* * sin(a); * Returns the sine of a (a is in radians). * Accept Type(s) :DOUBLE/INT/FLOAT/LONG * Return Type(s): DOUBLE */ public class SinFunctionExtension extends FunctionExecutor { /** * The initialization method for SinFunctionExtension, this method will be called before the other methods * * @param attributeExpressionExecutors the executors of each function parameter * @param executionPlanContext the context of the execution plan */ @Override protected void init(ExpressionExecutor[] attributeExpressionExecutors, ExecutionPlanContext executionPlanContext) { if (attributeExpressionExecutors.length != 1) { throw new ExecutionPlanValidationException("Invalid no of arguments passed to math:sin() function, " + "required 1, but found " + attributeExpressionExecutors.length); } Attribute.Type attributeType = attributeExpressionExecutors[0].getReturnType(); if (!((attributeType == Attribute.Type.DOUBLE) || (attributeType == Attribute.Type.INT) || (attributeType == Attribute.Type.FLOAT) || (attributeType == Attribute.Type.LONG))) { throw new ExecutionPlanValidationException("Invalid parameter type found for the argument of math:sin() function, " + "required " + Attribute.Type.INT + " or " + Attribute.Type.LONG + " or " + Attribute.Type.FLOAT + " or " + Attribute.Type.DOUBLE + ", but found " + attributeType.toString()); } } /** * The main execution method which will be called upon event arrival * when there are more than one function parameter * * @param data the runtime values of function parameters * @return the function result */ @Override protected Object execute(Object[] data) { return null; } /** * The main execution method which will be called upon event arrival * when there are zero or one function parameter * * @param data null if the function parameter count is zero or * runtime data value of the function parameter * @return the function result */ @Override protected Object execute(Object data) { if (data != null) { //type-conversion if (data instanceof Integer) { int inputInt = (Integer) data; return Math.sin((double) inputInt); } else if (data instanceof Long) { long inputLong = (Long) data; return Math.sin((double) inputLong); } else if (data instanceof Float) { float inputFloat = (Float) data; return Math.sin((double) inputFloat); } else if (data instanceof Double) { return Math.sin((Double) data); } } else { throw new ExecutionPlanRuntimeException("Input to the math:sin() function cannot be null"); } return null; } /** * This will be called only once and this can be used to acquire * required resources for the processing element. * This will be called after initializing the system and before * starting to process the events. */ @Override public void start() { //Implement start logic to acquire relevant resources } /** * This will be called only once and this can be used to release * the acquired resources for processing. * This will be called before shutting down the system. */ @Override public void stop() { //Implement stop logic to release the acquired resources } @Override public Attribute.Type getReturnType() { return Attribute.Type.DOUBLE; } /** * Used to collect the serializable state of the processing element, that need to be * persisted for the reconstructing the element to the same state on a different point of time * * @return stateful objects of the processing element as an array */ @Override public Object[] currentState() { return null; } /** * Used to restore serialized state of the processing element, for reconstructing * the element to the same state as if was on a previous point of time. * * @param state the stateful objects of the element as an array on * the same order provided by currentState(). */ @Override public void restoreState(Object[] state) { //Implement restore state logic. } }
Sample math.siddhiext extension mapping file for the  custom function extension can be found below;
# # Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. # # WSO2 Inc. 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. # sin=org.wso2.siddhi.extension.math.SinFunctionExtension