Search in sources :

Example 11 with Jar

use of org.apache.drill.exec.proto.UserBitShared.Jar in project drill by apache.

the class CreateFunctionHandler method initRemoteRegistration.

/**
 * Instantiates remote registration. First gets remote function registry with version.
 * Version is used to ensure that we update the same registry we validated against.
 * Then validates against list of remote jars.
 * If validation is successful, first copies jars to registry area and starts updating remote function registry.
 * If during update {@link VersionMismatchException} was detected,
 * attempts to repeat remote registration process till retry attempts exceeds the limit.
 * If retry attempts number hits 0, throws exception that failed to update remote function registry.
 * In case of any error, if jars have been already copied to registry area, they will be deleted.
 *
 * @param functions list of functions present in jar
 * @param jarManager helper class for copying jars to registry area
 * @param remoteRegistry remote function registry
 * @throws IOException in case of problems with copying jars to registry area
 */
private void initRemoteRegistration(List<String> functions, JarManager jarManager, RemoteFunctionRegistry remoteRegistry) throws IOException {
    int retryAttempts = remoteRegistry.getRetryAttempts();
    boolean copyJars = true;
    try {
        while (retryAttempts >= 0) {
            DataChangeVersion version = new DataChangeVersion();
            List<Jar> remoteJars = remoteRegistry.getRegistry(version).getJarList();
            validateAgainstRemoteRegistry(remoteJars, jarManager.getBinaryName(), functions);
            if (copyJars) {
                jarManager.copyToRegistryArea();
                copyJars = false;
            }
            List<Jar> jars = Lists.newArrayList(remoteJars);
            jars.add(Jar.newBuilder().setName(jarManager.getBinaryName()).addAllFunctionSignature(functions).build());
            Registry updatedRegistry = Registry.newBuilder().addAllJar(jars).build();
            try {
                remoteRegistry.updateRegistry(updatedRegistry, version);
                return;
            } catch (VersionMismatchException ex) {
                logger.debug("Failed to update function registry during registration, version mismatch was detected.", ex);
                retryAttempts--;
            }
        }
        throw new DrillRuntimeException("Failed to update remote function registry. Exceeded retry attempts limit.");
    } catch (Exception e) {
        if (!copyJars) {
            jarManager.deleteQuietlyFromRegistryArea();
        }
        throw e;
    }
}
Also used : Jar(org.apache.drill.exec.proto.UserBitShared.Jar) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) RemoteFunctionRegistry(org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry) Registry(org.apache.drill.exec.proto.UserBitShared.Registry) DataChangeVersion(org.apache.drill.exec.store.sys.store.DataChangeVersion) DrillRuntimeException(org.apache.drill.common.exceptions.DrillRuntimeException) VersionMismatchException(org.apache.drill.exec.exception.VersionMismatchException) UserException(org.apache.drill.common.exceptions.UserException) DrillRuntimeException(org.apache.drill.common.exceptions.DrillRuntimeException) FunctionValidationException(org.apache.drill.exec.exception.FunctionValidationException) JarValidationException(org.apache.drill.exec.exception.JarValidationException) IOException(java.io.IOException) ForemanSetupException(org.apache.drill.exec.work.foreman.ForemanSetupException) VersionMismatchException(org.apache.drill.exec.exception.VersionMismatchException)

Example 12 with Jar

use of org.apache.drill.exec.proto.UserBitShared.Jar in project drill by apache.

the class DropFunctionHandler method unregister.

/**
 * Gets remote function registry with version.
 * Version is used to ensure that we update the same registry we removed jars from.
 * Looks for a jar to be deleted, if founds one,
 * attempts to update remote registry with list of jars, that excludes jar to be deleted.
 * If during update {@link VersionMismatchException} was detected,
 * attempts to repeat unregistration process till retry attempts exceeds the limit.
 * If retry attempts number hits 0, throws exception that failed to update remote function registry.
 *
 * @param jarName jar name
 * @param remoteFunctionRegistry remote function registry
 * @return jar that was unregistered, null otherwise
 */
