Skip to content

Commit 5961ac2

Browse files
authored
KNOX-3253: Add advisory lock to the postgres table creation to avoid catalog race condition when multiple Knox instance start up simultaneously (#1157)
1 parent 5d2b153 commit 5961ac2

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed

gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,4 @@ void failedToDiscoverClusterServices(String clusterName, String topologyName,
825825

826826
@Message(level = MessageLevel.ERROR, text = "LDAP service not found or not properly registered")
827827
void ldapServiceNotFound();
828-
829-
@Message( level = MessageLevel.WARN, text = "Postgres type already exists exception caught. Tables already exist skipping creation." )
830-
void typeAlreadyExistsCaught();
831828
}

gateway-server/src/main/java/org/apache/knox/gateway/database/AbstractDataSourceFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public abstract class AbstractDataSourceFactory {
3232
public static final String ORACLE_TOKEN_METADATA_TABLE_CREATE_SQL_FILE_NAME = "createKnoxTokenMetadataDatabaseTableOracle.sql";
3333
public static final String DERBY_TOKENS_TABLE_CREATE_SQL_FILE_NAME = "createKnoxTokenDatabaseTableDerby.sql";
3434
public static final String DERBY_TOKEN_METADATA_TABLE_CREATE_SQL_FILE_NAME = "createKnoxTokenMetadataDatabaseTableDerby.sql";
35+
public static final String POSTGRES_TOKENS_TABLE_CREATE_SQL_FILE_NAME = "createKnoxTokenDatabaseTablePostgres.sql";
36+
public static final String POSTGRES_TOKEN_METADATA_TABLE_CREATE_SQL_FILE_NAME = "createKnoxTokenMetadataDatabaseTablePostgres.sql";
3537

3638
public static final String KNOX_PROVIDERS_TABLE_CREATE_SQL_FILE_NAME = "createKnoxProvidersTable.sql";
3739
public static final String KNOX_DESCRIPTORS_TABLE_CREATE_SQL_FILE_NAME = "createKnoxDescriptorsTable.sql";

gateway-server/src/main/java/org/apache/knox/gateway/database/DatabaseType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
public enum DatabaseType {
2121
POSTGRESQL("postgresql",
22-
AbstractDataSourceFactory.TOKENS_TABLE_CREATE_SQL_FILE_NAME,
23-
AbstractDataSourceFactory.TOKEN_METADATA_TABLE_CREATE_SQL_FILE_NAME,
22+
AbstractDataSourceFactory.POSTGRES_TOKENS_TABLE_CREATE_SQL_FILE_NAME,
23+
AbstractDataSourceFactory.POSTGRES_TOKEN_METADATA_TABLE_CREATE_SQL_FILE_NAME,
2424
AbstractDataSourceFactory.KNOX_PROVIDERS_TABLE_CREATE_SQL_FILE_NAME,
2525
AbstractDataSourceFactory.KNOX_DESCRIPTORS_TABLE_CREATE_SQL_FILE_NAME
2626
),

gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/TokenStateDatabase.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@
1818
package org.apache.knox.gateway.services.token.impl;
1919

2020
import org.apache.commons.codec.binary.Base64;
21-
import org.apache.knox.gateway.GatewayMessages;
2221
import org.apache.knox.gateway.database.DatabaseType;
2322
import org.apache.knox.gateway.database.JDBCUtils;
24-
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
2523
import org.apache.knox.gateway.services.security.token.KnoxToken;
2624
import org.apache.knox.gateway.services.security.token.TokenMetadata;
27-
import org.postgresql.util.PSQLException;
2825

2926
import javax.sql.DataSource;
3027
import java.sql.Connection;
@@ -41,9 +38,6 @@
4138
import static java.nio.charset.StandardCharsets.UTF_8;
4239

4340
public class TokenStateDatabase {
44-
45-
private static final GatewayMessages LOG = MessagesFactory.get(GatewayMessages.class);
46-
4741
static final String TOKENS_TABLE_NAME = "KNOX_TOKENS";
4842
static final String TOKEN_METADATA_TABLE_NAME = "KNOX_TOKEN_METADATA";
4943
private static final String ADD_TOKEN_SQL = "INSERT INTO " + TOKENS_TABLE_NAME + "(token_id, issue_time, expiration, max_lifetime) VALUES(?, ?, ?, ?)";
@@ -66,20 +60,11 @@ public class TokenStateDatabase {
6660

6761
private final DataSource dataSource;
6862

69-
private static final String POSTGRES_DUPLICATE_OBJECT_STATE = "42710";
70-
7163
TokenStateDatabase(DataSource dataSource, String dbType) throws Exception {
7264
this.dataSource = dataSource;
7365
DatabaseType databaseType = DatabaseType.fromString(dbType);
74-
try {
75-
createTableIfNotExists(TOKENS_TABLE_NAME, databaseType.tokensTableSql());
76-
createTableIfNotExists(TOKEN_METADATA_TABLE_NAME, databaseType.metadataTableSql());
77-
} catch (PSQLException psqlException) {
78-
if (!psqlException.getSQLState().equals(POSTGRES_DUPLICATE_OBJECT_STATE)) {
79-
throw psqlException;
80-
}
81-
LOG.typeAlreadyExistsCaught();
82-
}
66+
createTableIfNotExists(TOKENS_TABLE_NAME, databaseType.tokensTableSql());
67+
createTableIfNotExists(TOKEN_METADATA_TABLE_NAME, databaseType.metadataTableSql());
8368
}
8469

8570
private void createTableIfNotExists(String tableName, String createSqlFileName) throws Exception {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one or more
2+
-- contributor license agreements. See the NOTICE file distributed with this
3+
-- work for additional information regarding copyright ownership. The ASF
4+
-- licenses this file to you under the Apache License, Version 2.0 (the
5+
-- "License"); you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- http://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
-- License for the specific language governing permissions and limitations under
14+
-- the License.
15+
16+
SELECT pg_advisory_lock (12345);
17+
18+
CREATE TABLE IF NOT EXISTS KNOX_TOKENS (
19+
token_id varchar(128) NOT NULL,
20+
issue_time bigint NOT NULL,
21+
expiration bigint NOT NULL,
22+
max_lifetime bigint NOT NULL,
23+
PRIMARY KEY (token_id)
24+
);
25+
26+
SELECT pg_advisory_unlock (12345);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one or more
2+
-- contributor license agreements. See the NOTICE file distributed with this
3+
-- work for additional information regarding copyright ownership. The ASF
4+
-- licenses this file to you under the Apache License, Version 2.0 (the
5+
-- "License"); you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- http://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
-- License for the specific language governing permissions and limitations under
14+
-- the License.
15+
16+
SELECT pg_advisory_lock (12345);
17+
18+
CREATE TABLE IF NOT EXISTS KNOX_TOKEN_METADATA (
19+
token_id varchar(128) NOT NULL,
20+
md_name varchar(32) NOT NULL,
21+
md_value varchar(256) NOT NULL,
22+
PRIMARY KEY (token_id, md_name),
23+
CONSTRAINT fk_token_id FOREIGN KEY(token_id) REFERENCES KNOX_TOKENS(token_id) ON DELETE CASCADE
24+
);
25+
26+
SELECT pg_advisory_unlock (12345);

0 commit comments

Comments
 (0)