code.onehippo.org is currently readonly. We are migrating to code.bloomreach.com, please continue working there on Monday 14/12. See: https://docs.bloomreach.com/display/engineering/GitLab

Commit ff133e69 authored by Ate Douma's avatar Ate Douma

REPO-1897 [Backport 10.2] Implement new LockManager service and replace all...

REPO-1897 [Backport 10.2] Implement new LockManager service and replace all deprecated HippoLock and HippoLockManager usages

This is a cherry-picked and squashed backport from REPO-1881 and REPO-1887:

  REPO-1811 Implement in-memory lock manager

    (cherry picked from commit dfa6f279)

  REPO-1811 To the RepositoryImpl add a Journal ConnectionHelper accessor

    Via this Journal ConnectionHelper we can access the Journal DataSource
    via the ConnectionHelperDataSourceAccessor.

    Admittedly, a bit clumsy but we need access to the Journal DataSource
    because we need to know whether we are dealing with a database *and*
    whether we have a clustered setup : Only in that case, the lock mechanism
    has to be upgraded from in memory locking to db base locking because
    needs to be cluster wide

    (cherry picked from commit 4750450f)

  REPO-1811 Support for a Database lock manager

    The Database lock manager interaction is pretty much exactly the same
    as the MemoryLockManager interaction. The biggest difference is that
    the DbLockManager creates database based locks and the MemoryLockManager
    creates MemoryLocks. Note that a DbLock is the same as the MemoryLock
    but only contains a #destroy implementation that releases the database
    lock.

    The DbLockManager is still work in progress

    (cherry picked from commit e0f19fab)

  REPO-1811 Fix the LockClusterTest setup

    (still ignored but the setup failed since we do not allow SNS
    below jcr:root any more)

    (cherry picked from commit 1dba0d49)

  REPO-1811 Support database locking

    (cherry picked from commit 92c914ef)

  REPO-1811 Support background jobs in the Memory or Db LockManager

    - All the background jobs are run by a single thread
    - By default they run every 5 seconds with an initial delay of 5 seconds
    - Every background job is wrapped in a 'synchronized runnable' the synchronized
      on the LockManager instance: The reason for this is that we do not want
      background jobs to write concurrently to possibly the same records as
      other (background) jobs
    - We have the following background jobs:
      1) UnlockStoppedThreadJanitor : releases database locks for records
         that were held by a thread that is not alive any more
      2) DbResetExpiredLocksJanitor : Resets all database rows which have
         expired locks (rows with status 'RUNNING' or 'ABORT' and expirationTime
         has passed
      3) DbLockRefresher: Refreshes the expiresTime of a lock to currentTime + refreshRateSeconds
      4) LockThreadInterrupter : Interrupts the Thread that holds the lock that has been marked 'ABORT'

    (cherry picked from commit cbf14aed)

  REPO-1811 Make sure getLocks and isLocked works cluster wide in case of a database

    (cherry picked from commit 441beff4)

  REPO-1811 Fix sql statement

    (cherry picked from commit d3d25849)

  REPO-1811 Extract abstract test and add an 'abort' test

    (cherry picked from commit 5ab1e55f)

  REPO-1811 use getHoldCount() instead of protected access

    (cherry picked from commit 7027fce3)

  REPO-1811 improve feedback

    (cherry picked from commit 0bf87cb5)

  REPO-1811 use getHoldCount() instead of protected access

    (cherry picked from commit a268b5e6)

  REPO-1811 Fix abort statement

    (cherry picked from commit dac8d9cc)

  REPO-1811 Encapsulate the localLocks object

    Since localLocks is a hashmap, all access to it should be synchronized.
    This can be easier achieved by encapsulating it and whenever needed by
    other classes, return a new object containing the same locks

    (cherry picked from commit cc3e10d9)

  REPO-1811 Enhance abort tests

    (cherry picked from commit 43f17029)

  REPO-1811 use auto closable in integration tests

    (cherry picked from commit 05143edd)

  REPO-1811 Correct the expiresTime parameter

    (cherry picked from commit 62bd68c2)

  REPO-1811 Locks in status ABORT should also be refreshed

    Namely if a lock is in status ABORT and the lock is for the *CLUSTER NODE*
    on which the DbLockRefresher runs, then it means that on this cluster
    node the Thread that should be aborted did not yet abort (for example
    still busy with its job). All we can do is wait until that job finishes

    (cherry picked from commit f038ec5b)

  REPO-1811 remove unneeded auto commit

    (cherry picked from commit 591ff099)

  REPO-1811 If a Thread is already interrupted, don't interrupt again

    (cherry picked from commit 8a6b58b3)

  REPO-1811 Integration tests that confirm the correct working of the DbLockRefresher

    (cherry picked from commit a3bc5d1f)

  REPO-1811 Tests to confirm lock expiration

    Integration tests that confirm the correct working of the
    DbResetExpiredLocksJanitor

    (cherry picked from commit c2284223)

  REPO-1811 only run expires db lock test in integration test

    (cherry picked from commit 79490e41)

  REPO-1811 Fix test to have flexible logger node test

    (cherry picked from commit 547542ef)

  REPO-1811 Improve exception handling and logging

    (cherry picked from commit 4fdb9278)

  REPO-1811 Improved destroy of the LockManager and other improvements

    (cherry picked from commit 589c19b8)

  REPO-1811 Remove the 'refreshRateSeconds' logic

    Just fixed 60 seconds refresh rate

    (cherry picked from commit b51f32d9)

  REPO-1811 Deprecate JCR (hippo) locking

    Note all usages of JCR Locking still need to be replaced

    (cherry picked from commit 04c17617)

  REPO-1811 Use the new LockManager instead of JCR Locking

    (cherry picked from commit 8ddbbc21)

  REPO-1811 Implement autocloseable LockResource and integration tests

    (cherry picked from commit ac0b839d)

  REPO-1811 Use auto closeable

    (cherry picked from commit 6938d49c)

  REPO-1811 Add a cleanup background job that removes rows from database of old locks

    (cherry picked from commit bb1f233b)

  REPO-1811 Implement new LockResource getters

    (cherry picked from commit e209d242)

  REPO-1811 Better tearDown

    Make sure tearDown with clearing the repository still removes
    also the database entries because if they are kept, consequent runs can fail

    (cherry picked from commit ffb7b9a6)

  REPO-1811 shorter keys

    (cherry picked from commit 87e1cb4b)

  REPO-1811 Support all databases and most specifically Oracle

    (cherry picked from commit 03072bf6)

  REPO-1811 Handle the interrupted exception gracefully

    When the lockmanager has an indication for 'abort' for the lock for the
    thread that is executing the UpdateExecutor, it means, that the current
    or a different cluster node has requested the task to be stopped. Invoking
    #cancel is the graceful stop of the job

    (cherry picked from commit 6354174b)

  REPO-1811 further refactoring and cleanup of the new (Db)LockManager

    - construction moved to LocalHippoRepository as well as further generalized
    - LockManagerFactory moved to DbLockManagerFactory and now only is responsible for constructing a DbLockManager
    - DbLockManager: added support for schemaObjectPrefix and schemaCheckEnabled, like all JR schema definitions
    - Added (handling for) new AlreadyLockedException, indicating a lock retry might be feasible
    - Merged DbHelper logic into DbLockManager (which ittself now gets passed into background Runnables) and use JR ConnectionHelper to check if table already exists
    - Added LockManagerUtilsTest, in test module, for services-api provided LockManagerUtils

    (cherry picked from commit 035c7ff9)

  REPO-1811 Improve the logging statement

    (cherry picked from commit 11f334ee)

  REPO-1811 Make sure the lockThread finishes before tearDown kicks in

    (cherry picked from commit f81fb33e)

  REPO-1811 license header

  (cherry picked from commit ab46d905)

  REPO-1811 fix unit tests

    (cherry picked from commit 84858ae4)

  REPO-1873 Support closing a LockResource by a different thread - implementation

    (cherry picked from commit 8e614323)

  REPO-1873 improve LocalHippoRepository instantiation extensibility

    (cherry picked from commit 79f365d3)

  REPO-1874 Leverage LockManager for the RepositoryScheduler replacing the deprecated HippoLock usage

    (cherry picked from commit 7e91d6c3)

  REPO-1875 add support for mssql (Microsoft SQL Server)

    Also added test configurations for mssql, postgresql and oracle in repository-test module, and updated/aligned the repository.xml and test/connection parameters for each of these.

    (cherry picked from commit 92213cda)