private Jar unregister(String jarName, RemoteFunctionRegistry remoteFunctionRegistry) {
    int retryAttempts = remoteFunctionRegistry.getRetryAttempts();
    while (retryAttempts >= 0) {
        DataChangeVersion version = new DataChangeVersion();
        Registry registry = remoteFunctionRegistry.getRegistry(version);
        Jar jarToBeDeleted = null;
        List<Jar> jars = Lists.newArrayList();
        for (Jar j : registry.getJarList()) {
            if (j.getName().equals(jarName)) {
                jarToBeDeleted = j;
            } else {
                jars.add(j);
            }
        }
        if (jarToBeDeleted == null) {
            return null;
        }
        Registry updatedRegistry = Registry.newBuilder().addAllJar(jars).build();
        try {
            remoteFunctionRegistry.updateRegistry(updatedRegistry, version);
            return jarToBeDeleted;
        } catch (VersionMismatchException ex) {
            logger.debug("Failed to update function registry during unregistration, version mismatch was detected.", ex);
            retryAttempts--;
        }
    }
    throw new DrillRuntimeException("Failed to update remote function registry. Exceeded retry attempts limit.");
}
Also used : Jar(org.apache.drill.exec.proto.UserBitShared.Jar) Registry(org.apache.drill.exec.proto.UserBitShared.Registry) RemoteFunctionRegistry(org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry) DataChangeVersion(org.apache.drill.exec.store.sys.store.DataChangeVersion) DrillRuntimeException(org.apache.drill.common.exceptions.DrillRuntimeException) VersionMismatchException(org.apache.drill.exec.exception.VersionMismatchException)

Example 13 with Jar

use of org.apache.drill.exec.proto.UserBitShared.Jar in project drill by axbaretto.

the class DropFunctionHandler method getPlan.

/**
 * Unregisters UDFs dynamically. Process consists of several steps:
 * <ol>
 * <li>Registering jar in jar registry to ensure that several jars with the same name is not being unregistered.</li>
 * <li>Starts remote unregistration process, gets list of all jars and excludes jar to be deleted.</li>
 * <li>Signals drill bits to start local unregistration process.</li>
 * <li>Removes source and binary jars from registry area.</li>
 * </ol>
 *
 * UDFs unregistration is allowed only if dynamic UDFs support is enabled.
 * Only jars registered dynamically can be unregistered,
 * built-in functions loaded at start up are not allowed to be unregistered.
 *
 * Limitation: before jar unregistration make sure no one is using functions from this jar.
 * There is no guarantee that running queries will finish successfully or give correct result.
 *
 * @return - Single row indicating list of unregistered UDFs, raise exception otherwise
 */
@Override
public PhysicalPlan getPlan(SqlNode sqlNode) throws ForemanSetupException, IOException {
    if (!context.getOption(ExecConstants.DYNAMIC_UDF_SUPPORT_ENABLED).bool_val) {
        throw UserException.validationError().message("Dynamic UDFs support is disabled.").build(logger);
    }
    SqlDropFunction node = unwrap(sqlNode, SqlDropFunction.class);
    String jarName = ((SqlCharStringLiteral) node.getJar()).toValue();
    RemoteFunctionRegistry remoteFunctionRegistry = context.getRemoteFunctionRegistry();
    boolean inProgress = false;
    try {
        final String action = remoteFunctionRegistry.addToJars(jarName, RemoteFunctionRegistry.Action.UNREGISTRATION);
        if (!(inProgress = action == null)) {
            return DirectPlan.createDirectPlan(context, false, String.format("Jar with %s name is used. Action: %s", jarName, action));
        }
        Jar deletedJar = unregister(jarName, remoteFunctionRegistry);
        if (deletedJar == null) {
            return DirectPlan.createDirectPlan(context, false, String.format("Jar %s is not registered in remote registry", jarName));
        }
        remoteFunctionRegistry.submitForUnregistration(jarName);
        removeJarFromArea(jarName, remoteFunctionRegistry.getFs(), remoteFunctionRegistry.getRegistryArea());
        removeJarFromArea(JarUtil.getSourceName(jarName), remoteFunctionRegistry.getFs(), remoteFunctionRegistry.getRegistryArea());
        return DirectPlan.createDirectPlan(context, true, String.format("The following UDFs in jar %s have been unregistered:\n%s", jarName, deletedJar.getFunctionSignatureList()));
    } catch (Exception e) {
        logger.error("Error during UDF unregistration", e);
        return DirectPlan.createDirectPlan(context, false, e.getMessage());
    } finally {
        if (inProgress) {
            remoteFunctionRegistry.finishUnregistration(jarName);
            remoteFunctionRegistry.removeFromJars(jarName);
        }
    }
}
Also used : RemoteFunctionRegistry(org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry) Jar(org.apache.drill.exec.proto.UserBitShared.Jar) SqlCharStringLiteral(org.apache.calcite.sql.SqlCharStringLiteral) UserException(org.apache.drill.common.exceptions.UserException) IOException(java.io.IOException) DrillRuntimeException(org.apache.drill.common.exceptions.DrillRuntimeException) ForemanSetupException(org.apache.drill.exec.work.foreman.ForemanSetupException) VersionMismatchException(org.apache.drill.exec.exception.VersionMismatchException) SqlDropFunction(org.apache.drill.exec.planner.sql.parser.SqlDropFunction)

