You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2015/02/02 22:57:02 UTC
[19/50] [abbrv] incubator-ignite git commit: Merge remote-tracking
branch 'remotes/origin/ignite-67' into sprint-1
Merge remote-tracking branch 'remotes/origin/ignite-67' into sprint-1
Conflicts:
config/ignite-log4j.xml
config/java.util.logging.properties
modules/core/src/test/config/log4j-test.xml
modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jNodeIdFilePath.java
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/115f5979
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/115f5979
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/115f5979
Branch: refs/heads/ignite-132
Commit: 115f59799edf7038475002553891700d77c0ce03
Parents: f64485b ac05bb9
Author: Anton Vinogradov <av...@gridgain.com>
Authored: Fri Jan 30 22:01:50 2015 +0300
Committer: Anton Vinogradov <av...@gridgain.com>
Committed: Fri Jan 30 22:01:50 2015 +0300
----------------------------------------------------------------------
bin/ggrouter.sh | 10 +-
bin/ggstart.bat | 42 ++--
bin/ggstart.sh | 36 ++--
bin/ggvisorcmd.bat | 36 ++--
bin/ggvisorcmd.sh | 22 +--
bin/include/functions.sh | 42 ++--
bin/include/hadoop-classpath.bat | 2 +-
bin/include/hadoop-classpath.sh | 4 +-
bin/include/parseargs.bat | 2 +-
bin/include/parseargs.sh | 6 +-
bin/include/service.sh | 12 +-
bin/include/setenv.bat | 28 +--
bin/include/setenv.sh | 34 ++--
bin/include/target-classpath.bat | 8 +-
bin/include/target-classpath.sh | 14 +-
bin/setup-hadoop.sh | 10 +-
config/hadoop/default-config.xml | 2 +-
config/ignite-log4j.xml | 4 +-
config/java.util.logging.properties | 2 +-
config/router/default-router.xml | 2 +-
docs/mapred-site.ignite.xml | 2 +-
examples/config/example-cache.xml | 2 +-
examples/config/example-streamer.xml | 8 +-
examples/config/filesystem/example-ggfs.xml | 2 +-
examples/config/servlet/WEB-INF/web.xml | 2 +-
examples/rest/http-rest-example.php | 2 +-
examples/rest/memcache-rest-example.php | 2 +-
.../hibernate/HibernateL2CacheExample.java | 2 +-
.../streaming/StreamingCheckInExample.java | 6 +-
.../StreamingPopularNumbersExample.java | 6 +-
.../streaming/StreamingPriceBarsExample.java | 6 +-
.../StreamingRunningAverageExample.java | 6 +-
.../scalar/examples/ScalarPrimeExample.scala | 2 +-
.../GridMonteCarloExamplesSelfTest.java | 4 +-
.../testsuites/IgniteExamplesSelfTestSuite.java | 2 +-
.../ScalarExamplesSelfTestSuite.scala | 2 +-
.../GridifySetToXXXNonSpringAopSelfTest.java | 20 +-
.../GridifySetToXXXSpringAopSelfTest.java | 20 +-
.../ignite/gridify/NonSpringAopSelfTest.java | 20 +-
.../optimized/OptimizedMarshallerAopTest.java | 4 +-
.../testsuites/IgniteAopSelfTestSuite.java | 2 +-
.../gridify/ExternalNonSpringAopSelfTest.java | 20 +-
modules/clients/src/test/bin/start-nodes-ssh.sh | 2 +-
modules/clients/src/test/bin/start-nodes.cmd | 24 +--
modules/clients/src/test/bin/start-nodes.sh | 26 +--
.../client/ClientDefaultCacheSelfTest.java | 4 +-
.../client/ClientTopologyCacheSelfTest.java | 2 +-
.../integration/ClientAbstractSelfTest.java | 4 +-
.../client/router/ClientFailedInitSelfTest.java | 4 +-
.../client/router/RouterFactorySelfTest.java | 4 +-
.../JettyRestProcessorAbstractSelfTest.java | 4 +-
.../rest/TaskCommandHandlerSelfTest.java | 4 +-
.../protocols/tcp/TcpRestParserSelfTest.java | 6 +-
.../src/test/resources/jetty/rest-jetty-ssl.xml | 10 +-
.../src/test/resources/jetty/rest-jetty.xml | 8 +-
.../test/resources/jetty/router-jetty-ssl.xml | 8 +-
.../src/test/resources/jetty/router-jetty.xml | 8 +-
modules/clients/src/test/resources/log4j.xml | 4 +-
.../clients/src/test/resources/spring-cache.xml | 2 +-
.../src/test/resources/spring-router-ssl.xml | 4 +-
.../src/test/resources/spring-router.xml | 4 +-
.../src/test/resources/spring-server-node.xml | 2 +-
.../test/resources/spring-server-ssl-node.xml | 2 +-
.../apache/ignite/IgniteBasicWarmupClosure.java | 6 +-
.../java/org/apache/ignite/IgniteCluster.java | 2 +-
.../java/org/apache/ignite/IgniteLogger.java | 4 +-
.../apache/ignite/IgniteSystemProperties.java | 190 +++++++++----------
.../main/java/org/apache/ignite/Ignition.java | 6 +-
.../apache/ignite/cache/CacheConfiguration.java | 3 +-
.../CacheConsistentHashAffinityFunction.java | 2 +-
.../apache/ignite/client/GridClientCompute.java | 8 +-
.../ignite/client/router/GridRouterFactory.java | 4 +-
.../impl/GridRouterCommandLineStartup.java | 2 +-
.../router/impl/GridTcpRouterNioParser.java | 4 +-
.../apache/ignite/compute/gridify/Gridify.java | 2 +-
.../ignite/compute/gridify/GridifySetToSet.java | 2 +-
.../compute/gridify/GridifySetToValue.java | 2 +-
.../ClientConnectionConfiguration.java | 16 +-
.../configuration/IgniteConfiguration.java | 72 +++----
.../configuration/IgniteDeploymentMode.java | 4 +-
.../apache/ignite/fs/IgniteFsConfiguration.java | 2 +-
.../ignite/internal/GridKernalContextImpl.java | 2 +-
.../apache/ignite/internal/GridLoggerProxy.java | 4 +-
.../internal/GridPerformanceSuggestions.java | 4 +-
.../ignite/internal/IgniteInternalFuture.java | 8 +-
.../apache/ignite/internal/IgniteKernal.java | 20 +-
.../org/apache/ignite/internal/IgnitionEx.java | 46 ++---
.../processors/cache/GridCacheAdapter.java | 2 +-
.../GridCachePartitionExchangeManager.java | 2 +-
.../processors/cache/GridCacheProcessor.java | 4 +-
.../processors/cache/GridCacheUtils.java | 2 +-
.../distributed/dht/GridDhtLocalPartition.java | 2 +-
.../dht/GridPartitionedGetFuture.java | 2 +-
.../dht/atomic/GridDhtAtomicCache.java | 4 +-
.../distributed/near/GridNearAtomicCache.java | 2 +-
.../distributed/near/GridNearGetFuture.java | 2 +-
.../cache/transactions/IgniteTxManager.java | 10 +-
.../processors/fs/IgniteFsProcessor.java | 8 +-
.../processors/job/GridJobProcessor.java | 2 +-
.../jobmetrics/GridJobMetricsProcessor.java | 4 +-
.../handlers/log/GridLogCommandHandler.java | 2 +-
.../handlers/task/GridTaskCommandHandler.java | 2 +-
.../protocols/tcp/GridClientPacketType.java | 4 +-
.../protocols/tcp/GridMemcachedMessage.java | 4 +-
.../rest/protocols/tcp/GridTcpRestParser.java | 18 +-
.../streamer/GridStreamProcessor.java | 6 +-
.../internal/util/GridConcurrentFactory.java | 3 +-
.../internal/util/GridConfigurationFinder.java | 4 +-
.../internal/util/GridReflectionCache.java | 3 +-
.../ignite/internal/util/IgniteUtils.java | 50 ++---
.../util/future/GridFinishedFuture.java | 2 +-
.../internal/util/future/GridFutureAdapter.java | 4 +-
.../internal/util/io/GridUnsafeDataInput.java | 2 +-
.../internal/util/io/GridUnsafeDataOutput.java | 2 +-
.../shmem/IpcSharedMemoryServerEndpoint.java | 4 +-
.../util/ipc/shmem/IpcSharedMemorySpace.java | 2 +-
.../internal/util/nio/GridBufferedParser.java | 2 +-
.../nio/GridConnectionBytesVerifyFilter.java | 18 +-
.../util/nodestart/GridNodeStartUtils.java | 10 +-
.../util/offheap/unsafe/GridUnsafeMemory.java | 2 +-
.../util/portscanner/GridJmxPortFinder.java | 4 +-
.../apache/ignite/internal/util/typedef/X.java | 4 +-
.../visor/node/VisorBasicConfiguration.java | 26 +--
.../visor/node/VisorEmailConfiguration.java | 14 +-
.../visor/node/VisorLifecycleConfiguration.java | 2 +-
.../visor/node/VisorRestConfiguration.java | 4 +-
.../apache/ignite/jdbc/IgniteJdbcDriver.java | 2 +-
.../apache/ignite/lifecycle/LifecycleBean.java | 4 +-
.../ignite/logger/java/IgniteJavaLogger.java | 4 +-
.../java/IgniteJavaLoggerFileHandler.java | 2 +-
.../optimized/IgniteOptimizedMarshaller.java | 2 +-
.../org/apache/ignite/spi/IgniteSpiAdapter.java | 4 +-
.../ignite/spi/IgniteSpiManagementMBean.java | 2 +-
.../sharedfs/SharedFsCheckpointSpi.java | 6 +-
.../communication/tcp/TcpCommunicationSpi.java | 12 +-
.../spi/discovery/tcp/TcpDiscoverySpi.java | 2 +-
.../discovery/tcp/TcpDiscoverySpiAdapter.java | 2 +-
.../TcpDiscoveryMulticastIpFinder.java | 18 +-
.../sharedfs/TcpDiscoverySharedFsIpFinder.java | 2 +-
.../tcp/ipfinder/vm/TcpDiscoveryVmIpFinder.java | 2 +-
.../spi/swapspace/file/FileSwapSpaceSpi.java | 4 +-
.../ignite/startup/BasicWarmupClosure.java | 6 +-
.../startup/cmdline/CommandLineStartup.java | 12 +-
.../startup/cmdline/CommandLineTransformer.java | 2 +-
.../spring-cache-client-benchmark-1.xml | 2 +-
.../spring-cache-client-benchmark-2.xml | 2 +-
.../spring-cache-client-benchmark-3.xml | 2 +-
modules/core/src/test/config/example-cache.xml | 2 +-
modules/core/src/test/config/ggfs-loopback.xml | 2 +-
modules/core/src/test/config/ggfs-shmem.xml | 2 +-
modules/core/src/test/config/log4j-test.xml | 2 +-
.../core/src/test/config/spring-cache-load.xml | 2 +-
.../core/src/test/config/spring-multicache.xml | 2 +-
.../average/spring-streamer-average-base.xml | 2 +-
.../average/spring-streamer-average-local.xml | 2 +-
.../average/spring-streamer-average-random.xml | 2 +-
.../config/streamer/spring-streamer-base.xml | 2 +-
modules/core/src/test/config/tests.properties | 10 +-
.../internal/GridFactoryVmShutdownTest.java | 2 +-
.../ignite/internal/GridHomePathSelfTest.java | 2 +-
.../GridNodeVisorAttributesSelfTest.java | 4 +-
.../ignite/internal/GridStartStopSelfTest.java | 2 +-
.../ignite/internal/GridVersionSelfTest.java | 8 +-
.../GridCacheAbstractRemoveFailureTest.java | 6 +-
.../GridCacheMissingCommitVersionSelfTest.java | 6 +-
.../cache/GridCacheSlowTxWarnTest.java | 2 +-
...idCacheValueConsistencyAbstractSelfTest.java | 6 +-
.../GridCacheNodeFailureAbstractTest.java | 2 +-
.../GridCachePartitionedTxSalvageSelfTest.java | 6 +-
...artupWithSpecifiedWorkDirectorySelfTest.java | 2 +-
...tartupWithUndefinedGridGainHomeSelfTest.java | 6 +-
...GridUnsafeDataOutputArraySizingSelfTest.java | 2 +-
.../loadtest/GridSingleExecutionTest.java | 4 +-
.../cache/GridCacheAbstractLoadTest.java | 2 +-
.../cache/GridCacheDataStructuresLoadTest.java | 2 +-
.../loadtests/cache/GridCacheLoadTest.java | 2 +-
.../capacity/spring-capacity-cache.xml | 2 +-
.../loadtests/colocation/spring-colocation.xml | 2 +-
.../GridContinuousOperationsLoadTest.java | 18 +-
.../streamer/GridStreamerIndexLoadTest.java | 2 +-
.../ignite/loadtests/util/GridLoadTestArgs.java | 8 +-
.../startup/GridRandomCommandLineLoader.java | 8 +-
.../ignite/startup/GridVmNodesStarter.java | 8 +-
.../GridCommandLineTransformerSelfTest.java | 6 +-
.../ignite/testframework/GridTestUtils.java | 10 +-
.../config/GridTestProperties.java | 16 +-
.../testframework/junits/GridAbstractTest.java | 2 +-
.../logger/GridLog4jRollingFileAppender.java | 2 +-
.../junits/logger/GridTestLog4jLogger.java | 6 +-
.../core/src/test/webapp/META-INF/gg-config.xml | 2 +-
.../fs/hadoop/v1/GridGgfsHadoopFileSystem.java | 6 +-
.../fs/hadoop/v2/GridGgfsHadoopFileSystem.java | 6 +-
.../apache/ignite/hadoop/GridHadoopSetup.java | 16 +-
.../GridHadoopExternalTaskExecutor.java | 2 +-
.../hadoop/GridHadoopPopularWordsTest.java | 6 +-
.../processors/query/h2/IgniteH2Indexing.java | 2 +-
.../ignite/logger/log4j/IgniteLog4jLogger.java | 6 +-
.../logger/log4j/IgniteLog4jNodeIdFilePath.java | 6 +-
.../http/jetty/GridJettyRestProtocol.java | 16 +-
.../processors/schedule/ScheduleFutureImpl.java | 4 +-
.../java/org/apache/ignite/IgniteSpring.java | 2 +-
.../ignite/cache/spring/SpringCacheManager.java | 2 +-
.../spring/IgniteSpringProcessorImpl.java | 10 +-
.../ignite/internal/GridFactorySelfTest.java | 2 +-
.../util/nodestart/GridNodeCallableImpl.java | 10 +-
.../internal/GridNodeStartUtilsSelfTest.java | 6 +-
.../GridProjectionStartStopRestartSelfTest.java | 4 +-
.../optimized/OptimizedClassNamesGenerator.java | 12 +-
.../spi/deployment/uri/UriDeploymentSpi.java | 8 +-
.../file/GridFileDeploymentSelfTest.java | 4 +-
.../scala/org/apache/ignite/visor/Packet.scala | 2 +-
.../ignite/visor/commands/deploy/Packet.scala | 4 +-
.../commands/deploy/VisorDeployCommand.scala | 18 +-
.../ignite/visor/commands/start/Packet.scala | 2 +-
.../commands/start/VisorStartCommand.scala | 4 +-
.../scala/org/apache/ignite/visor/visor.scala | 14 +-
.../testsuites/VisorConsoleSelfTestSuite.scala | 2 +-
.../cache/websession/GridWebSessionFilter.java | 22 +--
.../IgniteServletContextListenerStartup.java | 18 +-
.../startup/servlet/IgniteServletStartup.java | 6 +-
.../internal/websession/WebSessionSelfTest.java | 8 +-
.../websession/WebSessionServerStart.java | 2 +-
pom.xml | 10 +-
223 files changed, 883 insertions(+), 896 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/config/ignite-log4j.xml
----------------------------------------------------------------------
diff --cc config/ignite-log4j.xml
index d8fefb7,0000000..3f171bf
mode 100644,000000..100644
--- a/config/ignite-log4j.xml
+++ b/config/ignite-log4j.xml
@@@ -1,152 -1,0 +1,152 @@@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+ -->
+
+<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
+ "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
+
+<!--
+ Default log4j configuration for GridGain.
+-->
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+ <!--
+ Logs System.out messages to console.
+
+ Note, this appender is disabled by default.
+ To enable, uncomment the section below and also CONSOLE appender in the <root> element.
+ -->
+ <!--
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out"/>
+
+ <param name="Threshold" value="DEBUG"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n"/>
+ </layout>
+
+ <filter class="org.apache.log4j.varia.LevelRangeFilter">
+ <param name="levelMin" value="DEBUG"/>
+ <param name="levelMax" value="WARN"/>
+ </filter>
+ </appender>
+ -->
+
+ <!--
+ Logs all ERROR messages to console.
+ -->
+ <appender name="CONSOLE_ERR" class="org.apache.log4j.ConsoleAppender">
+ <!-- Log to STDERR. -->
+ <param name="Target" value="System.err"/>
+
+ <!-- Log from ERROR and higher (change to WARN if needed). -->
+ <param name="Threshold" value="ERROR"/>
+
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+ <!--
+ Logs all output to specified file.
- By default, the logging goes to GRIDGAIN_HOME/work/log folder
++ By default, the logging goes to IGNITE_HOME/work/log folder
+ -->
+ <appender name="FILE" class="org.gridgain.grid.logger.log4j.GridLog4jRollingFileAppender">
+ <param name="Threshold" value="DEBUG"/>
- <param name="File" value="${GRIDGAIN_HOME}/work/log/ignite.log"/>
++ <param name="File" value="${IGNITE_HOME}/work/log/ignite.log"/>
+ <param name="Append" value="true"/>
+ <param name="MaxFileSize" value="10MB"/>
+ <param name="MaxBackupIndex" value="10"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+ <!--
+ <category name="org.gridgain">
+ <level value="DEBUG"/>
+ </category>
+ -->
+
+ <!--
+ Uncomment this category to enable cache
+ query execution tracing.
+ -->
+ <!--
+ <category name="org.gridgain.cache.queries">
+ <level value="DEBUG"/>
+ </category>
+ -->
+
+ <!--
+ Uncomment to enable DGC tracing.
+ -->
+ <!--
+ <category name="org.gridgain.grid.kernal.processors.cache.GridCacheDgcManager.trace">
+ <level value="DEBUG"/>
+ </category>
+ -->
+
+ <!--
+ Uncomment to disable courtesy notices, such as SPI configuration
+ consistency warnings.
+ -->
+ <!--
+ <category name="org.gridgain.grid.CourtesyConfigNotice">
+ <level value="OFF"/>
+ </category>
+ -->
+
+ <category name="org.springframework">
+ <level value="WARN"/>
+ </category>
+
+ <category name="org.eclipse.jetty">
+ <level value="WARN"/>
+ </category>
+
+ <!--
+ Avoid warnings about failed bind attempt when multiple nodes running on the same host.
+ -->
+ <category name="org.eclipse.jetty.util.log">
+ <level value="ERROR"/>
+ </category>
+
+ <category name="org.eclipse.jetty.util.component">
+ <level value="ERROR"/>
+ </category>
+
+ <category name="com.amazonaws">
+ <level value="WARN"/>
+ </category>
+
+ <!-- Default settings. -->
+ <root>
+ <!-- Print out all info by default. -->
+ <level value="INFO"/>
+
+ <!-- Uncomment to enable logging to console. -->
+ <!--
+ <appender-ref ref="CONSOLE"/>
+ -->
+
+ <appender-ref ref="CONSOLE_ERR"/>
+ <appender-ref ref="FILE"/>
+ </root>
+</log4j:configuration>
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/config/java.util.logging.properties
----------------------------------------------------------------------
diff --cc config/java.util.logging.properties
index 19dddb4,3e11d63..f30e028
--- a/config/java.util.logging.properties
+++ b/config/java.util.logging.properties
@@@ -64,11 -64,11 +64,11 @@@ java.util.logging.ConsoleHandler.format
java.util.logging.ConsoleHandler.level=INFO
#
-# File handler logs all messages into files with pattern `gridgain-%{id8}.%g.log`
+# File handler logs all messages into files with pattern `ignite-%{id8}.%g.log`
- # under `$GRIDGAIN_HOME/work/log/` directory. The placeholder `%{id8}` is a truncated node ID.
+ # under `$IGNITE_HOME/work/log/` directory. The placeholder `%{id8}` is a truncated node ID.
#
-org.gridgain.grid.logger.java.GridJavaLoggerFileHandler.formatter=org.apache.ignite.logger.java.IgniteJavaLoggerFormatter
-org.gridgain.grid.logger.java.GridJavaLoggerFileHandler.pattern=gridgain-%{id8}.%g.log
-org.gridgain.grid.logger.java.GridJavaLoggerFileHandler.level=INFO
-org.gridgain.grid.logger.java.GridJavaLoggerFileHandler.limit=10485760
-org.gridgain.grid.logger.java.GridJavaLoggerFileHandler.count=10
+org.apache.ignite.logger.java.IgniteJavaLoggerFileHandler.formatter=org.apache.ignite.logger.java.IgniteJavaLoggerFormatter
+org.apache.ignite.logger.java.IgniteJavaLoggerFileHandler.pattern=ignite-%{id8}.%g.log
+org.apache.ignite.logger.java.IgniteJavaLoggerFileHandler.level=INFO
+org.apache.ignite.logger.java.IgniteJavaLoggerFileHandler.limit=10485760
+org.apache.ignite.logger.java.IgniteJavaLoggerFileHandler.count=10
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/examples/config/servlet/WEB-INF/web.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/clients/src/test/java/org/apache/ignite/client/integration/ClientAbstractSelfTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/IgniteLogger.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/Ignition.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/client/router/impl/GridRouterCommandLineStartup.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/compute/gridify/GridifySetToSet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/compute/gridify/GridifySetToValue.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/logger/java/IgniteJavaLoggerFileHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/test/config/log4j-test.xml
----------------------------------------------------------------------
diff --cc modules/core/src/test/config/log4j-test.xml
index 0f29c37,a1332f3..984e973
--- a/modules/core/src/test/config/log4j-test.xml
+++ b/modules/core/src/test/config/log4j-test.xml
@@@ -66,7 -66,7 +66,7 @@@
-->
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="DEBUG"/>
- <param name="File" value="${GRIDGAIN_HOME}/work/log/ignite.log"/>
- <param name="File" value="${IGNITE_HOME}/work/log/gridgain.log"/>
++ <param name="File" value="${IGNITE_HOME}/work/log/ignite.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="10"/>
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
index d959f55,aa5808e..f8629d6
--- a/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
+++ b/modules/core/src/test/java/org/apache/ignite/startup/GridRandomCommandLineLoader.java
@@@ -47,10 -47,10 +47,10 @@@ import static org.apache.ignite.IgniteS
*/
public final class GridRandomCommandLineLoader {
/** Name of the system property defining name of command line program. */
- private static final String GRIDGAIN_PROG_NAME = "GRIDGAIN_PROG_NAME";
+ private static final String IGNITE_PROG_NAME = "IGNITE_PROG_NAME";
/** Copyright text. Ant processed. */
- private static final String COPYRIGHT = "Copyright (C) 2014 GridGain Systems.";
+ private static final String COPYRIGHT = "2015 Copyright(C) Apache Software Foundation.";
/** Version. Ant processed. */
private static final String VER = "x.x.x";
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/test/java/org/apache/ignite/testframework/junits/logger/GridLog4jRollingFileAppender.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/core/src/test/java/org/apache/ignite/testframework/junits/logger/GridTestLog4jLogger.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jLogger.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jNodeIdFilePath.java
----------------------------------------------------------------------
diff --cc modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jNodeIdFilePath.java
index 63945a0,a12bf5e..4423ace
--- a/modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jNodeIdFilePath.java
+++ b/modules/log4j/src/main/java/org/apache/ignite/logger/log4j/IgniteLog4jNodeIdFilePath.java
@@@ -46,10 -46,10 +46,10 @@@ class IgniteLog4jNodeIdFilePath impleme
/** {@inheritDoc} */
@Override public String apply(String oldPath) {
- if (!F.isEmpty(U.GRIDGAIN_LOG_DIR))
- return U.nodeIdLogFileName(nodeId, new File(U.GRIDGAIN_LOG_DIR, "ignite.log").getAbsolutePath());
+ if (!F.isEmpty(U.IGNITE_LOG_DIR))
- return U.nodeIdLogFileName(nodeId, new File(U.IGNITE_LOG_DIR, "gridgain.log").getAbsolutePath());
++ return U.nodeIdLogFileName(nodeId, new File(U.IGNITE_LOG_DIR, "ignite.log").getAbsolutePath());
- if (oldPath != null) // fileName could be null if GRIDGAIN_HOME is not defined.
+ if (oldPath != null) // fileName could be null if IGNITE_HOME is not defined.
return U.nodeIdLogFileName(nodeId, oldPath);
String tmpDir = IgniteSystemProperties.getString("java.io.tmpdir");
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/spring/src/main/java/org/apache/ignite/cache/spring/SpringCacheManager.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/GridNodeCallableImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/tools/src/main/java/org/apache/ignite/tools/marshaller/optimized/OptimizedClassNamesGenerator.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/UriDeploymentSpi.java
----------------------------------------------------------------------
diff --cc modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/UriDeploymentSpi.java
index e25752b,0000000..7c72243
mode 100644,000000..100644
--- a/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/UriDeploymentSpi.java
+++ b/modules/urideploy/src/main/java/org/apache/ignite/spi/deployment/uri/UriDeploymentSpi.java
@@@ -1,1367 -1,0 +1,1367 @@@
+/*
+ * 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;
+
+import org.apache.ignite.*;
+import org.apache.ignite.compute.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.resources.*;
+import org.apache.ignite.spi.*;
+import org.apache.ignite.spi.deployment.*;
+import org.apache.ignite.spi.deployment.uri.scanners.*;
+import org.apache.ignite.spi.deployment.uri.scanners.file.*;
+import org.apache.ignite.spi.deployment.uri.scanners.ftp.*;
+import org.apache.ignite.spi.deployment.uri.scanners.http.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.*;
+
+/**
+ * Implementation of {@link org.apache.ignite.spi.deployment.DeploymentSpi} which can deploy tasks from
+ * different sources like file system folders, FTP, email and HTTP.
+ * There are different ways to deploy tasks in grid and every deploy method
+ * depends on selected source protocol. This SPI is configured to work
+ * with a list of URI's. Every URI contains all data about protocol/transport
+ * plus configuration parameters like credentials, scan frequency, and others.
+ * <p>
+ * When SPI establishes a connection with an URI, it downloads deployable units
+ * to the temporary directory in order to prevent it from any changes while
+ * scanning. Use method {@link #setTemporaryDirectoryPath(String) setTemporaryDirectoryPath(String)})
+ * to set custom temporary folder for downloaded deployment units. SPI will
+ * create folder under the path with name identical to local node ID.
+ * <p>
+ * SPI tracks all changes of every given URI. This means that if any file is
+ * changed or deleted, SPI will re-deploy or delete corresponding tasks.
+ * Note that the very first apply to {@link #findResource(String)} findClassLoader(String)}
+ * is blocked until SPI finishes scanning all URI's at least once.
+ * <p>
+ * There are several deployable unit types supported:
+ * <ul>
+ * <li>GAR file.</li>
+ * <li>Local disk folder with structure of unpacked GAR file.</li>
+ * <li>Local disk folder containing only compiled Java classes.</li>
+ * </ul>
+ * <h1 class="header">GAR file</h1>
+ * GAR file is a deployable unit. GAR file is based on <a href="http://www.gzip.org/zlib/">ZLIB</a>
+ * compression format like simple JAR file and its structure is similar to WAR archive.
+ * GAR file has {@code '.gar'} extension.
+ * <p>
+ * GAR file structure (file or directory ending with {@code '.gar'}):
+ * <pre class="snippet">
+ * META-INF/
+ * |
+ * - gridgain.xml
+ * - ...
+ * lib/
+ * |
+ * -some-lib.jar
+ * - ...
+ * xyz.class
+ * ...</pre>
+ * <ul>
+ * <li>
+ * {@code META-INF/} entry may contain {@code gridgain.xml} file which is a
+ * task descriptor file. The purpose of task descriptor XML file is to specify
+ * all tasks to be deployed. This file is a regular
+ * <a href="http://www.springframework.org/documentation">Spring</a> XML
+ * definition file. {@code META-INF/} entry may also contain any other file
+ * specified by JAR format.
+ * </li>
+ * <li>
+ * {@code lib/} entry contains all library dependencies.
+ * </li>
+ * <li>Compiled Java classes must be placed in the root of a GAR file.</li>
+ * </ul>
+ * GAR file may be deployed without descriptor file. If there is no descriptor file, SPI
+ * will scan all classes in archive and instantiate those that implement
+ * {@link org.apache.ignite.compute.ComputeTask} interface. In that case, all grid task classes must have a
+ * public no-argument constructor. Use {@link org.apache.ignite.compute.ComputeTaskAdapter} adapter for
+ * convenience when creating grid tasks.
+ * <p>
+ * By default, all downloaded GAR files that have digital signature in {@code META-INF}
+ * folder will be verified and deployed only if signature is valid.
+ * <p>
+ * <h1 class="header">URI</h1>
+ * This SPI uses a hierarchical URI definition. For more information about standard URI
+ * syntax refer to {@link URI java.net.URI} documentation.
+ * <blockquote class="snippet">
+ * [<i>scheme</i><tt><b>:</b></tt>][<tt><b>//</b></tt><i>authority</i>][<i>path</i>][<tt><b>?</b></tt><i>query</i>][<tt><b>#</b></tt><i>fragment</i>]
+ * </blockquote>
+ * <p>
+ * Every URI defines its own deployment repository which will be scanned for any changes.
+ * URI itself has all information about protocol, connectivity, scan intervals and other
+ * parameters.
+ * <p>
+ * URI's may contain special characters, like spaces. If {@code encodeUri}
+ * flag is set to {@code true} (see {@link #setEncodeUri(boolean)}), then
+ * URI 'path' field will be automatically encoded. By default this flag is
+ * set to {@code true}.
+ * <p>
+ * <h1 class="header">Configuration</h1>
+ * {@code UriDeploymentSpi} has the following optional configuration
+ * parameters (there are no mandatory parameters):
+ * <ul>
+ * <li>
+ * Temporary directory path where scanned GAR files and directories are
+ * copied to (see {@link #setTemporaryDirectoryPath(String) setTemporaryDirectoryPath(String)}).
+ * </li>
+ * <li>
+ * List of URIs to scan (see {@link #setUriList(List)}). If not
+ * specified, then URI specified by {@link #DFLT_DEPLOY_DIR DFLT_DEPLOY_DIR} is used.
+ * </li>
+ * <li>
+ * Flag to control encoding of the {@code 'path'} portion of URI
+ * (see {@link #setEncodeUri(boolean) setEncodeUri(boolean)}).
+ * </li>
+ * </ul>
+ * <h1 class="header">Protocols</h1>
+ * Following protocols are supported in SPI:
+ * <ul>
+ * <li><a href="#file">file://</a> - File protocol</li>
+ * <li><a href="#classes">classes://</a> - Custom File protocol.</li>
+ * <li><a href="#ftp">ftp://</a> - File transfer protocol</li>
+ * <li><a href="#http">http://</a> - HTTP protocol</li>
+ * <li><a href="#http">https://</a> - Secure HTTP protocol</li>
+ * </ul>
+ * In addition to SPI configuration parameters, all necessary configuration
+ * parameters for selected URI should be defined in URI. Different protocols
+ * have different configuration parameters described below. Parameters are
+ * separated by '{@code ;}' character.
+ * <p>
+ * <a name="file"></a>
+ * <h1 class="header">File</h1>
+ * For this protocol SPI will scan folder specified by URI on file system and
+ * download any GAR files or directories that end with .gar from source
+ * directory defined in URI. For file system URI must have scheme equal to {@code file}.
+ * <p>
+ * Following parameters are supported for FILE protocol:
+ * <table class="doctable">
+ * <tr>
+ * <th>Parameter</th>
+ * <th>Description</th>
+ * <th>Optional</th>
+ * <th>Default</th>
+ * </tr>
+ * <tr>
+ * <td>freq</td>
+ * <td>File directory scan frequency in milliseconds.</td>
+ * <td>Yes</td>
+ * <td>{@code 5000} ms specified in {@link #DFLT_DISK_SCAN_FREQUENCY DFLT_DISK_SCAN_FREQUENCY}.</td>
+ * </tr>
+ * </table>
+ * <h2 class="header">File URI Example</h2>
+ * The following example will scan {@code 'c:/Program files/gridgain/deployment'}
+ * folder on local box every {@code '5000'} milliseconds. Note that since path
+ * has spaces, {@link #setEncodeUri(boolean) setEncodeUri(boolean)} parameter must
+ * be set to {@code true} (which is default behavior).
+ * <blockquote class="snippet">
+ * {@code file://freq=5000@localhost/c:/Program files/gridgain/deployment}
+ * </blockquote>
+ * <a name="classes"></a>
+ * <h1 class="header">Classes</h1>
+ * For this protocol SPI will scan folder specified by URI on file system
+ * looking for compiled classes that implement {@link org.apache.ignite.compute.ComputeTask} interface.
+ * This protocol comes very handy during development, as it allows developer
+ * to specify IDE compilation output folder as URI and all task classes
+ * in that folder will be deployed automatically.
+ * <p>
+ * Following parameters are supported for CLASSES protocol:
+ * <table class="doctable">
+ * <tr>
+ * <th>Parameter</th>
+ * <th>Description</th>
+ * <th>Optional</th>
+ * <th>Default</th>
+ * </tr>
+ * <tr>
+ * <td>freq</td>
+ * <td>File directory scan frequency in milliseconds.</td>
+ * <td>Yes</td>
+ * <td>{@code 5000} ms specified in {@link #DFLT_DISK_SCAN_FREQUENCY DFLT_DISK_SCAN_FREQUENCY}.</td>
+ * </tr>
+ * </table>
+ * <h2 class="header">Classes URI Example</h2>
+ * The following example will scan {@code 'c:/Program files/gridgain/deployment'}
+ * folder on local box every {@code '5000'} milliseconds. Note that since path
+ * has spaces, {@link #setEncodeUri(boolean) setEncodeUri(boolean)} parameter must
+ * be set to {@code true} (which is default behavior).
+ * <blockquote class="snippet">
+ * {@code classes://freq=5000@localhost/c:/Program files/gridgain/deployment}
+ * </blockquote>
+ * <a name="ftp"></a>
+ * <h1 class="header">FTP</h1>
+ * For FTP protocol SPI will scan and download only GAR files from source
+ * directory defined in URI. SPI doesn't scan FTP folders recursively.
+ * The following parameters are supported for FTP protocol:
+ * <table class="doctable">
+ * <tr>
+ * <th>Parameter</th>
+ * <th>Description</th>
+ * <th>Optional</th>
+ * <th>Default</th>
+ * </tr>
+ * <tr>
+ * <td>freq</td>
+ * <td>FTP location scan frequency in milliseconds.</td>
+ * <td>Yes</td>
+ * <td>{@code 300000} ms specified in {@link #DFLT_FTP_SCAN_FREQUENCY DFLT_FTP_SCAN_FREQUENCY}.</td>
+ * </tr>
+ * <tr>
+ * <td>username:password</td>
+ * <td>
+ * FTP username and password specified in standard URI server-based
+ * authority format.
+ * </td>
+ * <td>No</td>
+ * <td>---</td>
+ * </tr>
+ * </table>
+ * <h2 class="header">FTP URI Example</h2>
+ * Here is an example of an FTP URI that connects identified as
+ * {@code username:password} to {@code 'localhost'} on port {@code '21'},
+ * with initial path set to {@code 'gridgain/deployment'}
+ * <blockquote class="snippet">
+ * ftp://username:password;freq=10000@localhost:21/gridgain/deployment
+ * </blockquote>
+ * <p>
+ * <h2 class="header">HTTP URI Example</h2>
+ * The following example will scan {@code 'gridgain/deployment'} folder with
+ * on site {@code 'www.mysite.com'} using authentication
+ * {@code 'username:password'} every {@code '10000'} milliseconds.
+ * <blockquote class="snippet">
+ * {@code http://username:password;freq=10000@www.mysite.com:110/gridgain/deployment}
+ * </blockquote>
+ * <h2 class="header">Java Example</h2>
+ * UriDeploymentSpi needs to be explicitly configured to override default local deployment SPI.
+ * <pre name="code" class="java">
+ * UriDeploymentSpi deploySpi = new UriDeploymentSpi();
+ *
+ * GridConfiguration cfg = new GridConfiguration();
+ *
+ * List<String> uris = new ArrayList<String>(5);
+ *
+ * uris.add("http://www.site.com/tasks");
+ * uris.add("ftp://ftpuser:password;freq=10000@localhost:21/gg-test/deployment");
+ * uris.add("file://freq=20000@localhost/c:/Program files/gg-deployment");
+ * uris.add("classes:///c:/Java_Projects/myproject/out");
+ *
+ * // Set URIs.
+ * deploySpi.setUriList(uris);
+ *
+ * // Override temporary directory path.
+ * deploySpi.setTemporaryDirectoryPath("c:/tmp/grid");
+ *
+ * // Override default deployment SPI.
+ * cfg.setDeploymentSpi(deploySpi);
+ *
+ * // Start grid.
+ * G.start(cfg);
+ * </pre>
+ * <p>
+ * <h2 class="header">Spring Example</h2>
+ * UriDeploymentSpi can be configured from Spring XML configuration file:
+ * <pre name="code" class="xml">
+ * <bean id="grid.custom.cfg" class="org.gridgain.grid.GridConfiguration" singleton="true">
+ * ...
+ * <property name="deploymentSpi">
+ * <bean class="org.gridgain.grid.spi.deployment.uri.UriDeploymentSpi">
+ * <property name="temporaryDirectoryPath" value="c:/tmp/grid"/>
+ * <property name="uriList">
+ * <list>
+ * <value>http://www.site.com/tasks</value>
+ * <value>ftp://ftpuser:password;freq=10000@localhost:21/gg-test/deployment</value>
+ * <value>file://freq=20000@localhost/c:/Program files/gg-deployment</value>
+ * <value>classes:///c:/Java_Projects/myproject/out</value>
+ * </list>
+ * </property>
+ * </bean>
+ * </property>
+ * ...
+ * </bean>
+ * </pre>
+ * <p>
+ * <img src="http://www.gridgain.com/images/spring-small.png">
+ * <br>
+ * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
+ * @see org.apache.ignite.spi.deployment.DeploymentSpi
+ */
+@IgniteSpiMultipleInstancesSupport(true)
+@IgniteSpiConsistencyChecked(optional = false)
+@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
+public class UriDeploymentSpi extends IgniteSpiAdapter implements DeploymentSpi, UriDeploymentSpiMBean {
+ /**
+ * Default deployment directory where SPI will pick up GAR files. Note that this path is relative to
- * {@code GRIDGAIN_HOME/work} folder if {@code GRIDGAIN_HOME} system or environment variable specified,
++ * {@code IGNITE_HOME/work} folder if {@code IGNITE_HOME} system or environment variable specified,
+ * otherwise it is relative to {@code work} folder under system {@code java.io.tmpdir} folder.
+ *
+ * @see org.apache.ignite.configuration.IgniteConfiguration#getWorkDirectory()
+ */
+ public static final String DFLT_DEPLOY_DIR = "deployment/file";
+
+ /** Default scan frequency for {@code file://} and {@code classes://} protocols (value is {@code 5000}). */
+ public static final int DFLT_DISK_SCAN_FREQUENCY = 5000;
+
+ /** Default scan frequency for {@code ftp://} protocol (value is {@code 300000}). */
+ public static final int DFLT_FTP_SCAN_FREQUENCY = 300000;
+
+ /** Default scan frequency for {@code http://} protocol (value is {@code 300000}). */
+ public static final int DFLT_HTTP_SCAN_FREQUENCY = 300000;
+
+ /** Default task description file path and name (value is {@code META-INF/gridgain.xml}). */
+ public static final String XML_DESCRIPTOR_PATH = "META-INF/gridgain.xml";
+
+ /**
+ * Default temporary directory name relative to file path
+ * {@link #setTemporaryDirectoryPath(String)}} (value is {@code gg.uri.deployment.tmp}).
+ */
+ public static final String DEPLOY_TMP_ROOT_NAME = "gg.uri.deployment.tmp";
+
+ /** Temporary directory name. */
+ private String tmpDirPath;
+
+ /** Sub-folder of 'tmpDirPath'. */
+ private String deployTmpDirPath;
+
+ /** List of URIs to be scanned. */
+ private List<String> uriList = new ArrayList<>();
+
+ /** List of encoded URIs. */
+ private Collection<URI> uriEncodedList = new ArrayList<>();
+
+ /** Indicates whether md5 digest should be checked by this SPI before file deployment. */
+ private boolean checkMd5;
+
+ /** */
+ @SuppressWarnings({"CollectionDeclaredAsConcreteClass"})
+ private final LinkedList<GridUriDeploymentUnitDescriptor> unitLoaders =
+ new LinkedList<>();
+
+ /** */
+ @SuppressWarnings({"TypeMayBeWeakened"})
+ private final LastTimeUnitDescriptorComparator unitComp = new LastTimeUnitDescriptorComparator();
+
+ /** List of scanners. Every URI has it's own scanner. */
+ private final Collection<GridUriDeploymentScanner> scanners = new ArrayList<>();
+
+ /** Whether URIs should be encoded or not. */
+ private boolean encodeUri = true;
+
+ /** Whether first scan cycle is completed or not. */
+ private int firstScanCntr;
+
+ /** Deployment listener which processes all notifications from scanners. */
+ private volatile DeploymentListener lsnr;
+
+ /** */
+ private final Object mux = new Object();
+
+ /** */
+ @IgniteLoggerResource
+ private IgniteLogger log;
+
+ /** NOTE: flag for test purposes only. */
+ @SuppressWarnings("UnusedDeclaration")
+ private boolean delayOnNewOrUpdatedFile;
+
+ /**
+ * Sets absolute path to temporary directory which will be used by
+ * deployment SPI to keep all deployed classes in.
+ * <p>
+ * If not provided, default value is {@code java.io.tmpdir} system property value.
+ *
+ * @param tmpDirPath Temporary directory path.
+ */
+ @IgniteSpiConfiguration(optional = true)
+ public void setTemporaryDirectoryPath(String tmpDirPath) {
+ this.tmpDirPath = tmpDirPath;
+ }
+
+ /**
+ * Sets list of URI which point to GAR file and which should be
+ * scanned by SPI for the new tasks.
+ * <p>
+ * If not provided, default value is list with
- * {@code file://${GRIDGAIN_HOME}/work/deployment/file} element.
- * Note that system property {@code GRIDGAIN_HOME} must be set.
- * For unknown {@code GRIDGAIN_HOME} list of URI must be provided explicitly.
++ * {@code file://${IGNITE_HOME}/work/deployment/file} element.
++ * Note that system property {@code IGNITE_HOME} must be set.
++ * For unknown {@code IGNITE_HOME} list of URI must be provided explicitly.
+ *
+ * @param uriList GAR file URIs.
+ */
+ @IgniteSpiConfiguration(optional = true)
+ public void setUriList(List<String> uriList) {
+ this.uriList = uriList;
+ }
+
+ /**
+ * If set to {@code true} then SPI should exclude files with same md5s from deployment.
+ * Otherwise it should try to load new unit regardless to possible file duplication.
+ *
+ * @param checkMd5 new value for the property
+ */
+ @IgniteSpiConfiguration(optional = true)
+ public void setCheckMd5(boolean checkMd5) {
+ this.checkMd5 = checkMd5;
+ }
+
+ /**
+ * Gets {@code checkMd5} property.
+ *
+ * @return value of the {@code checkMd5} property.
+ */
+ @Override public boolean isCheckMd5() {
+ return checkMd5;
+ }
+
+ /**
+ * Indicates that URI must be encoded before usage. Encoding means replacing
+ * all occurrences of space with '%20', percent sign with '%25'
+ * and semicolon with '%3B'.
+ * <p>
+ * If not provided, default value is {@code true}.
+ *
+ * @param encodeUri {@code true} if every URI should be encoded and
+ * {@code false} otherwise.
+ */
+ @IgniteSpiConfiguration(optional = true)
+ public void setEncodeUri(boolean encodeUri) {
+ this.encodeUri = encodeUri;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String getTemporaryDirectoryPath() {
+ return tmpDirPath;
+ }
+
+ /** {@inheritDoc} */
+ @Override public List<String> getUriList() {
+ return Collections.unmodifiableList(uriList);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setListener(@Nullable DeploymentListener lsnr) {
+ this.lsnr = lsnr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void spiStop() throws IgniteSpiException {
+ for (GridUriDeploymentScanner scanner : scanners)
+ scanner.cancel();
+
+ for (GridUriDeploymentScanner scanner : scanners)
+ scanner.join();
+
+ // Clear inner collections.
+ uriEncodedList.clear();
+ scanners.clear();
+
+ List<ClassLoader> tmpClsLdrs;
+
+ // Release all class loaders.
+ synchronized (mux) {
+ tmpClsLdrs = new ArrayList<>(unitLoaders.size());
+
+ for (GridUriDeploymentUnitDescriptor desc : unitLoaders)
+ tmpClsLdrs.add(desc.getClassLoader());
+ }
+
+ for (ClassLoader ldr : tmpClsLdrs)
+ onUnitReleased(ldr);
+
+ // Delete temp directory.
+ if (deployTmpDirPath != null)
+ U.delete(new File(deployTmpDirPath));
+
+ unregisterMBean();
+
+ // Ack ok stop.
+ if (log.isDebugEnabled())
+ log.debug(stopInfo());
+ }
+
+ /** {@inheritDoc} */
+ @Override public void spiStart(String gridName) throws IgniteSpiException {
+ // Start SPI start stopwatch.
+ startStopwatch();
+
+ assertParameter(uriList != null, "uriList != null");
+
+ initializeUriList();
+
+ if (uriEncodedList.isEmpty())
+ addDefaultUri();
+
+ initializeTemporaryDirectoryPath();
+
+ registerMBean(gridName, this, UriDeploymentSpiMBean.class);
+
+ FilenameFilter filter = new FilenameFilter() {
+ @Override public boolean accept(File dir, String name) {
+ assert name != null;
+
+ return name.toLowerCase().endsWith(".gar");
+ }
+ };
+
+ firstScanCntr = 0;
+
+ GridUriDeploymentScannerListener lsnr = new GridUriDeploymentScannerListener() {
+ @Override public void onNewOrUpdatedFile(File file, String uri, long tstamp) {
+ if (log.isInfoEnabled())
+ log.info("Found new or updated GAR units [uri=" + U.hidePassword(uri) +
+ ", file=" + file.getAbsolutePath() + ", tstamp=" + tstamp + ']');
+
+ if (delayOnNewOrUpdatedFile) {
+ U.warn(log, "Delaying onNewOrUpdatedFile() by 10000 ms since 'delayOnNewOrUpdatedFile' " +
+ "is set to true (is this intentional?).");
+
+ try {
+ U.sleep(10000);
+ }
+ catch (IgniteInterruptedException ignored) {
+ // No-op
+ }
+
+ U.warn(log, "Delay finished.");
+ }
+
+ try {
+ GridUriDeploymentFileProcessorResult fileRes = GridUriDeploymentFileProcessor.processFile(file, uri,
+ new File(deployTmpDirPath), log);
+
+ if (fileRes != null)
+ newUnitReceived(uri, fileRes.getFile(), tstamp, fileRes.getClassLoader(),
+ fileRes.getTaskClasses(), fileRes.getMd5());
+ }
+ catch (IgniteSpiException e) {
+ U.error(log, "Error when processing file: " + file.getAbsolutePath(), e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onDeletedFiles(List<String> uris) {
+ if (log.isInfoEnabled()) {
+ List<String> uriList = null;
+
+ if (uris != null) {
+ uriList = new ArrayList<>();
+
+ for (String uri : uris)
+ uriList.add(U.hidePassword(uri));
+ }
+
+ log.info("Found deleted GAR units [uris=" + uriList + ']');
+ }
+
+ processDeletedFiles(uris);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onFirstScanFinished() {
+ synchronized (mux) {
+ firstScanCntr++;
+
+ if (isFirstScanFinished(firstScanCntr))
+ mux.notifyAll();
+ }
+ }
+ };
+
+ for (URI uri : uriEncodedList) {
+ String proto = uri.getScheme();
+
+ File file = new File(deployTmpDirPath);
+
+ long freq = -1;
+
+ try {
+ freq = getFrequencyFromUri(uri);
+ }
+ catch (NumberFormatException e) {
+ U.error(log, "Error parsing parameter value for frequency.", e);
+ }
+
+ assert proto != null;
+
+ GridUriDeploymentScanner scanner;
+
+ switch (proto) {
+ case "file":
+ scanner = new GridUriDeploymentFileScanner(gridName, uri, file, freq > 0 ? freq :
+ DFLT_DISK_SCAN_FREQUENCY, filter, lsnr, log);
+ break;
+
+ case "http":
+ case "https":
+ scanner = new GridUriDeploymentHttpScanner(gridName, uri, file, freq > 0 ? freq :
+ DFLT_HTTP_SCAN_FREQUENCY, filter, lsnr, log);
+ break;
+
+ case "ftp":
+ scanner = new GridUriDeploymentFtpScanner(gridName, uri, file, freq > 0 ? freq :
+ DFLT_FTP_SCAN_FREQUENCY, filter, lsnr, log);
+ break;
+
+ default:
+ throw new IgniteSpiException("Unsupported protocol: " + proto);
+ }
+
+ scanners.add(scanner);
+
+ scanner.start();
+ }
+
+ // Ack parameters.
+ if (log.isDebugEnabled()) {
+ log.debug(configInfo("tmpDirPath", tmpDirPath));
+ log.debug(configInfo("uriList", uriList));
+ log.debug(configInfo("encodeUri", encodeUri));
+ log.debug(configInfo("scanners", scanners));
+ }
+
+ // Ack ok start.
+ if (log.isDebugEnabled())
+ log.debug(startInfo());
+ }
+
+ /**
+ * Gets URI refresh frequency.
+ * URI is parsed and {@code freq} parameter value returned.
+ *
+ * @param uri URI to be parsed.
+ * @return {@code -1} if there if no {@code freq} parameter otherwise
+ * returns frequency.
+ * @throws NumberFormatException Thrown if {@code freq} parameter value
+ * is not a number.
+ */
+ private long getFrequencyFromUri(URI uri) throws NumberFormatException {
+ assert uri != null;
+
+ String userInfo = uri.getUserInfo();
+
+ if (userInfo != null) {
+ String[] arr = userInfo.split(";");
+
+ if (arr != null && arr.length > 0)
+ for (String el : arr)
+ if (el.startsWith("freq="))
+ return Long.parseLong(el.substring(5));
+ }
+
+ return -1;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable
+ @Override public DeploymentResource findResource(String rsrcName) {
+ assert rsrcName != null;
+
+ // Wait until all scanners finish their first scanning.
+ try {
+ synchronized (mux) {
+ while (!isFirstScanFinished(firstScanCntr))
+ mux.wait(5000);
+ }
+ }
+ catch (InterruptedException e) {
+ U.error(log, "Failed to wait while all scanners finish their first scanning.", e);
+
+ Thread.currentThread().interrupt();
+
+ return null;
+ }
+
+ synchronized (mux) {
+ // Last updated class loader has highest priority in search.
+ for (GridUriDeploymentUnitDescriptor unitDesc : unitLoaders) {
+ // Try to find resource for current class loader.
+ String clsName = rsrcName;
+ Class<?> clsByAlias = unitDesc.getResourcesByAlias().get(rsrcName);
+
+ if (clsByAlias != null)
+ clsName = clsByAlias.getName();
+
+ try {
+ ClassLoader ldr = unitDesc.getClassLoader();
+
+ Class<?> cls = ldr instanceof GridUriDeploymentClassLoader ?
+ ((GridUriDeploymentClassLoader)ldr).loadClassGarOnly(clsName) :
+ ldr.loadClass(clsName);
+
+ assert cls != null;
+
+ IgniteBiTuple<Class<?>, String> rsrc = unitDesc.findResource(rsrcName);
+
+ if (rsrc != null) {
+ // Recalculate resource name in case if access is performed by
+ // class name and not the resource name.
+ String alias = rsrc.get2();
+
+ return new DeploymentResourceAdapter(
+ alias != null ? alias : rsrcName,
+ cls,
+ unitDesc.getClassLoader());
+ }
+ // Ignore invalid tasks.
+ else if (!ComputeTask.class.isAssignableFrom(cls)) {
+ unitDesc.addResource(cls);
+
+ return new DeploymentResourceAdapter(rsrcName, cls, unitDesc.getClassLoader());
+ }
+ }
+ catch (ClassNotFoundException ignored) {
+ // No-op.
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean register(ClassLoader ldr, Class<?> rsrc) throws IgniteSpiException {
+ A.notNull(ldr, "ldr");
+ A.notNull(rsrc, "rsrc");
+
+ long tstamp = U.currentTimeMillis();
+
+ Collection<ClassLoader> rmvClsLdrs = new ArrayList<>();
+
+ Map<String, String> newRsrcs;
+
+ synchronized (mux) {
+ GridUriDeploymentUnitDescriptor desc = null;
+
+ // Find existing class loader.
+ for (GridUriDeploymentUnitDescriptor unitDesc : unitLoaders)
+ if (unitDesc.getClassLoader().equals(ldr)) {
+ desc = unitDesc;
+
+ break;
+ }
+
+ if (desc == null) {
+ desc = new GridUriDeploymentUnitDescriptor(tstamp, ldr);
+
+ // New unit has largest timestamp.
+ assert unitLoaders.size() <= 0 || unitComp.compare(desc, unitLoaders.getFirst()) <= 0;
+
+ unitLoaders.addFirst(desc);
+ }
+
+ newRsrcs = addResources(ldr, desc, new Class<?>[]{rsrc});
+
+ if (!F.isEmpty(newRsrcs))
+ removeResources(ldr, newRsrcs, rmvClsLdrs);
+ }
+
+ for (ClassLoader cldLdr : rmvClsLdrs)
+ onUnitReleased(cldLdr);
+
+ return !F.isEmpty(newRsrcs);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean unregister(String rsrcName) {
+ assert rsrcName != null;
+
+ Collection<ClassLoader> rmvClsLdrs = new ArrayList<>();
+
+ boolean rmv;
+
+ synchronized (mux) {
+ Map<String, String> rsrcs = U.newHashMap(1);
+
+ rsrcs.put(rsrcName, rsrcName);
+
+ rmv = removeResources(null, rsrcs, rmvClsLdrs);
+ }
+
+ for (ClassLoader cldLdr : rmvClsLdrs)
+ onUnitReleased(cldLdr);
+
+ return rmv;
+ }
+
+ /**
+ * Add new classes in class loader resource map.
+ * Note that resource map may contain two entries for one added class:
+ * task name -> class name and class name -> class name.
+ *
+ * @param ldr Registered class loader.
+ * @param desc Deployment descriptor.
+ * @param clss Registered classes array.
+ * @return Map of new resources added for registered class loader.
+ * @throws org.apache.ignite.spi.IgniteSpiException If resource already registered. Exception thrown
+ * if registered resources conflicts with rule when all task classes must be
+ * annotated with different task names.
+ */
+ @Nullable
+ private Map<String, String> addResources(ClassLoader ldr, GridUriDeploymentUnitDescriptor desc, Class<?>[] clss)
+ throws IgniteSpiException {
+ assert ldr != null;
+ assert desc != null;
+ assert clss != null;
+
+ // Maps resources to classes.
+ // Map may contain 2 entries for one class.
+ Map<String, Class<?>> alias2Cls = new HashMap<>(clss.length * 2, 1.0f);
+
+ // Check alias collision between added classes.
+ for (Class<?> cls : clss) {
+ String alias = null;
+
+ if (ComputeTask.class.isAssignableFrom(cls)) {
+ ComputeTaskName nameAnn = U.getAnnotation(cls, ComputeTaskName.class);
+
+ if (nameAnn != null)
+ alias = nameAnn.value();
+ }
+
+ // If added classes maps to one alias.
+ if (alias != null && alias2Cls.containsKey(alias) && !alias2Cls.get(alias).equals(cls))
+ throw new IgniteSpiException("Failed to register resources with given task name " +
+ "(found another class with same task name) [taskName=" + alias +
+ ", cls1=" + cls.getName() + ", cls2=" + alias2Cls.get(alias).getName() + ", ldr=" + ldr + ']');
+
+ if (alias != null) {
+ alias2Cls.put(alias, cls);
+
+ desc.addResource(alias, cls);
+ }
+ else
+ desc.addResource(cls);
+ }
+
+ Map<String, String> newRsrcs = null;
+
+ // Check collisions between added and exist classes.
+ for (Entry<String, Class<?>> entry : alias2Cls.entrySet()) {
+ String newAlias = entry.getKey();
+ String newName = entry.getValue().getName();
+ Class<?> cls = desc.getResourceByAlias(newAlias);
+
+ if (cls != null) {
+ // Different classes for the same resource name.
+ if (!cls.getName().equals(newName))
+ throw new IgniteSpiException("Failed to register resources with given task name " +
+ "(found another class with same task name in the same class loader) [taskName=" + newAlias +
+ ", existingCls=" + cls.getName() + ", newCls=" + newName + ", ldr=" + ldr + ']');
+ }
+ // Add resources that should be removed for another class loaders.
+ else {
+ if (newRsrcs == null)
+ newRsrcs = U.newHashMap(alias2Cls.size() + clss.length);
+
+ newRsrcs.put(newAlias, newName);
+ newRsrcs.put(newName, newName);
+ }
+ }
+
+ return newRsrcs;
+ }
+
+ /**
+ * Remove resources for all class loaders except {@code ignoreClsLdr}.
+ *
+ * @param ignoreClsLdr Ignored class loader or {@code null} to remove for all class loaders.
+ * @param rsrcs Resources that should be used in search for class loader to remove.
+ * @param rmvClsLdrs Class loaders to remove.
+ * @return {@code True} if resource was removed.
+ */
+ private boolean removeResources(@Nullable ClassLoader ignoreClsLdr, Map<String, String> rsrcs,
+ Collection<ClassLoader> rmvClsLdrs) {
+ assert Thread.holdsLock(mux);
+ assert rsrcs != null;
+
+ boolean res = false;
+
+ for (Iterator<GridUriDeploymentUnitDescriptor> iter = unitLoaders.iterator(); iter.hasNext();) {
+ GridUriDeploymentUnitDescriptor desc = iter.next();
+ ClassLoader ldr = desc.getClassLoader();
+
+ if (ignoreClsLdr == null || !ldr.equals(ignoreClsLdr)) {
+ boolean isRmv = false;
+
+ // Check class loader's registered resources.
+ for (String rsrcName : rsrcs.keySet()) {
+ IgniteBiTuple<Class<?>, String> rsrc = desc.findResource(rsrcName);
+
+ // Remove class loader if resource found.
+ if (rsrc != null) {
+ iter.remove();
+
+ // Add class loaders in collection to notify listener outside synchronization block.
+ rmvClsLdrs.add(ldr);
+
+ isRmv = true;
+ res = true;
+
+ break;
+ }
+ }
+
+ if (isRmv)
+ continue;
+
+ // Check is possible to load resources with classloader.
+ for (Entry<String, String> entry : rsrcs.entrySet()) {
+ // Check classes with class loader only when classes points to classes to avoid redundant check.
+ // Resources map contains two entries for class with task name(alias).
+ if (entry.getKey().equals(entry.getValue()) && isResourceExist(ldr, entry.getKey())) {
+ iter.remove();
+
+ // Add class loaders in collection to notify listener outside synchronization block.
+ rmvClsLdrs.add(ldr);
+
+ res = true;
+
+ break;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Gets resource name for a given class name.
+ *
+ * @param clsName Class name.
+ * @param rsrcs Map of resources.
+ * @return Resource name.
+ */
+ private String getResourceName(String clsName, Map<String, String> rsrcs) {
+ assert Thread.holdsLock(mux);
+
+ String rsrcName = clsName;
+
+ for (Entry<String, String> e : rsrcs.entrySet())
+ if (e.getValue().equals(clsName) && !e.getKey().equals(clsName)) {
+ rsrcName = e.getKey();
+
+ break;
+ }
+
+ return rsrcName;
+ }
+
+ /**
+ * Check is class can be reached.
+ *
+ * @param ldr Class loader.
+ * @param clsName Class name.
+ * @return {@code true} if class can be loaded.
+ */
+ private boolean isResourceExist(ClassLoader ldr, String clsName) {
+ String rsrc = clsName.replaceAll("\\.", "/") + ".class";
+
+ InputStream in = null;
+
+ try {
+ in = ldr instanceof GridUriDeploymentClassLoader ?
+ ((GridUriDeploymentClassLoader)ldr).getResourceAsStreamGarOnly(rsrc) :
+ ldr.getResourceAsStream(rsrc);
+
+ return in != null;
+ }
+ finally {
+ U.close(in, log);
+ }
+ }
+
+ /**
+ * Tests whether first scan is finished or not.
+ *
+ * @param cntr Number of already scanned URIs.
+ * @return {@code true} if all URIs have been scanned at least once and
+ * {@code false} otherwise.
+ */
+ private boolean isFirstScanFinished(int cntr) {
+ assert uriEncodedList != null;
+
+ return cntr >= uriEncodedList.size();
+ }
+
+ /**
+ * Fills in list of URIs with all available URIs and encodes them if
+ * encoding is enabled.
+ *
+ * @throws org.apache.ignite.spi.IgniteSpiException Thrown if at least one URI has incorrect syntax.
+ */
+ private void initializeUriList() throws IgniteSpiException {
+ for (String uri : uriList) {
+ assertParameter(uri != null, "uriList.get(X) != null");
+
+ assert uri != null;
+
+ String encUri = encodeUri(uri.replaceAll("\\\\", "/"));
+
+ URI uriObj;
+
+ try {
+ uriObj = new URI(encUri);
+ }
+ catch (URISyntaxException e) {
+ throw new IgniteSpiException("Failed to parse URI [uri=" + U.hidePassword(uri) +
+ ", encodedUri=" + U.hidePassword(encUri) + ']', e);
+ }
+
+ if (uriObj.getScheme() == null || uriObj.getScheme().trim().isEmpty())
+ throw new IgniteSpiException("Failed to get 'scheme' from URI [uri=" +
+ U.hidePassword(uri) +
+ ", encodedUri=" + U.hidePassword(encUri) + ']');
+
+ uriEncodedList.add(uriObj);
+ }
+ }
+
+ /**
+ * Add configuration for file scanner {@link GridUriDeploymentFileScanner}.
+ *
+ * @throws org.apache.ignite.spi.IgniteSpiException Thrown if default URI syntax is incorrect.
+ */
+ private void addDefaultUri() throws IgniteSpiException {
+ assert uriEncodedList != null;
+
+ URI uri;
+
+ try {
+ uri = U.resolveWorkDirectory(DFLT_DEPLOY_DIR, false).toURI();
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteSpiException("Failed to initialize default file scanner", e);
+ }
+
+ uriEncodedList.add(uri);
+ }
+
+ /**
+ * Encode URI path if encoding is enabled. Set of encoded characters
+ * in path is (' ', ';', '%').
+ *
+ * @param path URI which should be encoded.
+ * @return Either encoded URI if encoding is enabled or given one
+ * if encoding is disabled.
+ */
+ private String encodeUri(String path) {
+ return encodeUri ? new GridUriDeploymentUriParser(path).parse() : path;
+ }
+
+ /**
+ * Initializes temporary directory path. Path consists of base path
+ * (either {@link #tmpDirPath} value or {@code java.io.tmpdir}
+ * system property value if first is {@code null}) and path relative
+ * to base one - {@link #DEPLOY_TMP_ROOT_NAME}/{@code local node ID}.
+ *
+ * @throws org.apache.ignite.spi.IgniteSpiException Thrown if temporary directory could not be created.
+ */
+ private void initializeTemporaryDirectoryPath() throws IgniteSpiException {
+ String tmpDirPath = this.tmpDirPath == null ? System.getProperty("java.io.tmpdir") : this.tmpDirPath;
+
+ if (tmpDirPath == null)
+ throw new IgniteSpiException("Error initializing temporary deployment directory.");
+
+ File dir = new File(tmpDirPath + File.separator + DEPLOY_TMP_ROOT_NAME + File.separator +
+ ignite.configuration().getNodeId());
+
+ if (!U.mkdirs(dir))
+ throw new IgniteSpiException("Error initializing temporary deployment directory: " + dir);
+
+ if (!dir.isDirectory())
+ throw new IgniteSpiException("Temporary deployment directory path is not a valid directory: " + dir);
+
+ if (!dir.canRead() || !dir.canWrite())
+ throw new IgniteSpiException("Can not write to or read from temporary deployment directory: " + dir);
+
+ this.tmpDirPath = tmpDirPath;
+
+ deployTmpDirPath = dir.getPath();
+ }
+
+ /**
+ * Deploys all tasks that correspond to given descriptor.
+ * First method checks tasks versions and stops processing tasks that
+ * have both versioned and unversioned instances.
+ * <p>
+ * Than it deletes tasks with lower version and deploys newest tasks.
+ *
+ * @param newDesc Tasks deployment descriptor.
+ * @param clss Registered classes.
+ */
+ private void newUnitReceived(GridUriDeploymentUnitDescriptor newDesc, Collection<Class<?>> clss) {
+ assert newDesc != null;
+ assert newDesc.getType() == GridUriDeploymentUnitDescriptor.Type.FILE;
+
+ if (clss != null && !clss.isEmpty()) {
+ try {
+ addResources(newDesc.getClassLoader(), newDesc, clss.toArray(new Class<?>[clss.size()]));
+ }
+ catch (IgniteSpiException e) {
+ U.warn(log, "Failed to register GAR class loader [newDesc=" + newDesc +
+ ", msg=" + e.getMessage() + ']');
+ }
+ }
+
+ Collection<ClassLoader> rmvClsLdrs = new ArrayList<>();
+
+ synchronized (mux) {
+ if (checkMd5 && unitDeployed(newDesc.getMd5())) {
+ if (log.isInfoEnabled())
+ LT.info(log, "Skipping new deployment unit because of md5 match " +
+ "[uri='" + U.hidePassword(newDesc.getUri()) +
+ "', file=" + (newDesc.getFile() == null ? "N/A" : newDesc.getFile()) + ']');
+
+ return;
+ }
+
+ boolean isAdded = false;
+ boolean ignoreNewUnit = false;
+
+ for (ListIterator<GridUriDeploymentUnitDescriptor> iter = unitLoaders.listIterator();
+ iter.hasNext();) {
+ GridUriDeploymentUnitDescriptor desc = iter.next();
+
+ assert !newDesc.getClassLoader().equals(desc.getClassLoader()) :
+ "Uri scanners always create new class loader for every GAR file: " + newDesc;
+
+ // Only for GAR files. Undeploy all for overwritten GAR files.
+ if (desc.getType() == GridUriDeploymentUnitDescriptor.Type.FILE &&
+ newDesc.getUri().equals(desc.getUri()) && !newDesc.getFile().equals(desc.getFile())) {
+ // Remove descriptor.
+ iter.remove();
+
+ // Add class loaders in collection to notify listener outside synchronization block.
+ rmvClsLdrs.add(desc.getClassLoader());
+
+ // Last descriptor.
+ if (!iter.hasNext())
+ // New descriptor will be added after loop.
+ break;
+
+ continue;
+ }
+
+ if (!isAdded) {
+ // Unit with largest timestamp win.
+ // Insert it before current element.
+ if (unitComp.compare(newDesc, desc) <= 0) {
+ // Remove current class loader if found collisions.
+ if (checkUnitCollision(desc, newDesc)) {
+ iter.remove();
+ iter.add(newDesc);
+
+ // Add class loaders in collection to notify listener outside synchronization block.
+ rmvClsLdrs.add(desc.getClassLoader());
+ }
+ // Or add new class loader before current class loader.
+ else {
+ iter.set(newDesc);
+ iter.add(desc);
+ }
+
+ isAdded = true;
+ }
+ else if (checkUnitCollision(newDesc, desc)) {
+ // Don't add new unit if found collisions with latest class loader.
+ ignoreNewUnit = true;
+ break;
+ }
+ }
+ // New descriptor already added and we need to check other class loaders for collisions.
+ else if (checkUnitCollision(newDesc, desc)) {
+ iter.remove();
+
+ // Add class loaders in collection to notify listener outside synchronization block.
+ rmvClsLdrs.add(desc.getClassLoader());
+ }
+ }
+
+ if (!ignoreNewUnit) {
+ if (!isAdded)
+ unitLoaders.add(newDesc);
+
+ if (log.isDebugEnabled())
+ LT.info(log, "Class loader (re)registered [clsLdr=" + newDesc.getClassLoader() +
+ ", tstamp=" + newDesc.getTimestamp() +
+ ", uri='" + U.hidePassword(newDesc.getUri()) +
+ "', file=" + (newDesc.getFile() == null ? "N/A" : newDesc.getFile()) + ']');
+ }
+ }
+
+ for (ClassLoader cldLdr : rmvClsLdrs)
+ onUnitReleased(cldLdr);
+ }
+
+ /**
+ * Check task resource collisions in added descriptor {@code newDesc} with another
+ * descriptor {@code existDesc}.
+ *
+ * @param newDesc New added descriptor.
+ * @param existDesc Exist descriptor.
+ * @return {@code True} if collisions found.
+ */
+ private boolean checkUnitCollision(GridUriDeploymentUnitDescriptor newDesc,
+ GridUriDeploymentUnitDescriptor existDesc) {
+ assert newDesc != null;
+ assert existDesc != null;
+
+ Map<String, Class<?>> rsrcsByAlias = newDesc.getResourcesByAlias();
+
+ for (Entry<String, Class<?>> entry : existDesc.getResourcesByAlias().entrySet()) {
+ String rsrcName = entry.getKey();
+
+ if (rsrcsByAlias.containsKey(rsrcName)) {
+ U.warn(log, "Found collision with task name in different GAR files. " +
+ "Class loader will be removed [taskName=" + rsrcName + ", cls1=" + rsrcsByAlias.get(rsrcName) +
+ ", cls2=" + entry.getValue() + ", newDesc=" + newDesc + ", existDesc=" + existDesc + ']');
+
+ return true;
+ }
+ }
+
+ for (Class<?> rsrcCls : existDesc.getResources()) {
+ if (!ComputeTask.class.isAssignableFrom(rsrcCls) &&
+ isResourceExist(newDesc.getClassLoader(), rsrcCls.getName())) {
+ U.warn(log, "Found collision with task class in different GAR files. " +
+ "Class loader will be removed [taskCls=" + rsrcCls +
+ ", removedDesc=" + newDesc + ", existDesc=" + existDesc + ']');
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Deploys or redeploys given tasks.
+ *
+ * @param uri GAR file deployment URI.
+ * @param file GAR file.
+ * @param tstamp File modification date.
+ * @param ldr Class loader.
+ * @param clss List of tasks which were found in GAR file.
+ * @param md5 md5 of the new unit.
+ */
+ private void newUnitReceived(String uri, File file, long tstamp, ClassLoader ldr,
+ Collection<Class<? extends ComputeTask<?, ?>>> clss, @Nullable String md5) {
+ assert uri != null;
+ assert file != null;
+ assert tstamp > 0;
+
+ // To avoid units with incorrect timestamp.
+ tstamp = Math.min(tstamp, U.currentTimeMillis());
+
+ // Create descriptor.
+ GridUriDeploymentUnitDescriptor desc = new GridUriDeploymentUnitDescriptor(uri, file, tstamp, ldr, md5);
+
+ newUnitReceived(desc, clss != null && !clss.isEmpty() ? new ArrayList<Class<?>>(clss) : null);
+ }
+
+ /**
+ * Removes all tasks that belong to GAR files which are on list
+ * of removed files.
+ *
+ * @param uris List of removed files.
+ */
+ @SuppressWarnings({"TypeMayBeWeakened"})
+ private void processDeletedFiles(List<String> uris) {
+ assert uris != null;
+
+ if (uris.isEmpty())
+ return;
+
+ synchronized (mux) {
+ Set<String> uriSet = new HashSet<>(uris);
+
+ for (Iterator<GridUriDeploymentUnitDescriptor> iter = unitLoaders.iterator(); iter.hasNext();) {
+ GridUriDeploymentUnitDescriptor desc = iter.next();
+
+ if (desc.getType() == GridUriDeploymentUnitDescriptor.Type.FILE && uriSet.contains(desc.getUri())) {
+ // Remove descriptor.
+ iter.remove();
+
+ onUnitReleased(desc.getClassLoader());
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies listener about released class loader.
+ *
+ * @param clsLdr Released class loader.
+ */
+ private void onUnitReleased(ClassLoader clsLdr) {
+ // Make sure we don't remove system class loader.
+ if (!clsLdr.equals(getClass().getClassLoader()))
+ GridUriDeploymentFileProcessor.cleanupUnit(clsLdr, log);
+
+ DeploymentListener tmp = lsnr;
+
+ if (tmp != null)
+ tmp.onUnregistered(clsLdr);
+ }
+
+ /**
+ * Checks if a nut with the same md5 ai already deployed with this SPI.
+ *
+ * @param md5 md5 of a new unit.
+ * @return {@code true} if this unit deployed, {@code false} otherwise.
+ */
+ private boolean unitDeployed(String md5) {
+ assert Thread.holdsLock(mux);
+
+ if (md5 != null) {
+ for (GridUriDeploymentUnitDescriptor d: unitLoaders)
+ if (md5.equals(d.getMd5()))
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Task deployment descriptor comparator.
+ * The greater descriptor is those one that has less timestamp.
+ */
+ private static class LastTimeUnitDescriptorComparator implements Comparator<GridUriDeploymentUnitDescriptor>,
+ Serializable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override public int compare(GridUriDeploymentUnitDescriptor o1, GridUriDeploymentUnitDescriptor o2) {
+ if (o1.getTimestamp() < o2.getTimestamp())
+ return 1;
+
+ return o1.getTimestamp() == o2.getTimestamp() ? 0 : -1;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(UriDeploymentSpi.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/urideploy/src/test/java/org/apache/ignite/spi/deployment/uri/scanners/file/GridFileDeploymentSelfTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/visor-console/src/main/scala/org/apache/ignite/visor/visor.scala
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/115f5979/modules/web/src/main/java/org/apache/ignite/cache/websession/GridWebSessionFilter.java
----------------------------------------------------------------------