(cherry picked from commit fceda60165179a1aee27e095c7c649553debd36e)
(cherry picked from commit b05161a4)

  REPO-1881 ensure configuration.xml is found, also within unit tests

    (cherry picked from commit 282cb7a1)

  REPO-1881: [Backport 11.2] load HippoEnterpriseRepository instead of LocalHippoRepository, if available

    (cherry picked from commit b07f4308)
    (cherry picked from commit 6c3b3782)
    (cherry picked from commit 79148a61)

    (cherry picked from commit a70298c4)

  REPO-1887 [Backport 11.2] LockManager unit tests improvements

    (cherry picked from commit 77715d79)

    A couple of tests have the following pattern:
     @Test
        public void assert_something() throws Exception {
            Thread lockThread = new Thread(() -> {
                fail("I failed");
            });
            lockThread.start();
            lockThread.join();
        }
    The problem with this pattern is that although something gets logged like
    Exception in thread "Thread-2" java.lang.AssertionError: I failed
    the test itself just passes because the Thread the runs the test didn't get the exception

    Next to this, also improved the LockManagerBasicTest to not use Thread.sleep
    and also include the LockResource in its tests

    (cherry picked from commit f46028aa)
    (cherry picked from commit c7572bae)

  REPO-1887 [Backport 11.2] Make sure thread really stopped before continuing

    (cherry picked from commit 81d479e3)
    (cherry picked from commit db4470ab)

  REPO-1881 move specific tests which cannot reuse an previously started repository to integration test phase

    (cherry picked from commit 23d39e1c)
