public Expression visitLeave(UDFExpression node, List<Expression> l) { return new UDFExpression(l, node.getTenantId(), node.getFunctionClassName(), node.getJarPath(), node.getUdfFunction()); }
public UDFExpression(List<Expression> children, PName tenantId, String functionClassName, String jarPath, ScalarFunction udfFunction) { super(children); this.tenantId = tenantId; this.functionClassName = functionClassName; this.jarPath = jarPath; if(udfFunction != null) { this.udfFunction = udfFunction; } else { constructUDFFunction(); } }
private void constructUDFFunction() { try { DynamicClassLoader classLoader = getClassLoader(this.tenantId, this.jarPath); Class<?> clazz = classLoader.loadClass(this.functionClassName); Constructor<?> constructor = clazz.getConstructor(List.class); udfFunction = (ScalarFunction)constructor.newInstance(this.children); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new RuntimeException(e); } }
public static DynamicClassLoader getClassLoader(final PName tenantId, final String jarPath) { DynamicClassLoader cl = tenantIdSpecificCls.get(tenantId); Path parent = null; if (cl != null) return cl; if(jarPath != null && !jarPath.isEmpty()) { cl = pathSpecificCls.get(jarPath); if (cl != null) return cl; parent = getPathForParent(jarPath); } // Parse the DYNAMIC_JARS_DIR_KEY value as a Path if it's present in the configuration Path allowedDynamicJarsPath = config.get(DYNAMIC_JARS_DIR_KEY) != null ? new Path(config.get(DYNAMIC_JARS_DIR_KEY)) : null; // The case jarPath is not provided, or it is provided and the jar is inside hbase.dynamic.jars.dir if (jarPath == null || jarPath.isEmpty() || (allowedDynamicJarsPath != null && parent != null && parent.equals(allowedDynamicJarsPath))) { cl = tenantIdSpecificCls.get(tenantId); if (cl == null) { cl = new DynamicClassLoader(config, UDFExpression.class.getClassLoader()); } // Cache class loader as a weak value, will be GC'ed when no reference left DynamicClassLoader prev = tenantIdSpecificCls.putIfAbsent(tenantId, cl); if (prev != null) { cl = prev; } return cl; } else { //The case jarPath is provided as not part of DYNAMIC_JARS_DIR_KEY //As per PHOENIX-4231, DYNAMIC_JARS_DIR_KEY is the only place where loading a udf jar is allowed throw new SecurityException("Loading jars from " + jarPath + " is not allowed. The only location that is allowed is "+ config.get(DYNAMIC_JARS_DIR_KEY)); } }
@BeforeClass public static void doSetup() throws Exception { Configuration conf = HBaseConfiguration.create(); setUpConfigForMiniCluster(conf); util = new HBaseTestingUtility(conf); util.startMiniDFSCluster(1); util.startMiniZKCluster(1); String string = util.getConfiguration().get("fs.defaultFS"); // PHOENIX-4675 setting the trailing slash implicitly tests that we're doing some path normalization conf.set(DYNAMIC_JARS_DIR_KEY, string+"/hbase/tmpjars/"); util.startMiniHBaseCluster(1, 1); UDFExpression.setConfig(conf); String clientPort = util.getConfiguration().get(QueryServices.ZOOKEEPER_PORT_ATTRIB); url = JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + LOCALHOST + JDBC_PROTOCOL_SEPARATOR + clientPort + JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM; Map<String, String> props = Maps.newHashMapWithExpectedSize(1); props.put(QueryServices.ALLOW_USER_DEFINED_FUNCTIONS_ATTRIB, "true"); props.put(QueryServices.DYNAMIC_JARS_DIR_KEY,string+"/hbase/tmpjars/"); driver = initAndRegisterTestDriver(url, new ReadOnlyProps(props.entrySet().iterator())); }
public static DynamicClassLoader getClassLoader(final PName tenantId, final String jarPath) { DynamicClassLoader cl = tenantIdSpecificCls.get(tenantId); Path parent = null; if (cl != null) return cl; if(jarPath != null && !jarPath.isEmpty()) { cl = pathSpecificCls.get(jarPath); if (cl != null) return cl; parent = getPathForParent(jarPath); } // Parse the DYNAMIC_JARS_DIR_KEY value as a Path if it's present in the configuration Path allowedDynamicJarsPath = config.get(DYNAMIC_JARS_DIR_KEY) != null ? new Path(config.get(DYNAMIC_JARS_DIR_KEY)) : null; // The case jarPath is not provided, or it is provided and the jar is inside hbase.dynamic.jars.dir if (jarPath == null || jarPath.isEmpty() || (allowedDynamicJarsPath != null && parent != null && parent.equals(allowedDynamicJarsPath))) { cl = tenantIdSpecificCls.get(tenantId); if (cl == null) { cl = new DynamicClassLoader(config, UDFExpression.class.getClassLoader()); } // Cache class loader as a weak value, will be GC'ed when no reference left DynamicClassLoader prev = tenantIdSpecificCls.putIfAbsent(tenantId, cl); if (prev != null) { cl = prev; } return cl; } else { //The case jarPath is provided as not part of DYNAMIC_JARS_DIR_KEY //As per PHOENIX-4231, DYNAMIC_JARS_DIR_KEY is the only place where loading a udf jar is allowed throw new SecurityException("Loading jars from " + jarPath + " is not allowed. The only location that is allowed is "+ config.get(DYNAMIC_JARS_DIR_KEY)); } }
public Expression visitLeave(UDFExpression node, List<Expression> l) { return new UDFExpression(l, node.getTenantId(), node.getFunctionClassName(), node.getJarPath(), node.getUdfFunction()); }
@Override public void readFields(DataInput input) throws IOException { super.readFields(input); this.tenantId = PNameFactory.newName(WritableUtils.readString(input)); this.functionClassName = WritableUtils.readString(input); String str = WritableUtils.readString(input); this.jarPath = str.length() == 0 ? null: str; constructUDFFunction(); }
private void constructUDFFunction() { try { DynamicClassLoader classLoader = getClassLoader(this.tenantId, this.jarPath); Class<?> clazz = classLoader.loadClass(this.functionClassName); Constructor<?> constructor = clazz.getConstructor(List.class); udfFunction = (ScalarFunction)constructor.newInstance(this.children); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new RuntimeException(e); } }
public static DynamicClassLoader getClassLoader(final PName tenantId, final String jarPath) { DynamicClassLoader cl = tenantIdSpecificCls.get(tenantId); Path parent = null; if (cl != null) return cl; if(jarPath != null && !jarPath.isEmpty()) { cl = pathSpecificCls.get(jarPath); if (cl != null) return cl; parent = getPathForParent(jarPath); } // Parse the DYNAMIC_JARS_DIR_KEY value as a Path if it's present in the configuration Path allowedDynamicJarsPath = config.get(DYNAMIC_JARS_DIR_KEY) != null ? new Path(config.get(DYNAMIC_JARS_DIR_KEY)) : null; // The case jarPath is not provided, or it is provided and the jar is inside hbase.dynamic.jars.dir if (jarPath == null || jarPath.isEmpty() || (allowedDynamicJarsPath != null && parent != null && parent.equals(allowedDynamicJarsPath))) { cl = tenantIdSpecificCls.get(tenantId); if (cl == null) { cl = new DynamicClassLoader(config, UDFExpression.class.getClassLoader()); } // Cache class loader as a weak value, will be GC'ed when no reference left DynamicClassLoader prev = tenantIdSpecificCls.putIfAbsent(tenantId, cl); if (prev != null) { cl = prev; } return cl; } else { //The case jarPath is provided as not part of DYNAMIC_JARS_DIR_KEY //As per PHOENIX-4231, DYNAMIC_JARS_DIR_KEY is the only place where loading a udf jar is allowed throw new SecurityException("Loading jars from " + jarPath + " is not allowed. The only location that is allowed is "+ config.get(DYNAMIC_JARS_DIR_KEY)); } }
public Expression visitLeave(UDFExpression node, List<Expression> l) { return new UDFExpression(l, node.getTenantId(), node.getFunctionClassName(), node.getJarPath(), node.getUdfFunction()); }
public UDFExpression(List<Expression> children,PFunction functionInfo) { super(children); this.tenantId = functionInfo.getTenantId() == null ? PName.EMPTY_NAME : functionInfo.getTenantId(); this.functionClassName = functionInfo.getClassName(); this.jarPath = functionInfo.getJarPath(); constructUDFFunction(); }
private void constructUDFFunction() { try { DynamicClassLoader classLoader = getClassLoader(this.tenantId, this.jarPath); Class<?> clazz = classLoader.loadClass(this.functionClassName); Constructor<?> constructor = clazz.getConstructor(List.class); udfFunction = (ScalarFunction)constructor.newInstance(this.children); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new RuntimeException(e); } }
public UDFExpression(List<Expression> children, PName tenantId, String functionClassName, String jarPath, ScalarFunction udfFunction) { super(children); this.tenantId = tenantId; this.functionClassName = functionClassName; this.jarPath = jarPath; if(udfFunction != null) { this.udfFunction = udfFunction; } else { constructUDFFunction(); } }
public UDFExpression(List<Expression> children, PName tenantId, String functionClassName, String jarPath, ScalarFunction udfFunction) { super(children); this.tenantId = tenantId; this.functionClassName = functionClassName; this.jarPath = jarPath; if(udfFunction != null) { this.udfFunction = udfFunction; } else { constructUDFFunction(); } }
@Override public void readFields(DataInput input) throws IOException { super.readFields(input); this.tenantId = PNameFactory.newName(WritableUtils.readString(input)); this.functionClassName = WritableUtils.readString(input); String str = WritableUtils.readString(input); this.jarPath = str.length() == 0 ? null: str; constructUDFFunction(); }
@Override public void readFields(DataInput input) throws IOException { super.readFields(input); this.tenantId = PNameFactory.newName(WritableUtils.readString(input)); this.functionClassName = WritableUtils.readString(input); String str = WritableUtils.readString(input); this.jarPath = str.length() == 0 ? null: str; constructUDFFunction(); }
public UDFExpression(List<Expression> children,PFunction functionInfo) { super(children); this.tenantId = functionInfo.getTenantId() == null ? PName.EMPTY_NAME : functionInfo.getTenantId(); this.functionClassName = functionInfo.getClassName(); this.jarPath = functionInfo.getJarPath(); constructUDFFunction(); }
public UDFExpression(List<Expression> children,PFunction functionInfo) { super(children); this.tenantId = functionInfo.getTenantId() == null ? PName.EMPTY_NAME : functionInfo.getTenantId(); this.functionClassName = functionInfo.getClassName(); this.jarPath = functionInfo.getJarPath(); constructUDFFunction(); }