Add support for SAP HANA

SAP HANA [1] is now supported as a database.

[1] http://help.sap.com/hana_appliance/

Depends-On: Ib733610cb826d17d72defd71a9e2c5f0fc7ce154
Change-Id: I4c46ba18f95177c832472317fa6c2cdad19749ee
This commit is contained in:
Adrian Görler
2016-01-05 13:32:47 +01:00
committed by Matthias Sohn
parent 2c98da8571
commit 0eda471cf2
9 changed files with 202 additions and 0 deletions

View File

@@ -206,6 +206,51 @@ Sample database section in $site_path/etc/secure.config:
password = secret_pasword
----
[[createdb_hana]]
=== SAP HANA
SAP HANA is a supported database for running Gerrit Code Review. However it is
recommended only for environments where you intend to run Gerrit on an existing
HANA installation to reduce administrative overhead.
In the HANA studio or the SAP HANA Web-based Development Workbench create a user
'GERRIT2' with the role 'RESTRICTED_USER_JDBC_ACCESS' and a password
<secret password>. This will also create an associated schema on the database.
As this user would be required to change the password upon first login you might
want to to disable the password lifetime check by executing
'ALTER USER GERRIT2 DISABLE PASSWORD LIFETIME'.
To run Gerrit on HANA, you need to obtain the HANA JDBC driver. It can be found
as described
link:http://help.sap.com/saphelp_hanaplatform/helpdata/en/ff/15928cf5594d78b841fbbe649f04b4/frameset.htm[here].
It needs to be stored in the 'lib' folder of the review site.
In the following sample database section it is assumed that HANA is running on
the host 'hana.host' with the instance number 00 where a schema/user GERRIT2
was created:
In $site_path/etc/gerrit.config:
----
[database]
type = hana
instance = 00
hostname = hana.host
username = GERRIT2
----
In $site_path/etc/secure.config:
----
[database]
password = <secret password>
----
Visit SAP HANA's link:http://help.sap.com/hana_appliance/[documentation] for
further information regarding using SAP HANA.
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@@ -45,5 +45,7 @@ public class DatabaseConfigModule extends AbstractModule {
Names.named("postgresql")).to(PostgreSQLInitializer.class);
bind(DatabaseConfigInitializer.class).annotatedWith(
Names.named("maxdb")).to(MaxDbInitializer.class);
bind(DatabaseConfigInitializer.class).annotatedWith(
Names.named("hana")).to(HANAInitializer.class);
}
}

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2016 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.pgm.init;
import static com.google.gerrit.pgm.init.api.InitUtil.username;
import com.google.common.primitives.Ints;
import com.google.gerrit.pgm.init.api.InitUtil;
import com.google.gerrit.pgm.init.api.Section;
public class HANAInitializer implements DatabaseConfigInitializer {
@Override
public void initConfig(Section databaseSection) {
final String defInstanceNumber = "00";
databaseSection.string("Server hostname", "hostname", "localhost");
databaseSection.string("Instance number", "instance", defInstanceNumber,
false);
String instance = databaseSection.get("instance");
Integer instanceNumber = Ints.tryParse(instance);
if (instanceNumber == null || instanceNumber < 0 || instanceNumber > 99) {
instanceIsInvalid();
}
databaseSection.string("Database username", "username", username());
databaseSection.password("username", "password");
}
private void instanceIsInvalid() {
throw InitUtil.die("database.instance must be in the range of 00 to 99");
}
}

View File

@@ -86,6 +86,8 @@ class InitDatabase implements InitStep {
libraries.oracleDriver.downloadRequired();
} else if (dci instanceof DB2Initializer) {
libraries.db2Driver.downloadRequired();
} else if (dci instanceof HANAInitializer) {
libraries.hanaDriver.downloadRequired();
}
dci.initConfig(database);

View File

@@ -44,6 +44,7 @@ class Libraries {
/* final */LibraryDownloader bouncyCastleSSL;
/* final */LibraryDownloader db2Driver;
/* final */LibraryDownloader db2DriverLicense;
/* final */LibraryDownloader hanaDriver;
/* final */LibraryDownloader mysqlDriver;
/* final */LibraryDownloader oracleDriver;

View File

@@ -61,3 +61,8 @@
name = DB2 Type 4 JDBC driver license (10.5)
url = file:///opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar
remove = db2jcc_license_cu.jar
[library "hanaDriver"]
name = HANA JDBC driver
url = file:///usr/sap/hdbclient/ngdbc.jar
remove = ngdbc.jar

View File

@@ -35,5 +35,6 @@ public class DataSourceModule extends AbstractModule {
*/
bind(DataSourceType.class).annotatedWith(Names.named("maxdb")).to(MaxDb.class);
bind(DataSourceType.class).annotatedWith(Names.named("sap db")).to(MaxDb.class);
bind(DataSourceType.class).annotatedWith(Names.named("hana")).to(HANA.class);
}
}

View File

@@ -0,0 +1,55 @@
// Copyright (C) 2016 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.schema;
import static com.google.gerrit.server.schema.JdbcUtil.hostname;
import static com.google.gerrit.server.schema.JdbcUtil.port;
import com.google.gerrit.server.config.ConfigSection;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
class HANA extends BaseDataSourceType {
private Config cfg;
@Inject
public HANA(@GerritServerConfig final Config cfg) {
super("com.sap.db.jdbc.Driver");
this.cfg = cfg;
}
@Override
public String getUrl() {
final StringBuilder b = new StringBuilder();
final ConfigSection dbs = new ConfigSection(cfg, "database");
b.append("jdbc:sap://");
b.append(hostname(dbs.required("hostname")));
int instance = Integer.parseInt(dbs.required("instance"));
String port = "3" + String.format("%02d", instance) + "15";
b.append(port(port));
return b.toString();
}
@Override
public ScriptRunner getIndexScript() throws IOException {
// HANA uses column tables and should not require additional indices
return ScriptRunner.NOOP;
}
}

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2016 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
package com.google.gerrit.server.schema;
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.CoreMatchers.sameInstance;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
public class HANATest {
private HANA hana;
private Config config;
@Before
public void setup() {
config = new Config();
config.setString("database", null, "hostname", "my.host");
hana = new HANA(config);
}
@Test
public void testGetUrl() throws Exception {
config.setString("database", null, "instance", "3");
assertThat(hana.getUrl()).isEqualTo("jdbc:sap://my.host:30315");
config.setString("database", null, "instance", "77");
assertThat(hana.getUrl()).isEqualTo("jdbc:sap://my.host:37715");
}
@Test
public void testGetIndexScript() throws Exception {
assertThat(hana.getIndexScript()).isEqualTo(sameInstance(ScriptRunner.NOOP));
}
}