diff --git a/engine/src/main/java/com/arcadedb/GlobalConfiguration.java b/engine/src/main/java/com/arcadedb/GlobalConfiguration.java index 3b016b5a99..ddf6758da5 100644 --- a/engine/src/main/java/com/arcadedb/GlobalConfiguration.java +++ b/engine/src/main/java/com/arcadedb/GlobalConfiguration.java @@ -204,14 +204,19 @@ public Object call(final Object value) { SERVER_DATABASE_LOADATSTARTUP("arcadedb.server.databaseLoadAtStartup", "Open all the available databases at server startup", Boolean.class, true), - SERVER_PLUGINS("arcadedb.server.plugins", "List of server plugins to install. The format to load a plugin is: `:`", String.class, - ""), - SERVER_DEFAULT_DATABASES("arcadedb.server.defaultDatabases", "The default databases created when the server starts. The format is `([(:[:])[,]*])[{import|restore:}][;]*'. Pay attention on using `;`" + " to separate databases and `,` to separate credentials. The supported actions are `import` and `restore`. Example: `Universe[elon:musk:admin];Amiga[Jay:Miner,Jack:Tramiel]{import:/tmp/movies.tgz}`", String.class, ""), + SERVER_DEFAULT_DATABASE_MODE("arcadedb.server.defaultDatabaseMode", + "The default mode to load pre-existing databases. The value must match a com.arcadedb.engine.PaginatedFile.MODE enum value: {READ_ONLY, READ_WRITE}" + + "Databases which are newly created will always be opened READ_WRITE.", + String.class, "READ_WRITE"), + + SERVER_PLUGINS("arcadedb.server.plugins", "List of server plugins to install. The format to load a plugin is: `:`", String.class, + ""), + // SERVER HTTP SERVER_HTTP_INCOMING_HOST("arcadedb.server.httpIncomingHost", "TCP/IP host name used for incoming HTTP connections", String.class, "0.0.0.0"), diff --git a/server/src/main/java/com/arcadedb/server/ArcadeDBServer.java b/server/src/main/java/com/arcadedb/server/ArcadeDBServer.java index 154e972fcd..c1b225314e 100644 --- a/server/src/main/java/com/arcadedb/server/ArcadeDBServer.java +++ b/server/src/main/java/com/arcadedb/server/ArcadeDBServer.java @@ -18,6 +18,8 @@ */ package com.arcadedb.server; +import static com.arcadedb.engine.PaginatedFile.MODE.READ_WRITE; + import com.arcadedb.Constants; import com.arcadedb.ContextConfiguration; import com.arcadedb.GlobalConfiguration; @@ -25,6 +27,7 @@ import com.arcadedb.database.DatabaseFactory; import com.arcadedb.database.DatabaseInternal; import com.arcadedb.database.EmbeddedDatabase; +import com.arcadedb.engine.PaginatedFile; import com.arcadedb.exception.CommandExecutionException; import com.arcadedb.exception.ConfigurationException; import com.arcadedb.exception.DatabaseIsClosedException; @@ -350,10 +353,14 @@ public synchronized Database getDatabase(final String databaseName, final boolea factory.setSecurity(getSecurity()); + final PaginatedFile.MODE defaultDbMode = Optional.ofNullable( + GlobalConfiguration.SERVER_DEFAULT_DATABASE_MODE.getValueAsEnum(PaginatedFile.MODE.class)) + .orElse(READ_WRITE); + if (createIfNotExists) - db = (DatabaseInternal) (factory.exists() ? factory.open() : factory.create()); + db = (DatabaseInternal) (factory.exists() ? factory.open(defaultDbMode) : factory.create()); else - db = (DatabaseInternal) factory.open(); + db = (DatabaseInternal) factory.open(defaultDbMode); if (configuration.getValueAsBoolean(GlobalConfiguration.HA_ENABLED)) db = new ReplicatedDatabase(this, (EmbeddedDatabase) db); diff --git a/server/src/test/java/com/arcadedb/server/ServerDefaultDatabasesIT.java b/server/src/test/java/com/arcadedb/server/ServerDefaultDatabasesIT.java index 681e39cf2f..dc93d3190f 100644 --- a/server/src/test/java/com/arcadedb/server/ServerDefaultDatabasesIT.java +++ b/server/src/test/java/com/arcadedb/server/ServerDefaultDatabasesIT.java @@ -18,6 +18,8 @@ */ package com.arcadedb.server; +import static com.arcadedb.engine.PaginatedFile.MODE.READ_WRITE; + import com.arcadedb.ContextConfiguration; import com.arcadedb.GlobalConfiguration; import com.arcadedb.database.DatabaseInternal; @@ -77,6 +79,9 @@ public void checkDefaultDatabases() throws IOException { Assertions.assertTrue(getServer(0).existsDatabase("Universe")); Assertions.assertTrue(getServer(0).existsDatabase("Amiga")); + Assertions.assertTrue(READ_WRITE.equals(getServer(0).getDatabase("Universe").getMode())); + Assertions.assertTrue(READ_WRITE.equals(getServer(0).getDatabase("Amiga").getMode())); + ((DatabaseInternal) getServer(0).getDatabase("Universe")).getEmbedded().drop(); ((DatabaseInternal) getServer(0).getDatabase("Amiga")).getEmbedded().drop(); } diff --git a/server/src/test/java/com/arcadedb/server/ServerReadOnlyDatabasesIT.java b/server/src/test/java/com/arcadedb/server/ServerReadOnlyDatabasesIT.java new file mode 100644 index 0000000000..fa39b2f39a --- /dev/null +++ b/server/src/test/java/com/arcadedb/server/ServerReadOnlyDatabasesIT.java @@ -0,0 +1,54 @@ +/* + * Copyright © 2022-present Arcade Data Ltd (info@arcadedata.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. + * + * SPDX-FileCopyrightText: 2022-present Arcade Data Ltd (info@arcadedata.com) + * SPDX-License-Identifier: Apache-2.0 + */ +package com.arcadedb.server; + +import static com.arcadedb.engine.PaginatedFile.MODE.READ_ONLY; + +import com.arcadedb.ContextConfiguration; +import com.arcadedb.GlobalConfiguration; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.*; + +public class ServerReadOnlyDatabasesIT extends BaseGraphServerTest { + + @Override + protected boolean isCreateDatabases() { + return false; + } + + @Override + protected void populateDatabase() { + } + + protected void onServerConfiguration(final ContextConfiguration config) { + config.setValue(GlobalConfiguration.SERVER_DEFAULT_DATABASES, "Universe[elon:musk:admin];Amiga[Jay:Miner:admin,Jack:Tramiel:admin,root]"); + config.setValue(GlobalConfiguration.SERVER_DEFAULT_DATABASE_MODE, "READ_ONLY"); + } + + @Test + public void checkDefaultDatabases() throws IOException { + Assertions.assertTrue(getServer(0).existsDatabase("Universe")); + Assertions.assertTrue(getServer(0).existsDatabase("Amiga")); + + Assertions.assertTrue(READ_ONLY.equals(getServer(0).getDatabase("Universe").getMode())); + Assertions.assertTrue(READ_ONLY.equals(getServer(0).getDatabase("Amiga").getMode())); + } +}