Merge branch 'stable-2.11'
* stable-2.11: Set version to 2.11.2 in dev-plugins.txt Release notes for Gerrit 2.11.2 Bind OnlineReindexer.Factory in LuceneIndexModule Add ssh command to activate the latest index Add ssh command to restart online indexer PluginAPI: Don't convert to String in RestApi.get() method Change-Id: I907e665b20568fce8563bf9e22a7a0ffc96fc847
This commit is contained in:
32
Documentation/cmd-index-activate.txt
Normal file
32
Documentation/cmd-index-activate.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
= gerrit index activate
|
||||||
|
|
||||||
|
== NAME
|
||||||
|
gerrit index activate - Activate the latest index version available
|
||||||
|
|
||||||
|
== SYNOPSIS
|
||||||
|
--
|
||||||
|
'ssh' -p @SSH_PORT@ @SSH_HOST@ 'gerrit index activate'
|
||||||
|
--
|
||||||
|
|
||||||
|
== DESCRIPTION
|
||||||
|
Gerrit supports online index schema upgrades. When starting Gerrit for the first
|
||||||
|
time after an upgrade that requires an index schema upgrade, the online indexer
|
||||||
|
will be started. If the schema upgrade is a success, the new index will be
|
||||||
|
activated and if it fails, a statement in the logs will be printed with the
|
||||||
|
number of successfully/failed indexed changes.
|
||||||
|
|
||||||
|
This command allows to activate the latest index even if there were some
|
||||||
|
failures.
|
||||||
|
|
||||||
|
== ACCESS
|
||||||
|
Caller must be a member of the privileged 'Administrators' group.
|
||||||
|
|
||||||
|
== SCRIPTING
|
||||||
|
This command is intended to be used in scripts.
|
||||||
|
|
||||||
|
GERRIT
|
||||||
|
------
|
||||||
|
Part of link:index.html[Gerrit Code Review]
|
||||||
|
|
||||||
|
SEARCHBOX
|
||||||
|
---------
|
33
Documentation/cmd-index-start.txt
Normal file
33
Documentation/cmd-index-start.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
= gerrit index start
|
||||||
|
|
||||||
|
== NAME
|
||||||
|
gerrit index start - Start the online indexer
|
||||||
|
|
||||||
|
== SYNOPSIS
|
||||||
|
--
|
||||||
|
'ssh' -p @SSH_PORT@ @SSH_HOST@ 'gerrit index start'
|
||||||
|
--
|
||||||
|
|
||||||
|
== DESCRIPTION
|
||||||
|
Gerrit supports online index schema upgrades. When starting Gerrit for the first
|
||||||
|
time after an upgrade that requires an index schema upgrade, the online indexer
|
||||||
|
will be started. If the schema upgrade is a success, the new index will be
|
||||||
|
activated and if it fails, a statement in the logs will be printed with the
|
||||||
|
number of successfully/failed indexed changes.
|
||||||
|
|
||||||
|
This command allows restarting the online indexer without having to restart
|
||||||
|
Gerrit. This command will not start the indexer if it is already running or if
|
||||||
|
the active index is the latest.
|
||||||
|
|
||||||
|
== ACCESS
|
||||||
|
Caller must be a member of the privileged 'Administrators' group.
|
||||||
|
|
||||||
|
== SCRIPTING
|
||||||
|
This command is intended to be used in scripts.
|
||||||
|
|
||||||
|
GERRIT
|
||||||
|
------
|
||||||
|
Part of link:index.html[Gerrit Code Review]
|
||||||
|
|
||||||
|
SEARCHBOX
|
||||||
|
---------
|
@@ -120,6 +120,12 @@ link:cmd-gc.html[gerrit gc]::
|
|||||||
link:cmd-gsql.html[gerrit gsql]::
|
link:cmd-gsql.html[gerrit gsql]::
|
||||||
Administrative interface to active database.
|
Administrative interface to active database.
|
||||||
|
|
||||||
|
link:cmd-index-index.html[gerrit index activate]::
|
||||||
|
Activate the latest index version available.
|
||||||
|
|
||||||
|
link:cmd-index-start.html[gerrit index start]::
|
||||||
|
Start the online indexer.
|
||||||
|
|
||||||
link:cmd-logging-ls-level.html[gerrit logging ls-level]::
|
link:cmd-logging-ls-level.html[gerrit logging ls-level]::
|
||||||
List loggers and their logging level.
|
List loggers and their logging level.
|
||||||
|
|
||||||
|
97
ReleaseNotes/ReleaseNotes-2.11.2.txt
Normal file
97
ReleaseNotes/ReleaseNotes-2.11.2.txt
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
Release notes for Gerrit 2.11.2
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Gerrit 2.11.2 is now available:
|
||||||
|
|
||||||
|
link:https://gerrit-releases.storage.googleapis.com/gerrit-2.11.2.war[
|
||||||
|
https://gerrit-releases.storage.googleapis.com/gerrit-2.11.2.war]
|
||||||
|
|
||||||
|
Gerrit 2.11.2 includes the bug fixes done with
|
||||||
|
link:ReleaseNotes-2.10.6.html[Gerrit 2.10.6]. These bug fixes are *not* listed
|
||||||
|
in these release notes.
|
||||||
|
|
||||||
|
There are no schema changes from link:ReleaseNotes-2.11.1.html[2.11.1].
|
||||||
|
|
||||||
|
New Features
|
||||||
|
------------
|
||||||
|
|
||||||
|
New SSH commands:
|
||||||
|
|
||||||
|
* link:https://gerrit-documentation.storage.googleapis.com/Documentation/2.11.2/cmd-index-start.html[
|
||||||
|
`index start`]
|
||||||
|
+
|
||||||
|
Allows to restart the online indexer without restarting the Gerrit server.
|
||||||
|
|
||||||
|
* link:https://gerrit-documentation.storage.googleapis.com/Documentation/2.11.2/cmd-index-activate.html[
|
||||||
|
`index activate`]
|
||||||
|
+
|
||||||
|
Allows to activate the latest index version even if the indexing encountered
|
||||||
|
problems.
|
||||||
|
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
* link:link:https://code.google.com/p/gerrit/issues/detail?id=3460[Issue 3460]:
|
||||||
|
Fix regression in the search box auto-suggestions.
|
||||||
|
+
|
||||||
|
A change introduced in version 2.11 caused the auto-suggestions to not work
|
||||||
|
any more.
|
||||||
|
|
||||||
|
* link:https://code.google.com/p/gerrit/issues/detail?id=3355[Issue 3355]:
|
||||||
|
Fix corruption of database when deleting draft change ref fails.
|
||||||
|
|
||||||
|
* link:https://code.google.com/p/gerrit/issues/detail?id=3426[Issue 3426]:
|
||||||
|
Fix regression in the `%base` option.
|
||||||
|
+
|
||||||
|
A change introduced in version 2.11 caused the `%base` option to not work
|
||||||
|
any more, meaning it was not possible to push a commit, which is already merged
|
||||||
|
into a branch, for review to another branch of the same project.
|
||||||
|
|
||||||
|
* link:https://bugs.eclipse.org/bugs/show_bug.cgi?id=468024[JGit bug 468024]:
|
||||||
|
Fix data loss if a pack is pushed to a JGit based server and gc runs
|
||||||
|
concurrently on the same repository.
|
||||||
|
|
||||||
|
* link:https://code.google.com/p/gerrit/issues/detail?id=3371[Issue 3371]:
|
||||||
|
Fix wrong date/time for commits in `refs/meta/config` branch.
|
||||||
|
+
|
||||||
|
When the `refs/meta/config` branch was modified using the PutConfig REST endpoint
|
||||||
|
(e.g. when changing the project configuration in the web UI) the commit date/time
|
||||||
|
was wrong. Instead of the actual date/time the date/time of the last Gerrit server
|
||||||
|
start was used.
|
||||||
|
|
||||||
|
* Fix NullPointerException in the 'related changes' REST API endpoint.
|
||||||
|
|
||||||
|
* Make sure `/a` is not in the project name for git-over-http requests.
|
||||||
|
+
|
||||||
|
The `/a` prefix is used to trigger authentication but was not removed from the
|
||||||
|
request. Therefore, it was included in the project name and hence the project
|
||||||
|
wasn't found when performing, for example `git fetch http://server/a/project`.
|
||||||
|
|
||||||
|
* Fix disabling of git ssh commands.
|
||||||
|
+
|
||||||
|
The ssh commands were available even when ssh commands were disabled.
|
||||||
|
|
||||||
|
* Fix native string handling in Plugin API.
|
||||||
|
+
|
||||||
|
The results of REST API calls were incorrectly being converted from NativeString
|
||||||
|
to String when called from Javascript.
|
||||||
|
|
||||||
|
* link:https://code.google.com/p/gerrit/issues/detail?id=3440[Issue 3440]:
|
||||||
|
Include prettify source files in the documentation.
|
||||||
|
+
|
||||||
|
The prettify source files were being loaded from `cdnjs.cloudflare.com`, which
|
||||||
|
may cause trouble if the Gerrit instance is behind a firewall on a machine not
|
||||||
|
allowed to access the Internet at large.
|
||||||
|
+
|
||||||
|
Now those files are bundled with the documentation.
|
||||||
|
|
||||||
|
* Print proper name for project indexer tasks in `show-queue` command.
|
||||||
|
|
||||||
|
* Print proper name for reindex after update tasks in `show-queue` command.
|
||||||
|
|
||||||
|
Updates
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Update JGit to 4.0.1.201506240215-r.
|
||||||
|
|
@@ -4,6 +4,7 @@ Gerrit Code Review - Release Notes
|
|||||||
[[2_11]]
|
[[2_11]]
|
||||||
Version 2.11.x
|
Version 2.11.x
|
||||||
--------------
|
--------------
|
||||||
|
* link:ReleaseNotes-2.11.2.html[2.11.2]
|
||||||
* link:ReleaseNotes-2.11.1.html[2.11.1]
|
* link:ReleaseNotes-2.11.1.html[2.11.1]
|
||||||
* link:ReleaseNotes-2.11.html[2.11]
|
* link:ReleaseNotes-2.11.html[2.11]
|
||||||
|
|
||||||
|
@@ -166,6 +166,14 @@ public class ActionContext extends JavaScriptObject {
|
|||||||
api.get(wrap(cb));
|
api.get(wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #get(RestApi, JavaScriptObject)} but without converting
|
||||||
|
* a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void getRaw(RestApi api, final JavaScriptObject cb) {
|
||||||
|
api.get(wrapRaw(cb));
|
||||||
|
}
|
||||||
|
|
||||||
static final void post(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
static final void post(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
||||||
if (NativeString.is(in)) {
|
if (NativeString.is(in)) {
|
||||||
post(api, ((NativeString) in).asString(), cb);
|
post(api, ((NativeString) in).asString(), cb);
|
||||||
@@ -174,14 +182,42 @@ public class ActionContext extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #post(RestApi, JavaScriptObject, JavaScriptObject)} but
|
||||||
|
* without converting a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void postRaw(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
||||||
|
if (NativeString.is(in)) {
|
||||||
|
postRaw(api, ((NativeString) in).asString(), cb);
|
||||||
|
} else {
|
||||||
|
api.post(in, wrapRaw(cb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final void post(RestApi api, String in, JavaScriptObject cb) {
|
static final void post(RestApi api, String in, JavaScriptObject cb) {
|
||||||
api.post(in, wrap(cb));
|
api.post(in, wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #post(RestApi, String, JavaScriptObject)} but without
|
||||||
|
* converting a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void postRaw(RestApi api, String in, JavaScriptObject cb) {
|
||||||
|
api.post(in, wrapRaw(cb));
|
||||||
|
}
|
||||||
|
|
||||||
static final void put(RestApi api, JavaScriptObject cb) {
|
static final void put(RestApi api, JavaScriptObject cb) {
|
||||||
api.put(wrap(cb));
|
api.put(wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #put(RestApi, JavaScriptObject)} but without converting
|
||||||
|
* a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void putRaw(RestApi api, JavaScriptObject cb) {
|
||||||
|
api.put(wrapRaw(cb));
|
||||||
|
}
|
||||||
|
|
||||||
static final void put(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
static final void put(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
||||||
if (NativeString.is(in)) {
|
if (NativeString.is(in)) {
|
||||||
put(api, ((NativeString) in).asString(), cb);
|
put(api, ((NativeString) in).asString(), cb);
|
||||||
@@ -190,14 +226,42 @@ public class ActionContext extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #put(RestApi, JavaScriptObject, JavaScriptObject)} but
|
||||||
|
* without converting a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void putRaw(RestApi api, JavaScriptObject in, JavaScriptObject cb) {
|
||||||
|
if (NativeString.is(in)) {
|
||||||
|
putRaw(api, ((NativeString) in).asString(), cb);
|
||||||
|
} else {
|
||||||
|
api.put(in, wrapRaw(cb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final void put(RestApi api, String in, JavaScriptObject cb) {
|
static final void put(RestApi api, String in, JavaScriptObject cb) {
|
||||||
api.put(in, wrap(cb));
|
api.put(in, wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #put(RestApi, String, JavaScriptObject)} but without
|
||||||
|
* converting a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void putRaw(RestApi api, String in, JavaScriptObject cb) {
|
||||||
|
api.put(in, wrapRaw(cb));
|
||||||
|
}
|
||||||
|
|
||||||
static final void delete(RestApi api, JavaScriptObject cb) {
|
static final void delete(RestApi api, JavaScriptObject cb) {
|
||||||
api.delete(wrap(cb));
|
api.delete(wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The same as {@link #delete(RestApi, JavaScriptObject)} but without
|
||||||
|
* converting a {@link NativeString} result to String.
|
||||||
|
*/
|
||||||
|
static final void deleteRaw(RestApi api, JavaScriptObject cb) {
|
||||||
|
api.delete(wrapRaw(cb));
|
||||||
|
}
|
||||||
|
|
||||||
private static GerritCallback<JavaScriptObject> wrap(final JavaScriptObject cb) {
|
private static GerritCallback<JavaScriptObject> wrap(final JavaScriptObject cb) {
|
||||||
return new GerritCallback<JavaScriptObject>() {
|
return new GerritCallback<JavaScriptObject>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -211,4 +275,13 @@ public class ActionContext extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static GerritCallback<JavaScriptObject> wrapRaw(final JavaScriptObject cb) {
|
||||||
|
return new GerritCallback<JavaScriptObject>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(JavaScriptObject result) {
|
||||||
|
ApiGlue.invoke(cb, result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -102,6 +102,12 @@ public class ApiGlue {
|
|||||||
Lcom/google/gwt/core/client/JavaScriptObject;)
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
(this._api(u), b);
|
(this._api(u), b);
|
||||||
},
|
},
|
||||||
|
get_raw: function(u,b) {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::getRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), b);
|
||||||
|
},
|
||||||
post: function(u,i,b) {
|
post: function(u,i,b) {
|
||||||
if (typeof i == 'string') {
|
if (typeof i == 'string') {
|
||||||
@com.google.gerrit.client.api.ActionContext::post(
|
@com.google.gerrit.client.api.ActionContext::post(
|
||||||
@@ -117,6 +123,21 @@ public class ApiGlue {
|
|||||||
(this._api(u), i, b);
|
(this._api(u), i, b);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
post_raw: function(u,i,b) {
|
||||||
|
if (typeof i == 'string') {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::postRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Ljava/lang/String;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), i, b);
|
||||||
|
} else {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::postRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), i, b);
|
||||||
|
}
|
||||||
|
},
|
||||||
put: function(u,i,b) {
|
put: function(u,i,b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
if (typeof i == 'string') {
|
if (typeof i == 'string') {
|
||||||
@@ -139,6 +160,28 @@ public class ApiGlue {
|
|||||||
(this._api(u), i);
|
(this._api(u), i);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
put_raw: function(u,i,b) {
|
||||||
|
if (b) {
|
||||||
|
if (typeof i == 'string') {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::putRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Ljava/lang/String;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), i, b);
|
||||||
|
} else {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::putRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), i, b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::putRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), i);
|
||||||
|
}
|
||||||
|
},
|
||||||
'delete': function(u,b) {
|
'delete': function(u,b) {
|
||||||
@com.google.gerrit.client.api.ActionContext::delete(
|
@com.google.gerrit.client.api.ActionContext::delete(
|
||||||
Lcom/google/gerrit/client/rpc/RestApi;
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
@@ -151,6 +194,12 @@ public class ApiGlue {
|
|||||||
Lcom/google/gwt/core/client/JavaScriptObject;)
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
(this._api(u), b);
|
(this._api(u), b);
|
||||||
},
|
},
|
||||||
|
del_raw: function(u,b) {
|
||||||
|
@com.google.gerrit.client.api.ActionContext::deleteRaw(
|
||||||
|
Lcom/google/gerrit/client/rpc/RestApi;
|
||||||
|
Lcom/google/gwt/core/client/JavaScriptObject;)
|
||||||
|
(this._api(u), b);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}-*/;
|
}-*/;
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@ public class LuceneIndexModule extends LifecycleModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
factory(LuceneChangeIndex.Factory.class);
|
factory(LuceneChangeIndex.Factory.class);
|
||||||
|
factory(OnlineReindexer.Factory.class);
|
||||||
install(new IndexModule(threads));
|
install(new IndexModule(threads));
|
||||||
if (singleVersion == null && base == null) {
|
if (singleVersion == null && base == null) {
|
||||||
install(new MultiVersionModule());
|
install(new MultiVersionModule());
|
||||||
@@ -65,7 +66,6 @@ public class LuceneIndexModule extends LifecycleModule {
|
|||||||
private static class MultiVersionModule extends LifecycleModule {
|
private static class MultiVersionModule extends LifecycleModule {
|
||||||
@Override
|
@Override
|
||||||
public void configure() {
|
public void configure() {
|
||||||
factory(OnlineReindexer.Factory.class);
|
|
||||||
listener().to(LuceneVersionManager.class);
|
listener().to(LuceneVersionManager.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ import java.util.List;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class LuceneVersionManager implements LifecycleListener {
|
public class LuceneVersionManager implements LifecycleListener {
|
||||||
private static final Logger log = LoggerFactory
|
private static final Logger log = LoggerFactory
|
||||||
.getLogger(LuceneVersionManager.class);
|
.getLogger(LuceneVersionManager.class);
|
||||||
|
|
||||||
@@ -95,6 +95,7 @@ class LuceneVersionManager implements LifecycleListener {
|
|||||||
private final IndexCollection indexes;
|
private final IndexCollection indexes;
|
||||||
private final OnlineReindexer.Factory reindexerFactory;
|
private final OnlineReindexer.Factory reindexerFactory;
|
||||||
private final boolean onlineUpgrade;
|
private final boolean onlineUpgrade;
|
||||||
|
private OnlineReindexer reindexer;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
LuceneVersionManager(
|
LuceneVersionManager(
|
||||||
@@ -165,7 +166,53 @@ class LuceneVersionManager implements LifecycleListener {
|
|||||||
|
|
||||||
int latest = write.get(0).version;
|
int latest = write.get(0).version;
|
||||||
if (onlineUpgrade && latest != search.version) {
|
if (onlineUpgrade && latest != search.version) {
|
||||||
reindexerFactory.create(latest).start();
|
reindexer = reindexerFactory.create(latest);
|
||||||
|
reindexer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the online reindexer if the current index is not already the latest.
|
||||||
|
*
|
||||||
|
* @return true if started, otherwise false.
|
||||||
|
* @throws ReindexerAlreadyRunningException
|
||||||
|
*/
|
||||||
|
public synchronized boolean startReindexer()
|
||||||
|
throws ReindexerAlreadyRunningException {
|
||||||
|
validateReindexerNotRunning();
|
||||||
|
if (!isCurrentIndexVersionLatest()) {
|
||||||
|
reindexer.start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the latest index if the current index is not already the latest.
|
||||||
|
*
|
||||||
|
* @return true if index was activate, otherwise false.
|
||||||
|
* @throws ReindexerAlreadyRunningException
|
||||||
|
*/
|
||||||
|
public synchronized boolean activateLatestIndex()
|
||||||
|
throws ReindexerAlreadyRunningException {
|
||||||
|
validateReindexerNotRunning();
|
||||||
|
if (!isCurrentIndexVersionLatest()) {
|
||||||
|
reindexer.activateIndex();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCurrentIndexVersionLatest() {
|
||||||
|
return reindexer == null
|
||||||
|
|| reindexer.getVersion() == indexes.getSearchIndex().getSchema()
|
||||||
|
.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateReindexerNotRunning()
|
||||||
|
throws ReindexerAlreadyRunningException {
|
||||||
|
if (reindexer != null && reindexer.isRunning()) {
|
||||||
|
throw new ReindexerAlreadyRunningException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class OnlineReindexer {
|
public class OnlineReindexer {
|
||||||
private static final Logger log = LoggerFactory
|
private static final Logger log = LoggerFactory
|
||||||
@@ -42,6 +43,8 @@ public class OnlineReindexer {
|
|||||||
private final SiteIndexer batchIndexer;
|
private final SiteIndexer batchIndexer;
|
||||||
private final ProjectCache projectCache;
|
private final ProjectCache projectCache;
|
||||||
private final int version;
|
private final int version;
|
||||||
|
private ChangeIndex index;
|
||||||
|
private final AtomicBoolean running = new AtomicBoolean();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OnlineReindexer(
|
OnlineReindexer(
|
||||||
@@ -56,15 +59,29 @@ public class OnlineReindexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
Thread t = new Thread() {
|
if (running.compareAndSet(false, true)) {
|
||||||
@Override
|
Thread t = new Thread() {
|
||||||
public void run() {
|
@Override
|
||||||
reindex();
|
public void run() {
|
||||||
}
|
try {
|
||||||
};
|
reindex();
|
||||||
t.setName(String.format("Reindex v%d-v%d",
|
} finally {
|
||||||
version(indexes.getSearchIndex()), version));
|
running.set(false);
|
||||||
t.start();
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.setName(String.format("Reindex v%d-v%d",
|
||||||
|
version(indexes.getSearchIndex()), version));
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return running.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int version(ChangeIndex i) {
|
private static int version(ChangeIndex i) {
|
||||||
@@ -72,7 +89,7 @@ public class OnlineReindexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void reindex() {
|
private void reindex() {
|
||||||
ChangeIndex index = checkNotNull(indexes.getWriteIndex(version),
|
index = checkNotNull(indexes.getWriteIndex(version),
|
||||||
"not an active write schema version: %s", version);
|
"not an active write schema version: %s", version);
|
||||||
log.info("Starting online reindex from schema version {} to {}",
|
log.info("Starting online reindex from schema version {} to {}",
|
||||||
version(indexes.getSearchIndex()), version(index));
|
version(indexes.getSearchIndex()), version(index));
|
||||||
@@ -84,9 +101,13 @@ public class OnlineReindexer {
|
|||||||
version(index), result.doneCount(), result.failedCount());
|
version(index), result.doneCount(), result.failedCount());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
log.info("Reindex to version {} complete", version(index));
|
||||||
|
activateIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void activateIndex() {
|
||||||
indexes.setSearchIndex(index);
|
indexes.setSearchIndex(index);
|
||||||
log.info("Reindex complete, using schema version {}", version(index));
|
log.info("Using schema version {}", version(index));
|
||||||
try {
|
try {
|
||||||
index.markReady(true);
|
index.markReady(true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2015 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.lucene;
|
||||||
|
|
||||||
|
public class ReindexerAlreadyRunningException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ReindexerAlreadyRunningException() {
|
||||||
|
super("Reindexer is already running.");
|
||||||
|
}
|
||||||
|
}
|
@@ -110,7 +110,7 @@ public class RestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static native void get(String p, JavaScriptObject r)
|
private static native void get(String p, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.get(p, r) }-*/;
|
/*-{ $wnd.Gerrit.get_raw(p, r) }-*/;
|
||||||
|
|
||||||
public <T extends JavaScriptObject>
|
public <T extends JavaScriptObject>
|
||||||
void put(AsyncCallback<T> cb) {
|
void put(AsyncCallback<T> cb) {
|
||||||
@@ -118,7 +118,7 @@ public class RestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static native void put(String p, JavaScriptObject r)
|
private static native void put(String p, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.put(p, r) }-*/;
|
/*-{ $wnd.Gerrit.put_raw(p, r) }-*/;
|
||||||
|
|
||||||
public <T extends JavaScriptObject>
|
public <T extends JavaScriptObject>
|
||||||
void put(String content, AsyncCallback<T> cb) {
|
void put(String content, AsyncCallback<T> cb) {
|
||||||
@@ -127,7 +127,7 @@ public class RestApi {
|
|||||||
|
|
||||||
private static native
|
private static native
|
||||||
void put(String p, String c, JavaScriptObject r)
|
void put(String p, String c, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.put(p, c, r) }-*/;
|
/*-{ $wnd.Gerrit.put_raw(p, c, r) }-*/;
|
||||||
|
|
||||||
public <T extends JavaScriptObject>
|
public <T extends JavaScriptObject>
|
||||||
void put(JavaScriptObject content, AsyncCallback<T> cb) {
|
void put(JavaScriptObject content, AsyncCallback<T> cb) {
|
||||||
@@ -136,7 +136,7 @@ public class RestApi {
|
|||||||
|
|
||||||
private static native
|
private static native
|
||||||
void put(String p, JavaScriptObject c, JavaScriptObject r)
|
void put(String p, JavaScriptObject c, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.put(p, c, r) }-*/;
|
/*-{ $wnd.Gerrit.put_raw(p, c, r) }-*/;
|
||||||
|
|
||||||
public <T extends JavaScriptObject>
|
public <T extends JavaScriptObject>
|
||||||
void post(String content, AsyncCallback<T> cb) {
|
void post(String content, AsyncCallback<T> cb) {
|
||||||
@@ -145,7 +145,7 @@ public class RestApi {
|
|||||||
|
|
||||||
private static native
|
private static native
|
||||||
void post(String p, String c, JavaScriptObject r)
|
void post(String p, String c, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.post(p, c, r) }-*/;
|
/*-{ $wnd.Gerrit.post_raw(p, c, r) }-*/;
|
||||||
|
|
||||||
public <T extends JavaScriptObject>
|
public <T extends JavaScriptObject>
|
||||||
void post(JavaScriptObject content, AsyncCallback<T> cb) {
|
void post(JavaScriptObject content, AsyncCallback<T> cb) {
|
||||||
@@ -154,14 +154,14 @@ public class RestApi {
|
|||||||
|
|
||||||
private static native
|
private static native
|
||||||
void post(String p, JavaScriptObject c, JavaScriptObject r)
|
void post(String p, JavaScriptObject c, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.post(p, c, r) }-*/;
|
/*-{ $wnd.Gerrit.post_raw(p, c, r) }-*/;
|
||||||
|
|
||||||
public void delete(AsyncCallback<NoContent> cb) {
|
public void delete(AsyncCallback<NoContent> cb) {
|
||||||
delete(path(), wrap(cb));
|
delete(path(), wrap(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void delete(String p, JavaScriptObject r)
|
private static native void delete(String p, JavaScriptObject r)
|
||||||
/*-{ $wnd.Gerrit.del(p, r) }-*/;
|
/*-{ $wnd.Gerrit.del_raw(p, r) }-*/;
|
||||||
|
|
||||||
private static native <T extends JavaScriptObject>
|
private static native <T extends JavaScriptObject>
|
||||||
JavaScriptObject wrap(AsyncCallback<T> b) /*-{
|
JavaScriptObject wrap(AsyncCallback<T> b) /*-{
|
||||||
|
@@ -8,6 +8,7 @@ java_library(
|
|||||||
'//gerrit-cache-h2:cache-h2',
|
'//gerrit-cache-h2:cache-h2',
|
||||||
'//gerrit-common:annotations',
|
'//gerrit-common:annotations',
|
||||||
'//gerrit-common:server',
|
'//gerrit-common:server',
|
||||||
|
'//gerrit-lucene:lucene',
|
||||||
'//gerrit-patch-jgit:server',
|
'//gerrit-patch-jgit:server',
|
||||||
'//gerrit-reviewdb:server',
|
'//gerrit-reviewdb:server',
|
||||||
'//gerrit-server:server',
|
'//gerrit-server:server',
|
||||||
|
@@ -36,6 +36,7 @@ public class DefaultCommandModule extends CommandModule {
|
|||||||
protected void configure() {
|
protected void configure() {
|
||||||
final CommandName git = Commands.named("git");
|
final CommandName git = Commands.named("git");
|
||||||
final CommandName gerrit = Commands.named("gerrit");
|
final CommandName gerrit = Commands.named("gerrit");
|
||||||
|
CommandName index = Commands.named(gerrit, "index");
|
||||||
final CommandName logging = Commands.named(gerrit, "logging");
|
final CommandName logging = Commands.named(gerrit, "logging");
|
||||||
final CommandName plugin = Commands.named(gerrit, "plugin");
|
final CommandName plugin = Commands.named(gerrit, "plugin");
|
||||||
final CommandName testSubmit = Commands.named(gerrit, "test-submit");
|
final CommandName testSubmit = Commands.named(gerrit, "test-submit");
|
||||||
@@ -56,8 +57,12 @@ public class DefaultCommandModule extends CommandModule {
|
|||||||
command(gerrit, StreamEvents.class);
|
command(gerrit, StreamEvents.class);
|
||||||
command(gerrit, VersionCommand.class);
|
command(gerrit, VersionCommand.class);
|
||||||
command(gerrit, GarbageCollectionCommand.class);
|
command(gerrit, GarbageCollectionCommand.class);
|
||||||
command(gerrit, "plugin").toProvider(new DispatchCommandProvider(plugin));
|
|
||||||
|
|
||||||
|
command(index).toProvider(new DispatchCommandProvider(index));
|
||||||
|
command(index, IndexActivateCommand.class);
|
||||||
|
command(index, IndexStartCommand.class);
|
||||||
|
|
||||||
|
command(gerrit, "plugin").toProvider(new DispatchCommandProvider(plugin));
|
||||||
command(plugin, PluginLsCommand.class);
|
command(plugin, PluginLsCommand.class);
|
||||||
command(plugin, PluginEnableCommand.class);
|
command(plugin, PluginEnableCommand.class);
|
||||||
command(plugin, PluginInstallCommand.class);
|
command(plugin, PluginInstallCommand.class);
|
||||||
|
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (C) 2015 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.sshd.commands;
|
||||||
|
|
||||||
|
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER;
|
||||||
|
|
||||||
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
|
import com.google.gerrit.lucene.LuceneVersionManager;
|
||||||
|
import com.google.gerrit.lucene.ReindexerAlreadyRunningException;
|
||||||
|
import com.google.gerrit.sshd.CommandMetaData;
|
||||||
|
import com.google.gerrit.sshd.SshCommand;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
|
||||||
|
@CommandMetaData(name = "activate",
|
||||||
|
description = "Activate the latest index version available",
|
||||||
|
runsAt = MASTER)
|
||||||
|
public class IndexActivateCommand extends SshCommand {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private LuceneVersionManager luceneVersionManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void run() throws UnloggedFailure {
|
||||||
|
try {
|
||||||
|
if (luceneVersionManager.activateLatestIndex()) {
|
||||||
|
stdout.println("Activated latest index version");
|
||||||
|
} else {
|
||||||
|
stdout.println("Not activating index, already using latest version");
|
||||||
|
}
|
||||||
|
} catch (ReindexerAlreadyRunningException e) {
|
||||||
|
throw new UnloggedFailure("Failed to activate latest index: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (C) 2015 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.sshd.commands;
|
||||||
|
|
||||||
|
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER;
|
||||||
|
|
||||||
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
|
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||||
|
import com.google.gerrit.lucene.LuceneVersionManager;
|
||||||
|
import com.google.gerrit.lucene.ReindexerAlreadyRunningException;
|
||||||
|
import com.google.gerrit.sshd.CommandMetaData;
|
||||||
|
import com.google.gerrit.sshd.SshCommand;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
|
||||||
|
@CommandMetaData(name = "start", description = "Start the online reindexer",
|
||||||
|
runsAt = MASTER)
|
||||||
|
public class IndexStartCommand extends SshCommand {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private LuceneVersionManager luceneVersionManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void run() throws UnloggedFailure {
|
||||||
|
try {
|
||||||
|
if (luceneVersionManager.startReindexer()) {
|
||||||
|
stdout.println("Reindexer started");
|
||||||
|
} else {
|
||||||
|
stdout.println("Nothing to reindex, index is already the latest version");
|
||||||
|
}
|
||||||
|
} catch (ReindexerAlreadyRunningException e) {
|
||||||
|
throw new UnloggedFailure("Failed to start reindexer: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user