diff --git a/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/DefaultCacheFactory.java b/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/DefaultCacheFactory.java index 5bee010173..a8287aea0f 100644 --- a/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/DefaultCacheFactory.java +++ b/gerrit-cache-h2/src/main/java/com/google/gerrit/server/cache/h2/DefaultCacheFactory.java @@ -23,6 +23,7 @@ import com.google.common.cache.Weigher; import com.google.gerrit.extensions.config.FactoryModule; import com.google.gerrit.lifecycle.LifecycleModule; import com.google.gerrit.server.cache.CacheBinding; +import com.google.gerrit.server.cache.CacheImpl; import com.google.gerrit.server.cache.ForwardingRemovalListener; import com.google.gerrit.server.cache.MemoryCacheFactory; import com.google.gerrit.server.cache.PersistentCacheFactory; @@ -33,6 +34,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jgit.lib.Config; public class DefaultCacheFactory implements MemoryCacheFactory { + @CacheImpl(type = CacheImpl.Type.MEMORY) public static class MemoryCacheModule extends FactoryModule { @Override protected void configure() { @@ -41,6 +43,7 @@ public class DefaultCacheFactory implements MemoryCacheFactory { } } + @CacheImpl(type = CacheImpl.Type.PERSISTENT) public static class PersistentCacheModule extends LifecycleModule { @Override protected void configure() { diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java index db150a1fcb..b693da95bd 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java @@ -50,6 +50,7 @@ import com.google.gerrit.pgm.util.SiteProgram; import com.google.gerrit.server.LibModuleLoader; import com.google.gerrit.server.StartupChecks; import com.google.gerrit.server.account.InternalAccountDirectory; +import com.google.gerrit.server.cache.CacheOverrides; import com.google.gerrit.server.cache.h2.DefaultCacheFactory; import com.google.gerrit.server.change.ChangeCleanupRunner; import com.google.gerrit.server.config.AuthConfig; @@ -438,8 +439,8 @@ public class Daemon extends SiteProgram { if (!slave) { modules.add(new ChangeCleanupRunner.Module()); } - modules.addAll(LibModuleLoader.loadModules(cfgInjector)); - return cfgInjector.createChildInjector(modules); + return cfgInjector.createChildInjector( + CacheOverrides.override(modules, LibModuleLoader.loadModules(cfgInjector))); } private Module createIndexModule() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheImpl.java new file mode 100644 index 0000000000..f06f8d584f --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheImpl.java @@ -0,0 +1,34 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// 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 com.google.gerrit.server.cache; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(TYPE) +@Inherited +public @interface CacheImpl { + enum Type { + MEMORY, + PERSISTENT + } + + Type type(); +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheOverrides.java b/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheOverrides.java new file mode 100644 index 0000000000..9008f7b665 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/cache/CacheOverrides.java @@ -0,0 +1,65 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// 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 com.google.gerrit.server.cache; + +import com.google.inject.Module; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class CacheOverrides { + public static List override(List modules, List overrideCandidates) { + if (overrideCandidates == null || overrideCandidates.isEmpty()) { + return modules; + } + + // group candidates by annotation existence + Map> grouped = + overrideCandidates + .stream() + .collect( + Collectors.groupingBy(m -> m.getClass().getAnnotation(CacheImpl.class) != null)); + + // add all non annotated libs to modules list + List libs = grouped.get(Boolean.FALSE); + if (libs != null) { + modules.addAll(libs); + } + + List overrides = grouped.get(Boolean.TRUE); + if (overrides == null) { + return modules; + } + + // swipe cache implementation with alternative provided in lib + return modules + .stream() + .map( + m -> { + CacheImpl a = m.getClass().getAnnotation(CacheImpl.class); + if (a == null) { + return m; + } + return overrides + .stream() + .filter(o -> o.getClass().getAnnotation(CacheImpl.class).type() == a.type()) + .findFirst() + .orElse(m); + }) + .collect(Collectors.toList()); + } + + private CacheOverrides() {} +} diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java index 6b3573cb0f..cf44963da6 100644 --- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java +++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java @@ -34,6 +34,7 @@ import com.google.gerrit.pgm.util.LogFileCompressor; import com.google.gerrit.server.LibModuleLoader; import com.google.gerrit.server.StartupChecks; import com.google.gerrit.server.account.InternalAccountDirectory; +import com.google.gerrit.server.cache.CacheOverrides; import com.google.gerrit.server.cache.h2.DefaultCacheFactory; import com.google.gerrit.server.change.ChangeCleanupRunner; import com.google.gerrit.server.config.AuthConfig; @@ -364,8 +365,8 @@ public class WebAppInitializer extends GuiceServletContextListener implements Fi }); modules.add(new GarbageCollectionModule()); modules.add(new ChangeCleanupRunner.Module()); - modules.addAll(LibModuleLoader.loadModules(cfgInjector)); - return cfgInjector.createChildInjector(modules); + return cfgInjector.createChildInjector( + CacheOverrides.override(modules, LibModuleLoader.loadModules(cfgInjector))); } private Module createIndexModule() {