Example 14 with Jar

use of org.apache.drill.exec.proto.UserBitShared.Jar in project drill by apache.

the class TestDynamicUDFSupport method testLazyInitConcurrent.

@Test
public void testLazyInitConcurrent() throws Exception {
    FunctionImplementationRegistry functionImplementationRegistry = spyFunctionImplementationRegistry();
    copyDefaultJarsToStagingArea();
    test("create function using jar '%s'", defaultBinaryJar);
    final CountDownLatch latch1 = new CountDownLatch(1);
    final CountDownLatch latch2 = new CountDownLatch(1);
    final String query = "select custom_lower('A') from (values(1))";
    doAnswer(invocation -> {
        latch1.await();
        boolean result = (boolean) invocation.callRealMethod();
        assertTrue("syncWithRemoteRegistry() should return true", result);
        latch2.countDown();
        return true;
    }).doAnswer(invocation -> {
        latch1.countDown();
        latch2.await();
        boolean result = (boolean) invocation.callRealMethod();
        assertTrue("syncWithRemoteRegistry() should return true", result);
        return true;
    }).when(functionImplementationRegistry).syncWithRemoteRegistry(anyInt());
    SimpleQueryRunner simpleQueryRunner = new SimpleQueryRunner(query);
    Thread thread1 = new Thread(simpleQueryRunner);
    Thread thread2 = new Thread(simpleQueryRunner);
    thread1.start();
    thread2.start();
    thread1.join();
    thread2.join();
    verify(functionImplementationRegistry, times(2)).syncWithRemoteRegistry(anyInt());
    LocalFunctionRegistry localFunctionRegistry = (LocalFunctionRegistry) FieldUtils.readField(functionImplementationRegistry, "localFunctionRegistry", true);
    assertEquals("Sync function registry version should match", 2, localFunctionRegistry.getVersion());
}
Also used : FileSystem(org.apache.hadoop.fs.FileSystem) LocalFunctionRegistry(org.apache.drill.exec.expr.fn.registry.LocalFunctionRegistry) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) Mockito.doThrow(org.mockito.Mockito.doThrow) TestBuilder(org.apache.drill.test.TestBuilder) SlowTest(org.apache.drill.categories.SlowTest) After(org.junit.After) Mockito.doAnswer(org.mockito.Mockito.doAnswer) HadoopUtils.hadoopToJavaPath(org.apache.drill.test.HadoopUtils.hadoopToJavaPath) Assert.fail(org.junit.Assert.fail) URI(java.net.URI) Path(java.nio.file.Path) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) ConfigConstants(org.apache.drill.common.config.ConfigConstants) Category(org.junit.experimental.categories.Category) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) SqlFunctionTest(org.apache.drill.categories.SqlFunctionTest) Assert.assertFalse(org.junit.Assert.assertFalse) VersionMismatchException(org.apache.drill.exec.exception.VersionMismatchException) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BeforeClass(org.junit.BeforeClass) BaseTestQuery(org.apache.drill.test.BaseTestQuery) ArrayUtils(org.apache.commons.lang3.ArrayUtils) Mockito.spy(org.mockito.Mockito.spy) DrillbitContext(org.apache.drill.exec.server.DrillbitContext) RemoteFunctionRegistry(org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry) FieldUtils(org.apache.commons.lang3.reflect.FieldUtils) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ExpectedException(org.junit.rules.ExpectedException) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) Before(org.junit.Before) UserRemoteException(org.apache.drill.common.exceptions.UserRemoteException) Assert.assertTrue(org.junit.Assert.assertTrue) FileUtils(org.apache.commons.io.FileUtils) Test(org.junit.Test) IOException(java.io.IOException) Mockito.times(org.mockito.Mockito.times) DataChangeVersion(org.apache.drill.exec.store.sys.store.DataChangeVersion) File(java.io.File) Mockito.verify(org.mockito.Mockito.verify) Registry(org.apache.drill.exec.proto.UserBitShared.Registry) Lists(org.apache.drill.shaded.guava.com.google.common.collect.Lists) Rule(org.junit.Rule) Paths(java.nio.file.Paths) Jar(org.apache.drill.exec.proto.UserBitShared.Jar) JarUtil(org.apache.drill.exec.util.JarUtil) Mockito.reset(org.mockito.Mockito.reset) Assert.assertEquals(org.junit.Assert.assertEquals) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) LocalFunctionRegistry(org.apache.drill.exec.expr.fn.registry.LocalFunctionRegistry) SlowTest(org.apache.drill.categories.SlowTest) SqlFunctionTest(org.apache.drill.categories.SqlFunctionTest) Test(org.junit.Test)

