/* * 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 * * 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.apache.ignite.spi.deployment.uri.scanners; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.net.URI; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.IgniteSpiThread; /** * URI deployment scanner manager. */ public class UriDeploymentScannerManager implements UriDeploymentScannerContext { /** Ignite instance name. */ private final String igniteInstanceName; /** URI that scanner should looks after. */ @GridToStringExclude private final URI uri; /** Temporary deployment directory. */ private final File deployDir; /** Scan frequency. */ private final long freq; /** Found files filter. */ private final FilenameFilter filter; /** Scanner listener which should be notified about changes. */ private final GridUriDeploymentScannerListener lsnr; /** Logger. */ private final IgniteLogger log; /** Underlying scanner. */ private final UriDeploymentScanner scanner; /** Scanner implementation. */ private IgniteSpiThread scannerThread; /** Whether first scan completed or not. */ private boolean firstScan = true; /** * Creates new scanner. * * @param igniteInstanceName Ignite instance name. * @param uri URI which scanner should looks after. * @param deployDir Temporary deployment directory. * @param freq Scan frequency. * @param filter Found files filter. * @param lsnr Scanner listener which should be notifier about changes. * @param log Logger. * @param scanner Scanner. */ public UriDeploymentScannerManager( String igniteInstanceName, URI uri, File deployDir, long freq, FilenameFilter filter, GridUriDeploymentScannerListener lsnr, IgniteLogger log, UriDeploymentScanner scanner) { assert uri != null; assert freq > 0; assert deployDir != null; assert filter != null; assert log != null; assert lsnr != null; assert scanner != null; this.igniteInstanceName = igniteInstanceName; this.uri = uri; this.deployDir = deployDir; this.freq = freq; this.filter = filter; this.log = log.getLogger(getClass()); this.lsnr = lsnr; this.scanner = scanner; } /** * Starts scanner. */ public void start() { scannerThread = new IgniteSpiThread(igniteInstanceName, "grid-uri-scanner", log) { /** {@inheritDoc} */ @SuppressWarnings({"BusyWait"}) @Override protected void body() throws InterruptedException { try { while (!isInterrupted()) { try { scanner.scan(UriDeploymentScannerManager.this); } finally { // Do it in finally to avoid any hanging. if (firstScan) { firstScan = false; lsnr.onFirstScanFinished(); } } Thread.sleep(freq); } } finally { // Double check. If we were cancelled before anything has been scanned. if (firstScan) { firstScan = false; lsnr.onFirstScanFinished(); } } } }; scannerThread.start(); if (log.isDebugEnabled()) log.debug("Grid URI deployment scanner started: " + this); } /** * Cancels scanner execution. */ public void cancel() { U.interrupt(scannerThread); } /** * Joins scanner thread. */ public void join() { U.join(scannerThread, log); if (log.isDebugEnabled()) log.debug("Grid URI deployment scanner stopped: " + this); } /** {@inheritDoc} */ public boolean isCancelled() { assert scannerThread != null; return scannerThread.isInterrupted(); } /** {@inheritDoc} */ public File createTempFile(String fileName, File tmpDir) throws IOException { assert fileName != null; int idx = fileName.lastIndexOf('.'); if (idx == -1) idx = fileName.length(); String prefix = fileName.substring(0, idx); if (idx < 3) { // Prefix must be at least 3 characters long. See File.createTempFile(...). prefix += "___"; } String suffix = fileName.substring(idx); return File.createTempFile(prefix, suffix, tmpDir); } /** {@inheritDoc} */ public boolean isFirstScan() { return firstScan; } /** {@inheritDoc} */ public URI getUri() { return uri; } /** {@inheritDoc} */ public File getDeployDirectory() { return deployDir; } /** {@inheritDoc} */ public FilenameFilter getFilter() { return filter; } /** {@inheritDoc} */ public GridUriDeploymentScannerListener getListener() { return lsnr; } /** {@inheritDoc} */ public IgniteLogger getLogger() { return log; } /** {@inheritDoc} */ @Override public String toString() { return S.toString(UriDeploymentScannerManager.class, this, "uri", U.hidePassword(uri.toString())); } }