Repository: ambari Updated Branches: refs/heads/trunk 1df39c324 -> 688f6d46d
Revert "AMBARI-14084. Views: Provide refresh list of available views with newly deployed views w/o restart (Ashwin Rajeev via pallavkul)" This reverts commit 1df39c324fc97d4db4cc19023d1e8aed92efc36d. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/85bb0794 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/85bb0794 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/85bb0794 Branch: refs/heads/trunk Commit: 85bb079447706e004e2b2dcb103b0fdac5704290 Parents: 1df39c3 Author: Pallav Kulshreshtha <[email protected]> Authored: Thu Apr 7 13:33:33 2016 +0530 Committer: Pallav Kulshreshtha <[email protected]> Committed: Thu Apr 7 13:33:33 2016 +0530 ---------------------------------------------------------------------- .../controllers/ambariViews/ViewsListCtrl.js | 5 - .../app/views/ambariViews/listTable.html | 4 - .../ambari/server/controller/AmbariServer.java | 5 - .../ambari/server/view/DirectoryWatcher.java | 30 --- .../server/view/ViewDirectoryWatcher.java | 265 ------------------- .../apache/ambari/server/view/ViewRegistry.java | 36 +-- .../server/view/ViewDirectoryWatcherTest.java | 163 ------------ 7 files changed, 1 insertion(+), 507 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js index 6d1dc52..75f6198 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js @@ -125,9 +125,4 @@ angular.module('ambariAdminConsole') $location.path('/views/'+viewName+'/new'); } }; - - $scope.reloadViews = function () { - loadViews(); - } - }]); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html index ae71d78..4b87070 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html @@ -20,10 +20,6 @@ <div class="clearfix"> <ol class="breadcrumb pull-left"> <li class="active">{{'common.views' | translate}}</li> - <button ng-click="reloadViews()" - class="btn btn-xs"> - <i class="glyphicon glyphicon-refresh"></i> - </button> </ol> <div class="pull-right col-sm-4"> <div class="input-group search-container"> http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java index 0e45f79..5802f08 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java @@ -118,7 +118,6 @@ import org.apache.ambari.server.utils.AmbariPath; import org.apache.ambari.server.utils.RetryHelper; import org.apache.ambari.server.utils.StageUtils; import org.apache.ambari.server.utils.VersionUtils; -import org.apache.ambari.server.view.ViewDirectoryWatcher; import org.apache.ambari.server.view.ViewRegistry; import org.apache.velocity.app.Velocity; import org.eclipse.jetty.http.HttpVersion; @@ -261,9 +260,6 @@ public class AmbariServer { @Inject DelegatingFilterProxy springSecurityFilter; - @Inject - ViewDirectoryWatcher viewDirectoryWatcher; - public String getServerOsType() { return configs.getServerOsType(); } @@ -488,7 +484,6 @@ public class AmbariServer { SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); viewRegistry.readViewArchives(); - viewDirectoryWatcher.start(); handlerList.addHandler(root); server.setHandler(handlerList); http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-server/src/main/java/org/apache/ambari/server/view/DirectoryWatcher.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/DirectoryWatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/view/DirectoryWatcher.java deleted file mode 100644 index 6bc8b39..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/DirectoryWatcher.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF 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 - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * 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.apache.ambari.server.view; - -public interface DirectoryWatcher { - - void start(); - - boolean isRunning(); - - void stop(); - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDirectoryWatcher.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDirectoryWatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDirectoryWatcher.java deleted file mode 100644 index c3d443a..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDirectoryWatcher.java +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF 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 - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * 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.apache.ambari.server.view; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.apache.ambari.server.configuration.Configuration; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.annotation.Nullable; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardWatchEventKinds; -import java.nio.file.WatchEvent; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.zip.ZipFile; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.lang.Thread.sleep; - -@Singleton -public class ViewDirectoryWatcher implements DirectoryWatcher { - - public static final int FIXED_FILE_COUNTER = 30; - public static final int FILE_CHECK_INTERVAL_MILLIS = 200; - // Global configuration - @Inject - Configuration configuration; - - // View Registry - @Inject - ViewRegistry viewRegistry; - - private WatchService watchService; - - // Executor service on which the watcher will run - private ExecutorService executorService = Executors.newSingleThreadExecutor(); - - private Future<?> watchTask; - - private static Log LOG = LogFactory.getLog(ViewDirectoryWatcher.class); - - // Callbacks to hook into file processing - private List<Function<Path, Boolean>> hooks = Lists.newArrayList(loggingHook()); - - public void addHook(Function<Path, Boolean> hook) { - hooks.add(hook); - } - - private Function<Path, Boolean> loggingHook() { - return new Function<Path, Boolean>() { - @Nullable - @Override - public Boolean apply(@Nullable Path path) { - LOG.info("Finished processing the view definition for" + path); - return true; - } - }; - } - - public void start() { - - try { - Path path = buildWatchService(); - Runnable task = startWatching(path); - watchTask = executorService.submit(task); - } catch (Exception e) { - LOG.error("There were errors in starting the view directory watcher. This task will not run", e); - } - } - - - @SuppressWarnings("unchecked") - private static <T> WatchEvent<T> cast(WatchEvent<?> event) { - return (WatchEvent<T>) event; - } - - private Runnable startWatching(final Path path) { - return new Runnable() { - @Override - public void run() { - try { - while (true) { - // wait for key , park the thread meanwhile - WatchKey key = watchService.take(); - LOG.info("Watcher Key was signalled"); - for (WatchEvent<?> event : key.pollEvents()) { - LOG.info("Watcher recieved poll event"); - WatchEvent<Path> ev = cast(event); - Path resolvedPath = path.resolve(ev.context()); - LOG.info(String.format("Event %s: %s\n", ev.kind(), resolvedPath)); - if (!canBlockTillFileAvailable(resolvedPath)) { - LOG.info("Watcher detected that the file was either empty or corrupt"); - continue; - } - if (!verify(resolvedPath)) { - LOG.info("The uploaded file was 1> Empty 2> Not a regular file or 3> Not a valid Jar archive file"); - continue; - } - try { - LOG.info("Starting view extraction"); - viewRegistry.readViewArchive(resolvedPath); - // fire registered hooks - for (Function<Path, Boolean> hook : hooks) { - hook.apply(resolvedPath); - } - } catch (Exception e) { - LOG.error("Cannot read the view archive, offending file: " + resolvedPath, e); - } - - } - - // reset key - if (!key.reset()) { - //watch key is invalid, break out - LOG.error("The watch key could not be reset, Directory watcher will not run anymore"); - break; - } - - - } - } catch (InterruptedException x) { - LOG.info("Cancelling the directory watcher", x); - return; - } - - } - }; - } - - - /** - * Routine to make the file watcher block the thread till the file is completely copied - * Check the length of the file continuously till there are 20 consecutive intervals when - * the file length does not change - * FILE_CHECK_INTERVAL_MILLIS defines the check interval both for detecting empty files - * and subsequent checks to detect if a file has finished copying - * - * The process which copies the jar into the views dir is external and we dont really - * know when it would finish, this is also highly OS and FS dependent. The following routine - * introduces a heuristic to detect when a file has finished copying by looking at subsequent - * lengths of the file which was detected as being created - * - * This would block for ~ 7 seconds in most cases - * - * - * @param resolvedPath - * @return false if the file check failed, true otherwise - */ - private boolean canBlockTillFileAvailable(Path resolvedPath) throws InterruptedException { - long oldLength; - long newSize; - - long emptyCheck = 0; - int fixed = 0; - // get the underlying file - File file = resolvedPath.toAbsolutePath().toFile(); - - // empty file check - while (file.length() == 0 && emptyCheck < 5) { - sleep(FILE_CHECK_INTERVAL_MILLIS); - emptyCheck++; - } - // The file seems to be empty - if (emptyCheck == 5) - return false; - - // check the file size - oldLength = file.length(); - - // Check if file copy is done - while (true) { - LOG.info("Waiting for file to be completely copied"); - sleep(FILE_CHECK_INTERVAL_MILLIS); - newSize = file.length(); - if (newSize > oldLength) { - oldLength = newSize; - continue; - } else if (oldLength == newSize) { - fixed++; - } else { - // this can never happen, - return false; - } - if (fixed > FIXED_FILE_COUNTER) { - LOG.info("File " + resolvedPath + " has finished copying"); - return true; - } - } - - - } - - /** - * Sanity check to validate if the detected path is a valid archive file - * is not a directory, also check that the file is not empty - * - * @param resolvedPath - * @return - */ - private boolean verify(Path resolvedPath) { - try { - File file = resolvedPath.toAbsolutePath().toFile(); - checkArgument(!file.isDirectory()); - checkArgument(file.length() > 0); - new ZipFile(file); - } catch (Exception e) { - LOG.info("Verification failed ", e); - return false; - } - return true; - } - - private Path buildWatchService() throws IOException { - // Get the directory for view Archives - //Attach a file watcher at this directory, Extracted work directory will be ignored - File viewsDir = configuration.getViewsDir(); - Path path = Paths.get(viewsDir.getAbsolutePath()); - - watchService = path.getFileSystem().newWatchService(); - //Watch vews directory for creation events - path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); - return path; - - } - - @Override - public boolean isRunning() { - if (watchTask != null) - return !(watchTask.isDone()); - return false; - } - - @Override - public void stop() { - watchTask.cancel(true); - } - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java index 037d1e5..d9b1fac 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java @@ -102,7 +102,6 @@ import javax.inject.Singleton; import java.beans.IntrospectionException; import java.io.File; import java.net.URL; -import java.nio.file.Path; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -1425,43 +1424,12 @@ public class ViewRegistry { privilegeDAO.remove(privilegeEntity); } - - /** - * Extract a view archive at the specified path - * @param path - */ - public void readViewArchive(Path path) { - - File viewDir = configuration.getViewsDir(); - String extractedArchivesPath = viewDir.getAbsolutePath() + - File.separator + EXTRACTED_ARCHIVES_DIR; - - File archiveFile = path.toAbsolutePath().toFile(); - if (extractor.ensureExtractedArchiveDirectory(extractedArchivesPath)) { - try { - final ViewConfig viewConfig = archiveUtility.getViewConfigFromArchive(archiveFile); - String viewName = ViewEntity.getViewName(viewConfig.getName(), viewConfig.getVersion()); - final String extractedArchiveDirPath = extractedArchivesPath + File.separator + viewName; - final File extractedArchiveDirFile = archiveUtility.getFile(extractedArchiveDirPath); - final ViewEntity viewDefinition = new ViewEntity(viewConfig, configuration, extractedArchiveDirPath); - addDefinition(viewDefinition); - readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile, ambariMetaInfoProvider.get().getServerVersion()); - } catch (Exception e){ - LOG.error("Could not process archive at path "+path, e); - } - } - - } - - - - // read the view archives. private void readViewArchives(boolean systemOnly, boolean useExecutor, String viewNameRegExp) { try { - File viewDir = configuration.getViewsDir(); + String extractedArchivesPath = viewDir.getAbsolutePath() + File.separator + EXTRACTED_ARCHIVES_DIR; @@ -1799,8 +1767,6 @@ public class ViewRegistry { return new ViewAmbariStreamProvider(streamProvider, ambariSessionManager, AmbariServer.getController()); } - - /** * Module for stand alone view registry. */ http://git-wip-us.apache.org/repos/asf/ambari/blob/85bb0794/ambari-server/src/test/java/org/apache/ambari/server/view/ViewDirectoryWatcherTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewDirectoryWatcherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewDirectoryWatcherTest.java deleted file mode 100644 index d9f8919..0000000 --- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewDirectoryWatcherTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF 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 - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * 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.apache.ambari.server.view; - -import com.google.common.base.Function; -import org.apache.ambari.server.configuration.Configuration; -import org.apache.commons.io.FileDeleteStrategy; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import javax.annotation.Nullable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.CountDownLatch; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.easymock.EasyMock.*; - -public class ViewDirectoryWatcherTest { - - private static final Configuration configuration = createNiceMock(Configuration.class); - private static final ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class); - private File testDir; - - - @Before - public void setUp() throws Exception { - reset(configuration, viewRegistry); - testDir = new File(System.getProperty("java.io.tmpdir"), "test_dir"); - if (testDir.exists()) { - FileDeleteStrategy.FORCE.delete(testDir); - } - testDir.mkdirs(); - - } - - - @Test - public void testDirectoryWatcherStart() throws Exception { - ViewDirectoryWatcher viewDirectoryWatcher = new ViewDirectoryWatcher(); - - expect(configuration.getViewsDir()).andReturn(testDir).once(); - viewDirectoryWatcher.configuration = configuration; - viewDirectoryWatcher.viewRegistry = viewRegistry; - replay(configuration); - final CountDownLatch countDownLatch = new CountDownLatch(1); - viewDirectoryWatcher.addHook(new Function<Path, Boolean>() { - @Nullable - @Override - public Boolean apply(@Nullable Path path) { - countDownLatch.countDown(); - return true; - } - - }); - viewDirectoryWatcher.start(); - countDownLatch.await(1, SECONDS); - // Expect watecher to start - Assert.assertTrue(viewDirectoryWatcher.isRunning()); - verify(configuration); - } - - - @Test - public void testDirectoryExtractionOnFileAdd() throws Exception { - ViewDirectoryWatcher viewDirectoryWatcher = new ViewDirectoryWatcher(); - expect(configuration.getViewsDir()).andReturn(testDir).once(); - viewDirectoryWatcher.configuration = configuration; - viewDirectoryWatcher.viewRegistry = viewRegistry; - viewRegistry.readViewArchive(Paths.get(testDir.getAbsolutePath(), "file.jar")); - replay(configuration, viewRegistry); - final CountDownLatch countDownLatch = new CountDownLatch(1); - viewDirectoryWatcher.addHook(new Function<Path, Boolean>() { - @Nullable - @Override - public Boolean apply(@Nullable Path path) { - countDownLatch.countDown(); - return true; - } - }); - viewDirectoryWatcher.start(); - // Create a new File at destination - createZipFile(); - countDownLatch.await(7, SECONDS); - - // Expect watcher to respond - verify(configuration, viewRegistry); - } - - - @Test - public void testDirectoryWatcherStop() throws Exception { - - ViewDirectoryWatcher viewDirectoryWatcher = new ViewDirectoryWatcher(); - expect(configuration.getViewsDir()).andReturn(testDir).once(); - viewDirectoryWatcher.configuration = configuration; - viewDirectoryWatcher.viewRegistry = viewRegistry; - replay(configuration); - - viewDirectoryWatcher.start(); - //Time to start - Thread.sleep(100); - viewDirectoryWatcher.stop(); - Assert.assertFalse(viewDirectoryWatcher.isRunning()); - verify(configuration); - } - - - private void createZipFile() throws IOException { - File file = new File(System.getProperty("java.io.tmpdir") + File.separator + "view.xml"); - file.createNewFile(); - - // input file - FileInputStream in = new FileInputStream(file); - - // out put file - ZipOutputStream out = new ZipOutputStream(new FileOutputStream(new File(testDir, "file.jar"))); - - // name the file inside the zip file - out.putNextEntry(new ZipEntry("view.xml")); - - // buffer size - byte[] b = new byte[1024]; - int count; - - while ((count = in.read(b)) > 0) { - System.out.println(); - out.write(b, 0, count); - } - out.close(); - in.close(); - - } - -} - - - -
