Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create User Defined Functions in Cassandra with Custom Java Class?

I couldn't find this anywhere online. How can I create a custom user defined function in cassandra?.

For Ex :

CREATE OR REPLACE FUNCTION customfunc(custommap map<text, int>)
CALLED ON NULL INPUT
RETURNS map<int,bigint> 
LANGUAGE java AS 'return MyClass.mymethod(custommap);';

Where "MyClass" is a class that I can register in the Classpath?

like image 606
Venky Avatar asked Apr 27 '17 15:04

Venky


People also ask

How do I enable user defined functions in Cassandra?

To enable, change the following settings in the cassandra. yaml file: Java: Set enable_user_defined_functions to true. Javascript and other custom languages: Set enable_scripted_user_defined_functions to true .

How do you create a function in Cassandra?

Define a new index on a single column of a table. Creates custom function that execute user provided code in Cassandra. Define a new keyspace. Create a materialized view in Cassandra 3.0 and later.


2 Answers

I have the same issue, too. The custom class in UDF is support in cassandra 2.2.14, but not in cassandra 3.11.4.

Go through the source codes, cassandra 3.11.4 setup the UDF class loader with no parent class loader so that it have full control about what class/resource UDF uses. In org.apache.cassandra.cql3.functions.UDFunction.java, a whitelist and blacklist is used to control which class/package can be access.

For your issue, you should add the full name of MyClass into whitelist, and re-build the cassandra.

like image 187
haishan Avatar answered Oct 20 '22 00:10

haishan


1. First build your java project that contains your class. Remember you have to add package name to your class.

Example :

package exp;

import java.lang.Math;
import java.util.*;

public class MyClass
{
  public static Map<Integer,Long> mymethod(Map<String, Integer> data) {
      Map<Integer,Long> map = new HashMap<>();
      map.put(1, 10L);
      map.put(2, 20L);
      map.put(3, 30L);
      return map;
  }
}

After compile and build i have the jar test.jar

2. Copy the jar file to all cassandra node's $CASSANDRA_HOME/lib Directory

3. Restart All Cassandra Node

4. Create your custom function

Example :

 CREATE OR REPLACE FUNCTION customfunc(custommap map<text, int>) 
    CALLED ON NULL INPUT 
    RETURNS map<int,bigint>  
    LANGUAGE java 
    AS 'return exp.MyClass.mymethod(custommap);';

Now you can use the function :

cassandra@cqlsh:test> SELECT * FROM test_fun ;

 id | data
----+------------------
  1 | {'a': 1, 'b': 2}

(1 rows)
cassandra@cqlsh:test> SELECT customfunc(data) FROM test_fun ;

 test.customfunc(data)
-----------------------
 {1: 10, 2: 20, 3: 30}

(1 rows)
like image 1
Ashraful Islam Avatar answered Oct 19 '22 23:10

Ashraful Islam