parent 78715923
/.classpath
/.idea
/.project
/.settings
api/*.iml
api/*.tmp
api/.classpath
api/.project
api/.settings
api/datanucleus.log
api/local.properties
api/nbproject
api/repository
api/target
api/tm.epoch
api/tm.out
api/tm.out.1
api/tm.out.lck
api/tmlog.lck
api/version
api/wdbp-error-log.txt
api/workspaces
builtin/.classpath
builtin/.project
builtin/.settings
builtin/hippo-repository-builtin.iml
builtin/target
config/.classpath
config/.project
config/.settings
config/hippo-repository-config.iml
config/target
connector/*.iml
connector/*.tmp
connector/.classpath
connector/.project
connector/.settings
connector/local.properties
connector/nbproject
connector/target
connector/tm.epoch
connector/tm.out
connector/tm.out.1
connector/tm.out.lck
connector/tmlog.lck
connector/wdbp-error-log.txt
/datanucleus.log
/debuglog
dependencies/*.iml
dependencies/.project
dependencies/.settings
dependencies/target
deprecated/*.iml
deprecated/.project
deprecated/.settings
deprecated/facetsearch/*.iml
deprecated/facetsearch/.classpath
deprecated/facetsearch/.project
deprecated/facetsearch/.settings
deprecated/facetsearch/target
deprecated/facetselectmirror/.classpath
deprecated/facetselectmirror/.project
deprecated/facetselectmirror/.settings
deprecated/facetselectmirror/hippo-repository-deprecated-facetselectmirror.iml
deprecated/facetselectmirror/target
deprecated/target
engine/*.tmp
engine/.classpath
engine/.pom.xml.swp
engine/.project
engine/.settings
engine/derby.log
engine/hippo-repository-engine.iml
engine/jpox.log
engine/local.properties
engine/log4j.log
engine/nbproject
engine/repository
engine/src/main/java/org/hippoecm/repository/standardworkflow/.VersionWorkflowImpl.java.swp
engine/src/test/java/org/hippoecm/repository/.ConfigurationTest.java.swp
engine/target
engine/tm.epoch
engine/tm.out
engine/tm.out.1
engine/tm.out.lck
engine/tmlog.lck
engine/version
engine/wdbp-error-log.txt
engine/workspaces
/hippo-repository.iml
jaxrs/*.iml
jaxrs/log4j.log
jaxrs/target
/jpox.log
/log4j.log
modules/*.iml
modules/*.tmp
modules/.classpath
modules/.project
modules/.settings
modules/local.properties
modules/nbproject
modules/target
modules/tm.epoch
modules/tm.out
modules/tm.out.1
modules/tm.out.lck
modules/tmlog.lck
modules/wdbp-error-log.txt
provider/*.iml
provider/*.tmp
provider/.classpath
provider/.pom.xml.swp
provider/.project
provider/.settings
provider/jpox.log
provider/local.properties
provider/nbproject
provider/target
provider/tm.epoch
provider/tm.out
provider/tm.out.1
provider/tm.out.lck
provider/tmlog.lck
provider/wdbp-error-log.txt
resources/*.iml
resources/.classpath
resources/.project
resources/.settings
resources/target
scripts/.classpath
scripts/.project
scripts/.settings
scripts/hippo-repository-scripts.iml
scripts/target
servlets/*.iml
servlets/*.tmp
servlets/.classpath
servlets/.pom.xml.swp
servlets/.project
servlets/.settings
servlets/jpox.log
servlets/local.properties
servlets/nbproject
servlets/target
servlets/tm.epoch
servlets/tm.out
servlets/tm.out.1
servlets/tm.out.lck
servlets/tmlog.lck
servlets/wdbp-error-log.txt
/target
test/*.tmp
test/.classpath
test/.project
test/.settings
test/checker-repository.xml
test/checker-storage
test/checker.jar
test/checker.properties
test/datanucleus.log
test/derby.log
test/hippo-repository-test.iml
test/jpox.log
test/local.properties
test/log4j.log
test/nbproject
test/repository
test/src/test/java/org/hippoecm/repository/decorating/.MirrorTest.java.swp
test/src/test/java/org/onehippo/repository/scratchpad
test/src/test/resources/org/onehippo/repository/scratchpad
test/target
test/tm.epoch
test/tm.out
test/tm.out.1
test/tm.out.lck
test/tmlog.lck
test/version
test/wdbp-error-log.txt
test/workspaces
testcontent/.classpath
testcontent/.project
testcontent/.settings
testcontent/hippo-repository-testcontent.iml
testcontent/target
testutils/*.tmp
testutils/.classpath
testutils/.project
testutils/.settings
testutils/hippo-repository-testutils.iml
testutils/local.properties
testutils/nbproject
testutils/repository
testutils/target
testutils/tm.epoch
testutils/tm.out
testutils/tm.out.1
testutils/tm.out.lck
testutils/tmlog.lck
testutils/version
testutils/wdbp-error-log.txt
testutils/workspaces
upgrade/*.iml
upgrade/*.tmp
upgrade/.classpath
upgrade/.project
upgrade/.settings
upgrade/bin
upgrade/local.properties
upgrade/nbproject
upgrade/target
upgrade/tm.epoch
upgrade/tm.out
upgrade/tm.out.1
upgrade/tm.out.lck
upgrade/tmlog.lck
upgrade/wdbp-error-log.txt
utilities/*.iml
utilities/*.tmp
utilities/.classpath
utilities/.project
utilities/.settings
utilities/local.properties
utilities/nbproject
utilities/target
utilities/tm.epoch
utilities/tm.out
utilities/tm.out.1
utilities/tm.out.lck
utilities/tmlog.lck
utilities/wdbp-error-log.txt
workflow/*.iml
workflow/*.log
workflow/.classpath
workflow/.project
workflow/.settings
workflow/target
/workspaces
*.iml
*.log
*.tmp
/.idea/
.classpath
.project
.settings
.DS_Store
target/
/engine/workspaces/
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
* Copyright 2015-2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -20,6 +20,25 @@ import javax.jcr.RepositoryException;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
/**
* JCR locking is deprecated, use {@link org.onehippo.cms7.services.lock.LockManager} instead. Creating a (cluster wide)
* lock with {@link org.onehippo.cms7.services.lock.LockManager} can be achieved as follows:
* <code>
* <pre>
* final LockManager lockManager = HippoServiceRegistry.getService(LockManager.class);
* try {
* lockManager.lock(key);
* // do locked work
* } catch (LockException e) {
* log.info("{} already locked", key);
* } finally {
* lockManager.unlock(key);
* }
* </pre>
* </code>
* @deprecated since 5.0.3
*/
@Deprecated
public interface HippoLock extends Lock {
/**
......
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
* Copyright 2015-2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -18,6 +18,25 @@ package org.onehippo.repository.locking;
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockManager;
/**
* JCR locking is deprecated, use {@link org.onehippo.cms7.services.lock.LockManager} instead. Creating a (cluster wide)
* lock with {@link org.onehippo.cms7.services.lock.LockManager} can be achieved as follows:
* <code>
* <pre>
* final LockManager lockManager = HippoServiceRegistry.getService(LockManager.class);
* try {
* lockManager.lock(key);
* // do locked work
* } catch (LockException e) {
* log.info("{} already locked", key);
* } finally {
* lockManager.unlock(key);
* }
* </pre>
* </code>
* @deprecated since 5.0.3
*/
@Deprecated
public interface HippoLockManager extends LockManager {
/**
......
/*
* Copyright 2009-2013 Hippo B.V. (http://www.onehippo.com)
* Copyright 2009-2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -17,7 +17,6 @@ package org.hippoecm.repository;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
......@@ -31,6 +30,18 @@ public class HippoRepositoryFactory {
private static String defaultLocation = null; // FIXME: should become: "java:comp/env/jcr/repository";
private static HippoRepository defaultRepository = null;
private static Class localRepositoryClass = null;
private static Class getLocalHippoRepositoryClass() throws ClassNotFoundException {
if (localRepositoryClass == null) {
try {
localRepositoryClass = Class.forName("com.onehippo.repository.HippoEnterpriseRepository");
} catch (ClassNotFoundException e) {
localRepositoryClass = Class.forName("org.hippoecm.repository.LocalHippoRepository");
}
}
return localRepositoryClass;
}
private HippoRepositoryFactory() {
}
......@@ -71,8 +82,7 @@ public class HippoRepositoryFactory {
}
try {
Class cls = Class.forName("org.hippoecm.repository.LocalHippoRepository");
defaultRepository = (HippoRepository) cls.getMethod("create", new Class[] { String.class } ).invoke(null, (String)null);
defaultRepository = (HippoRepository) getLocalHippoRepositoryClass().getMethod("create", new Class[] { String.class } ).invoke(null, (String)null);
} catch(NoSuchMethodException ex) {
throw new RepositoryException(ex);
} catch(InvocationTargetException ex) {
......@@ -128,54 +138,13 @@ public class HippoRepositoryFactory {
}
}
if(location.startsWith("bootstrap:")) {
try {
location = location.substring("bootstrap:".length());
return (HippoRepository) Class.forName("org.hippoecm.repository.BootstrapHippoRepository").getMethod("create", new Class[] { String.class }).invoke(null, new Object[] { location });
} catch(ClassNotFoundException ex) {
throw new RepositoryException(ex);
} catch(NoSuchMethodException ex) {
throw new RepositoryException(ex);
} catch(IllegalAccessException ex) {
throw new RepositoryException(ex);
} catch(InvocationTargetException ex) {
if (ex.getCause() instanceof RepositoryException) {
throw (RepositoryException) ex.getCause();
} else if (ex.getCause() instanceof IllegalArgumentException) {
throw new RepositoryException("Invalid data: " + ex.getCause());
} else {
throw new RepositoryException("unchecked exception: " + ex.getMessage());
}
}
}
if(location.startsWith("vm:")) {
return VMHippoRepository.create(location);
}
if(location.startsWith("proxy:")) {
try {
return (HippoRepository) Class.forName("org.hippoecm.repository.proxyrepository.ProxyHippoRepository").getMethod("create", new Class[] { String.class }).invoke(null, new Object[] { location });
} catch(ClassNotFoundException ex) {
throw new RepositoryException(ex);
} catch(NoSuchMethodException ex) {
throw new RepositoryException(ex);
} catch(IllegalAccessException ex) {
throw new RepositoryException(ex);
} catch(InvocationTargetException ex) {
if (ex.getCause() instanceof RepositoryException) {
throw (RepositoryException) ex.getCause();
} else if (ex.getCause() instanceof IllegalArgumentException) {
throw new RepositoryException("Invalid data: " + ex.getCause());
} else {
throw new RepositoryException("unchecked exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
}
}
}
// embedded/local with location
try {
repository = (HippoRepository) Class.forName("org.hippoecm.repository.LocalHippoRepository").getMethod("create", new Class[] { String.class }).invoke(null, new Object[] { location });
repository = (HippoRepository) getLocalHippoRepositoryClass().getMethod("create", new Class[] { String.class }).invoke(null, new Object[] { location });
} catch(ClassNotFoundException ex) {
throw new RepositoryException(ex);
} catch(NoSuchMethodException ex) {
......@@ -183,22 +152,30 @@ public class HippoRepositoryFactory {
} catch(IllegalAccessException ex) {
throw new RepositoryException(ex);
} catch(InvocationTargetException ex) {
if (ex.getCause() instanceof RepositoryException) {
throw (RepositoryException) ex.getCause();
} else if (ex.getCause() instanceof IllegalArgumentException) {
throw new RepositoryException("Invalid data: " + ex.getCause(), ex);
final Throwable cause = unwindInvocationTargetException(ex);
if (cause instanceof RepositoryException) {
throw (RepositoryException) cause;
} else if (cause instanceof IllegalArgumentException) {
throw new RepositoryException("Invalid data: " + cause, cause);
} else {
throw new RepositoryException("unchecked exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
throw new RepositoryException("unchecked exception: " + cause.getClass().getName() + ": " + cause.getMessage(), cause);
}
}
return repository;
}
private static Throwable unwindInvocationTargetException(final InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause != null && cause instanceof InvocationTargetException) {
return unwindInvocationTargetException((InvocationTargetException)cause);
}
return cause == null ? e : cause;
}
static void unregister(HippoRepository repository) {
if (repository == defaultRepository) {
defaultRepository = null;
}
}
}
/*
* Copyright 2015 Hippo B.V. (http://www.onehippo.com)
* Copyright 2015-2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -25,7 +25,10 @@ import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import javax.jcr.lock.LockManager;
/**
* @deprecated since 5.0.3
*/
@Deprecated
public class LockManagerDecorator implements LockManager {
protected final Session session;
......
......@@ -171,11 +171,38 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/RefreshTest.java</exclude>
<exclude>**/ExternalRepositorySyncRevisionServiceTest.java</exclude>
<exclude>**/ExternalRepositorySyncRevisionServiceNoClusterTest.java</exclude>
</excludes>
<systemPropertyVariables>
<org.onehippo.repository.test.keepserver>true</org.onehippo.repository.test.keepserver>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/RefreshTest.java</include>
<include>**/ExternalRepositorySyncRevisionServiceTest.java</include>
<include>**/ExternalRepositorySyncRevisionServiceNoClusterTest.java</include>
</includes>
<systemPropertyVariables>
<org.onehippo.repository.test.keepserver>false</org.onehippo.repository.test.keepserver>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
......
/*
* Copyright 2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.jackrabbit.core.journal;
import org.apache.jackrabbit.core.util.db.ConnectionHelper;
public class JournalConnectionHelperAccessorImpl {
public static ConnectionHelper getConnectionHelper(final DatabaseJournal journal)
{
return journal.conHelper;
}
}
/*
* Copyright 2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed 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.jackrabbit.core.util.db;
import javax.sql.DataSource;
public class ConnectionHelperDataSourceAccessor {
private ConnectionHelperDataSourceAccessor(){
}
public static DataSource getDataSource(final ConnectionHelper connectionHelper) {
return connectionHelper.dataSource;
}
}
/*
* Copyright 2008-2016 Hippo B.V. (http://www.onehippo.com)
* Copyright 2008-2017 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -36,10 +36,18 @@ import javax.jcr.SimpleCredentials;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.core.cluster.ClusterNode;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.apache.jackrabbit.core.fs.FileSystem;
import org.apache.jackrabbit.core.fs.FileSystemException;
import org.apache.jackrabbit.core.journal.DatabaseJournal;
import org.apache.jackrabbit.core.journal.JournalConnectionHelperAccessorImpl;
import org.apache.jackrabbit.core.util.db.ConnectionHelper;
import org.hippoecm.repository.nodetypes.NodeTypesChangeTracker;
import org.onehippo.cms7.services.HippoServiceRegistry;
import org.onehippo.cms7.services.lock.LockManager;
import org.onehippo.cms7.services.lock.LockManagerUtils;
import org.onehippo.cms7.services.lock.LockResource;
import org.onehippo.repository.bootstrap.InitializationProcessor;
import org.onehippo.repository.bootstrap.PostStartupTask;
import org.hippoecm.repository.api.ReferenceWorkspace;
......@@ -49,7 +57,11 @@ import org.hippoecm.repository.impl.ReferenceWorkspaceImpl;
import org.hippoecm.repository.jackrabbit.RepositoryImpl;
import org.hippoecm.repository.security.HippoSecurityManager;
import org.hippoecm.repository.util.RepoUtils;
import org.onehippo.repository.bootstrap.util.BootstrapConstants;
import org.onehippo.repository.bootstrap.util.BootstrapUtils;
import org.onehippo.repository.lock.InternalLockManager;
import org.onehippo.repository.lock.db.DbLockManagerFactory;
import org.onehippo.repository.lock.memory.MemoryLockManager;
import org.onehippo.repository.modules.ModuleManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -78,6 +90,12 @@ public class LocalHippoRepository extends HippoRepositoryImpl {
/** Default config file */
public static final String DEFAULT_REPOSITORY_CONFIG = "repository.xml";
/** key to lock during repository initialization */
private static final String INIT_LOCK_KEY = BootstrapConstants.INIT_FOLDER_PATH;
/** wait interval for retrying to lock on {@link #INIT_LOCK_KEY} during repository initialization */
private static final long INIT_LOCK_ATTEMPT_INTERVAL = 500;
/** The advised threshold on the number of modified nodes to hold in transient session state */
public static int batchThreshold = 96;
......@@ -88,6 +106,8 @@ public class LocalHippoRepository extends HippoRepositoryImpl {
private String repoPath;
private String repoConfig;
protected InternalLockManager lockManager;
private ModuleManager moduleManager;
private NodeTypesChangeTracker nodeTypesChangeTracker;
......@@ -199,7 +219,7 @@ public class LocalHippoRepository extends HippoRepositoryImpl {
* @return InputStream to the repository config
* @throws RepositoryException
*/
private InputStream getRepositoryConfigAsStream() throws RepositoryException {
protected InputStream getRepositoryConfigAsStream() throws RepositoryException {
String configPath = repoConfig;
......@@ -237,14 +257,17 @@ public class LocalHippoRepository extends HippoRepositoryImpl {
}
}
private class LocalRepositoryImpl extends RepositoryImpl {
LocalRepositoryImpl(RepositoryConfig repConfig) throws RepositoryException {
protected class LocalRepositoryImpl extends RepositoryImpl {
protected LocalRepositoryImpl(RepositoryConfig repConfig) throws RepositoryException {
super(repConfig);
}
@Override
public Session getRootSession(String workspaceName) throws RepositoryException {
return super.getRootSession(workspaceName);
}
void enableVirtualLayer(boolean enabled) throws RepositoryException {
isStarted = enabled;
}
......@@ -252,7 +275,23 @@ public class LocalHippoRepository extends HippoRepositoryImpl {
protected FileSystem getFileSystem() {
return super.getFileSystem();
}
}
protected LocalRepositoryImpl createLocalRepository(final RepositoryConfig repConfig) throws RepositoryException {
return new LocalRepositoryImpl(repConfig);
}
protected void initializeLockManager() throws RepositoryException {
ClusterNode clusterNode = jackrabbitRepository.getClusterNode();
if (clusterNode != null && clusterNode.getJournal() instanceof DatabaseJournal) {
DatabaseJournal dbJournal = (DatabaseJournal) clusterNode.getJournal();
ConnectionHelper connectionHelper =
JournalConnectionHelperAccessorImpl.getConnectionHelper((DatabaseJournal) clusterNode.getJournal());
this.lockManager = DbLockManagerFactory.create(connectionHelper, dbJournal.getSchemaObjectPrefix(),
dbJournal.isSchemaCheckEnabled(), jackrabbitRepository.getDescriptor("jackrabbit.cluster.id"));
} else {
this.lockManager = new MemoryLockManager();
}
}
protected void initialize() throws RepositoryException {
......@@ -260,16 +299,17 @@