Example 15 with Jar

use of org.apache.drill.exec.proto.UserBitShared.Jar in project drill by apache.

the class FunctionImplementationRegistry method getMissingJars.

/**
 * Return list of jars that are missing in local function registry
 * but present in remote function registry.
 * Also updates version holder with remote function registry version.
 *
 * @param remoteFunctionRegistry remote function registry
 * @param localFunctionRegistry local function registry
 * @param version holder for remote function registry version
 * @return list of missing jars
 */
private List<String> getMissingJars(RemoteFunctionRegistry remoteFunctionRegistry, LocalFunctionRegistry localFunctionRegistry, DataChangeVersion version) {
    List<Jar> remoteJars = remoteFunctionRegistry.getRegistry(version).getJarList();
    List<String> localJars = localFunctionRegistry.getAllJarNames();
    List<String> missingJars = new ArrayList<>();
    for (Jar jar : remoteJars) {
        if (!localJars.contains(jar.getName())) {
            missingJars.add(jar.getName());
        }
    }
    return missingJars;
}
Also used : ArrayList(java.util.ArrayList) Jar(org.apache.drill.exec.proto.UserBitShared.Jar)

Aggregations

Jar (org.apache.drill.exec.proto.UserBitShared.Jar)16 RemoteFunctionRegistry (org.apache.drill.exec.expr.fn.registry.RemoteFunctionRegistry)14 Registry (org.apache.drill.exec.proto.UserBitShared.Registry)12 DataChangeVersion (org.apache.drill.exec.store.sys.store.DataChangeVersion)12 FunctionImplementationRegistry (org.apache.drill.exec.expr.fn.FunctionImplementationRegistry)10 VersionMismatchException (org.apache.drill.exec.exception.VersionMismatchException)9 CountDownLatch (java.util.concurrent.CountDownLatch)8 LocalFunctionRegistry (org.apache.drill.exec.expr.fn.registry.LocalFunctionRegistry)8 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)8 IOException (java.io.IOException)7 Test (org.junit.Test)7 SlowTest (org.apache.drill.categories.SlowTest)6 SqlFunctionTest (org.apache.drill.categories.SqlFunctionTest)6 DrillRuntimeException (org.apache.drill.common.exceptions.DrillRuntimeException)6 UserException (org.apache.drill.common.exceptions.UserException)4 ForemanSetupException (org.apache.drill.exec.work.foreman.ForemanSetupException)4 Matchers.anyString (org.mockito.Matchers.anyString)4 Mockito.doAnswer (org.mockito.Mockito.doAnswer)4 InvocationOnMock (org.mockito.invocation.InvocationOnMock)4 File (java.io.File)3