You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@solr.apache.org by "iamsanjay (via GitHub)" <gi...@apache.org> on 2023/06/30 19:03:16 UTC
[GitHub] [solr] iamsanjay opened a new pull request, #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
iamsanjay opened a new pull request, #1740:
URL: https://github.com/apache/solr/pull/1740
https://issues.apache.org/jira/browse/SOLR-16490
<!--
_(If you are a project committer then you may remove some/all of the following template.)_
Before creating a pull request, please file an issue in the ASF Jira system for Solr:
* https://issues.apache.org/jira/projects/SOLR
For something minor (i.e. that wouldn't be worth putting in release notes), you can skip JIRA.
To create a Jira issue, you will need to create an account there first.
The title of the PR should reference the Jira issue number in the form:
* SOLR-####: <short description of problem or changes>
SOLR must be fully capitalized. A short description helps people scanning pull requests for items they can work on.
Properly referencing the issue in the title ensures that Jira is correctly updated with code review comments and commits. -->
# Description
Create a v2 equivalent for /admin/cores BACKUPCORE
# Solution
Created a new class BackupAPI.java, a new Jax RS endpoints, that contains the BackUpCoreOp.java code. Now BackupCoreOp.java class is calling this new class to create SnapShooter or the Incremental Backup.
# Tests
Created one test class that testing both Incremental and SnapShooter backup commands on.
1 The Valid response.
2 Missing Parameters.
# Checklist
Please review the following and check all that apply:
- [x] I have reviewed the guidelines for [How to Contribute](https://wiki.apache.org/solr/HowToContribute) and my code conforms to the standards described there to the best of my ability.
- [x] I have created a Jira issue and added the issue ID to my pull request title.
- [x] I have given Solr maintainers [access](https://help.github.com/en/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork) to contribute to my PR branch. (optional but recommended)
- [x] I have developed this patch against the `main` branch.
- [ ] I have run `./gradlew check`.
- [x] I have added tests for my changes.
- [ ] I have added documentation for the [Reference Guide](https://github.com/apache/solr/tree/main/solr/solr-ref-guide)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256141365
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
Review Comment:
[Q] Are the extra set of parenthesis around the path value serving a particular purpose that I'm missing?
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
Review Comment:
[-0] Should probably update "query parameter" in this message to just read "parameter" - since `location` now appears in the request body of v2 requests.
##########
solr/core/src/test/org/apache/solr/handler/admin/api/BackupCoreAPITest.java:
##########
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BackupCoreAPITest extends SolrTestCaseJ4 {
+
+ private BackupCoreAPI backupCoreAPI;
+
+ @BeforeClass
+ public static void initializeCoreAndRequestFactory() throws Exception {
+ initCore("solrconfig.xml", "schema.xml");
+
+ lrf = h.getRequestFactory("/api", 0, 10);
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ SolrQueryRequest solrQueryRequest = req();
+ SolrQueryResponse solrQueryResponse = new SolrQueryResponse();
+ CoreContainer coreContainer = h.getCoreContainer();
+
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker =
+ new CoreAdminHandler.CoreAdminAsyncTracker();
+ backupCoreAPI =
+ new BackupCoreAPI(
+ coreContainer, solrQueryRequest, solrQueryResponse, coreAdminAsyncTracker);
+ }
+
+ @Test
+ public void testCreateBackupReturnsValidResponse() throws Exception {
Review Comment:
[0] Maybe add "NonIncremental" before "Backup" in the test name, to differentiate it a bit more from the Incremental version of this test below?
##########
solr/core/src/java/org/apache/solr/handler/IncrementalShardBackup.java:
##########
@@ -134,14 +135,13 @@ private IndexCommit getAndSaveLatestIndexCommit(IndexDeletionPolicyWrapper delPo
}
// note: remember to reserve the indexCommit first so it won't get deleted concurrently
- protected NamedList<Object> backup(final IndexCommit indexCommit) throws Exception {
+ protected IncrementalBackupCoreResponse backup(final IndexCommit indexCommit) throws Exception {
Review Comment:
[+1] Always great to see NamedList usages go away!
##########
solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java:
##########
@@ -17,84 +17,48 @@
package org.apache.solr.handler.admin;
-import java.net.URI;
-import java.nio.file.Paths;
-import java.util.Optional;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.backup.ShardBackupId;
-import org.apache.solr.core.backup.repository.BackupRepository;
-import org.apache.solr.handler.IncrementalShardBackup;
-import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.api.BackupCoreAPI;
+import org.apache.solr.handler.api.V2ApiUtils;
+import org.apache.solr.jersey.SolrJerseyResponse;
class BackupCoreOp implements CoreAdminHandler.CoreAdminOp {
@Override
public void execute(CoreAdminHandler.CallInfo it) throws Exception {
final SolrParams params = it.req.getParams();
-
- String cname = params.required().get(CoreAdminParams.CORE);
- boolean incremental = isIncrementalBackup(params);
- final String name = parseBackupName(params);
- final ShardBackupId shardBackupId = parseShardBackupId(params);
- String prevShardBackupIdStr = params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
- String repoName = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ BackupCoreAPI.BackupCoreRequestBody backupCoreRequestBody =
+ new BackupCoreAPI.BackupCoreRequestBody();
+ backupCoreRequestBody.repository = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ backupCoreRequestBody.location = params.get(CoreAdminParams.BACKUP_LOCATION);
// An optional parameter to describe the snapshot to be backed-up. If this
// parameter is not supplied, the latest index commit is backed-up.
- String commitName = params.get(CoreAdminParams.COMMIT_NAME);
-
- try (BackupRepository repository = it.handler.coreContainer.newBackupRepository(repoName);
- SolrCore core = it.handler.coreContainer.getCore(cname)) {
- String location = repository.getBackupLocation(params.get(CoreAdminParams.BACKUP_LOCATION));
- if (location == null) {
- throw new SolrException(
- SolrException.ErrorCode.BAD_REQUEST,
- "'location' is not specified as a query"
- + " parameter or as a default repository property");
- }
+ backupCoreRequestBody.commitName = params.get(CoreAdminParams.COMMIT_NAME);
- URI locationUri = repository.createDirectoryURI(location);
- repository.createDirectory(locationUri);
+ String cname = params.required().get(CoreAdminParams.CORE);
+ final String name = parseBackupName(params);
+ boolean incremental = isIncrementalBackup(params);
+ if (incremental) {
+ backupCoreRequestBody.shardBackupId = params.required().get(CoreAdminParams.SHARD_BACKUP_ID);
+ backupCoreRequestBody.prevShardBackupId =
+ params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
+ backupCoreRequestBody.incremental = true;
+ }
+ BackupCoreAPI backupCoreAPI =
+ new BackupCoreAPI(
+ it.handler.coreContainer, it.req, it.rsp, it.handler.coreAdminAsyncTracker);
+ try {
+ SolrJerseyResponse response =
+ backupCoreAPI.createBackup(cname, name, backupCoreRequestBody, null);
Review Comment:
[Q/-1] Is there a reason why the last parameter of this method is always 'null'? I would've expected it to get `params.get("async")` or something similar?
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ if (backupCoreRequestBody.shardBackupId == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: shardBackupId");
+ }
+ final ShardBackupId shardBackupId =
+ ShardBackupId.from(backupCoreRequestBody.shardBackupId);
+ final ShardBackupId prevShardBackupId =
+ backupCoreRequestBody.prevShardBackupId != null
+ ? ShardBackupId.from(backupCoreRequestBody.prevShardBackupId)
+ : null;
+ BackupFilePaths incBackupFiles = new BackupFilePaths(repository, locationUri);
+ IncrementalShardBackup incSnapShooter =
+ new IncrementalShardBackup(
+ repository,
+ core,
+ incBackupFiles,
+ prevShardBackupId,
+ shardBackupId,
+ Optional.ofNullable(backupCoreRequestBody.commitName));
+ return incSnapShooter.backup();
+ } else {
+ SnapShooter snapShooter =
+ new SnapShooter(
+ repository, core, locationUri, name, backupCoreRequestBody.commitName);
+ // validateCreateSnapshot will create parent dirs instead of throw; that choice is
+ // dubious.
+ // But we want to throw. One reason is that this dir really should, in fact must,
+ // already
+ // exist here if triggered via a collection backup on a shared file system. Otherwise,
+ // perhaps the FS location isn't shared -- we want an error.
+ if (!snapShooter.getBackupRepository().exists(snapShooter.getLocation())) {
Review Comment:
Present in code only moved as a part of this PR.
##########
solr/core/src/test/org/apache/solr/handler/admin/api/BackupCoreAPITest.java:
##########
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BackupCoreAPITest extends SolrTestCaseJ4 {
+
+ private BackupCoreAPI backupCoreAPI;
+
+ @BeforeClass
+ public static void initializeCoreAndRequestFactory() throws Exception {
+ initCore("solrconfig.xml", "schema.xml");
+
+ lrf = h.getRequestFactory("/api", 0, 10);
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ SolrQueryRequest solrQueryRequest = req();
+ SolrQueryResponse solrQueryResponse = new SolrQueryResponse();
+ CoreContainer coreContainer = h.getCoreContainer();
+
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker =
+ new CoreAdminHandler.CoreAdminAsyncTracker();
+ backupCoreAPI =
+ new BackupCoreAPI(
+ coreContainer, solrQueryRequest, solrQueryResponse, coreAdminAsyncTracker);
+ }
+
+ @Test
+ public void testCreateBackupReturnsValidResponse() throws Exception {
+ final String backupName = "my-new-backup";
+ BackupCoreAPI.BackupCoreRequestBody backupCoreRequestBody = createBackupCoreRequestBody();
+ backupCoreRequestBody.incremental = false;
+ SnapShooter.SnapShooterBackupCoreResponse response =
+ (SnapShooter.SnapShooterBackupCoreResponse)
+ backupCoreAPI.createBackup(coreName, backupName, backupCoreRequestBody, null);
+
+ assertEquals(backupName, response.snapshotName);
+ assertEquals("snapshot." + backupName, response.directoryName);
+ assertEquals(1, response.fileCount);
+ assertEquals(1, response.indexFileCount);
+ }
+
+ @Test
+ public void testMissingLocationParameter() throws Exception {
+ final String backupName = "my-new-backup";
+ BackupCoreAPI.BackupCoreRequestBody backupCoreRequestBody = createBackupCoreRequestBody();
+ backupCoreRequestBody.location = null;
+ backupCoreRequestBody.incremental = false;
+ final SolrException solrException =
+ expectThrows(
+ SolrException.class,
+ () -> {
+ backupCoreAPI.createBackup(coreName, backupName, backupCoreRequestBody, null);
+ });
+ assertEquals(500, solrException.code());
+ assertTrue(
+ "Exception message differed from expected: " + solrException.getMessage(),
+ solrException.getMessage().contains("'location' is not specified as a query"));
+ }
+
+ @Test
+ public void testMissingCoreNameParameter() throws Exception {
+ final String backupName = "my-new-backup";
Review Comment:
[0] If you wanted you could create a static constant at the top of the test, and then use that in each test method.
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
Review Comment:
[-1] Shouldn't the PathParam annotation value be "coreName" instead of "core"? I've been thinking the value of these annotations need to match whatever the placeholder is up in the `@Path` annotation (see L50). If this works as-is, then I've been misunderstanding how these work for a loong time 😮
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ if (backupCoreRequestBody.shardBackupId == null) {
Review Comment:
[0] You can replace the null-check-and-throw block here (and in a few other places) with a call to `JerseyResource.ensureRequiredParameterProvided` which should be inherited and available here.
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
Review Comment:
[-1] I really like the idea of making "async" a query parameter instead of including it in the request body.
The request body of a POST or PUT is supposed to represent the resource being created or updated. Since "async" is more about _how_ the request is processed, and less about the resource itself, I think it makes sense to keep out of the request body.
But I'm worried about inconsistency across the many APIs that accept the "async" param. So far, all of these put "async" in the request body. And, personally, I'd rather keep the Solr's APIs as a whole a bit more consistent with one another than make this specific API a little bit better.
That's all to say: can we keep "async" in the request body for now?
##########
solr/core/src/test/org/apache/solr/handler/admin/api/BackupCoreAPITest.java:
##########
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BackupCoreAPITest extends SolrTestCaseJ4 {
Review Comment:
[+1] Great tests!
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ if (backupCoreRequestBody.shardBackupId == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: shardBackupId");
+ }
+ final ShardBackupId shardBackupId =
+ ShardBackupId.from(backupCoreRequestBody.shardBackupId);
+ final ShardBackupId prevShardBackupId =
+ backupCoreRequestBody.prevShardBackupId != null
+ ? ShardBackupId.from(backupCoreRequestBody.prevShardBackupId)
+ : null;
+ BackupFilePaths incBackupFiles = new BackupFilePaths(repository, locationUri);
+ IncrementalShardBackup incSnapShooter =
+ new IncrementalShardBackup(
+ repository,
+ core,
+ incBackupFiles,
+ prevShardBackupId,
+ shardBackupId,
+ Optional.ofNullable(backupCoreRequestBody.commitName));
+ return incSnapShooter.backup();
+ } else {
+ SnapShooter snapShooter =
+ new SnapShooter(
+ repository, core, locationUri, name, backupCoreRequestBody.commitName);
+ // validateCreateSnapshot will create parent dirs instead of throw; that choice is
+ // dubious.
+ // But we want to throw. One reason is that this dir really should, in fact must,
+ // already
+ // exist here if triggered via a collection backup on a shared file system. Otherwise,
+ // perhaps the FS location isn't shared -- we want an error.
+ if (!snapShooter.getBackupRepository().exists(snapShooter.getLocation())) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Directory to contain snapshots doesn't exist: "
+ + snapShooter.getLocation()
+ + ". "
+ + "Note that Backup/Restore of a SolrCloud collection "
+ + "requires a shared file system mounted at the same path on all nodes!");
+ }
+ snapShooter.validateCreateSnapshot();
+ return snapShooter.createSnapshot();
+ }
+ } catch (Exception exp) {
+ throw new SolrException(
+ SolrException.ErrorCode.SERVER_ERROR,
+ "Failed to backup core=" + coreName + " because " + exp,
+ exp);
+ }
+ });
+ }
+
+ public static class BackupCoreRequestBody extends SolrJerseyResponse {
+
+ @Schema(description = "The name of the repository to be used for backup.")
+ @JsonProperty("repository")
+ public String repository;
+
+ @Schema(description = "The path where the backup will be created")
+ @JsonProperty("location")
+ public String location;
+
+ @JsonProperty("shardBackupId")
+ public String shardBackupId;
+
+ @JsonProperty("prevShardBackupId")
+ public String prevShardBackupId;
+
+ @Schema(
+ description =
+ "The name of the commit which was used while taking a snapshot using the CREATESNAPSHOT command.")
+ @JsonProperty("commitName")
+ public String commitName;
+
+ @Schema(description = "To turn on incremental backup feature")
+ @JsonProperty("incremental")
+ public boolean incremental;
Review Comment:
[-1] We should have this be a `Boolean`, so that BackupCoreAPI has a way to tell whether users actually requested 'false' in their request or whether they just didn't provide a value. This property is supposed to default to 'true', so it's pretty important to know whether users explicitly requested 'false' or not.
##########
solr/core/src/java/org/apache/solr/handler/SnapShooter.java:
##########
@@ -277,7 +281,8 @@ public void createSnapAsync(final int numberToKeep, Consumer<NamedList<?>> resul
* @see IndexDeletionPolicyWrapper#saveCommitPoint
* @see IndexDeletionPolicyWrapper#releaseCommitPoint
*/
- protected NamedList<Object> createSnapshot(final IndexCommit indexCommit) throws Exception {
+ protected SnapShooterBackupCoreResponse createSnapshot(final IndexCommit indexCommit)
Review Comment:
[Q] Looking at createSnapAsync, it looks like this same `createSnapshot()` code is also called by Solr's "ReplicationHandler" (i.e. `/replication`) APIs.
Maybe the name of the response class should be made more generic so that it's not so "Backup Core API" specific? Maybe something like `CoreSnapshotResponse` or `CoreSnapshotDetails`? Idk, just thinking aloud...
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
Review Comment:
[-1] Shouldn't the PathParam annotation value be "coreName" instead of "core"? I've been thinking the value of these annotations need to match whatever the placeholder is up in the `@Path` annotation (see L50). If this works as-is, then I've been misunderstanding how these work for a loong time 😮
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256683858
##########
solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java:
##########
@@ -17,84 +17,48 @@
package org.apache.solr.handler.admin;
-import java.net.URI;
-import java.nio.file.Paths;
-import java.util.Optional;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.backup.ShardBackupId;
-import org.apache.solr.core.backup.repository.BackupRepository;
-import org.apache.solr.handler.IncrementalShardBackup;
-import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.api.BackupCoreAPI;
+import org.apache.solr.handler.api.V2ApiUtils;
+import org.apache.solr.jersey.SolrJerseyResponse;
class BackupCoreOp implements CoreAdminHandler.CoreAdminOp {
@Override
public void execute(CoreAdminHandler.CallInfo it) throws Exception {
final SolrParams params = it.req.getParams();
-
- String cname = params.required().get(CoreAdminParams.CORE);
- boolean incremental = isIncrementalBackup(params);
- final String name = parseBackupName(params);
- final ShardBackupId shardBackupId = parseShardBackupId(params);
- String prevShardBackupIdStr = params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
- String repoName = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ BackupCoreAPI.BackupCoreRequestBody backupCoreRequestBody =
+ new BackupCoreAPI.BackupCoreRequestBody();
+ backupCoreRequestBody.repository = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ backupCoreRequestBody.location = params.get(CoreAdminParams.BACKUP_LOCATION);
// An optional parameter to describe the snapshot to be backed-up. If this
// parameter is not supplied, the latest index commit is backed-up.
- String commitName = params.get(CoreAdminParams.COMMIT_NAME);
-
- try (BackupRepository repository = it.handler.coreContainer.newBackupRepository(repoName);
- SolrCore core = it.handler.coreContainer.getCore(cname)) {
- String location = repository.getBackupLocation(params.get(CoreAdminParams.BACKUP_LOCATION));
- if (location == null) {
- throw new SolrException(
- SolrException.ErrorCode.BAD_REQUEST,
- "'location' is not specified as a query"
- + " parameter or as a default repository property");
- }
+ backupCoreRequestBody.commitName = params.get(CoreAdminParams.COMMIT_NAME);
- URI locationUri = repository.createDirectoryURI(location);
- repository.createDirectory(locationUri);
+ String cname = params.required().get(CoreAdminParams.CORE);
+ final String name = parseBackupName(params);
+ boolean incremental = isIncrementalBackup(params);
+ if (incremental) {
+ backupCoreRequestBody.shardBackupId = params.required().get(CoreAdminParams.SHARD_BACKUP_ID);
+ backupCoreRequestBody.prevShardBackupId =
+ params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
+ backupCoreRequestBody.incremental = true;
+ }
+ BackupCoreAPI backupCoreAPI =
+ new BackupCoreAPI(
+ it.handler.coreContainer, it.req, it.rsp, it.handler.coreAdminAsyncTracker);
+ try {
+ SolrJerseyResponse response =
+ backupCoreAPI.createBackup(cname, name, backupCoreRequestBody, null);
Review Comment:
I believe v1 calls come through `CoreAdminHandler.handleRequestBody()` and it looks for `async` parameter. If present, they create an CoreAdminOp object, such as BackupCoreOp in our case and then run it asynchronously via calling `CoreAdminAsyncTracker.submitAsyncTask()`. As per my understanding, if we start submitting `async` in `BackupCoreOp` as well then same task will be submitted twice to `ExecutorService`. https://github.com/apache/solr/blob/583fdf0cc7438cd3a50e4d0aa865281ff209c5c6/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java#L196-L227
But if call come via v2 api, then we are passing the actual taskID, not null.
https://github.com/apache/solr/blob/cbe661547d7f12f0c4d21e6fef4e03455b97575c/solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java#L78-L84
Same way we are handling in `CreateSnapshotOp.java`.
https://github.com/apache/solr/blob/583fdf0cc7438cd3a50e4d0aa865281ff209c5c6/solr/core/src/java/org/apache/solr/handler/admin/CreateSnapshotOp.java#L37-L38
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272662520
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ backupCoreRequestBody.async,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' parameter is not specified in the request body or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
Review Comment:
[-1] If a v2 request comes in that doesn't specify "incremental" in the request body, the `Boolean` value here might be null and this conditional will cause a NPE
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272773932
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
Review Comment:
I've updated the path to `/cores/<coreName>/backups`, and created a field in the request body to hold the "backup name" parameter.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256927914
##########
solr/core/src/java/org/apache/solr/handler/SnapShooter.java:
##########
@@ -277,7 +281,8 @@ public void createSnapAsync(final int numberToKeep, Consumer<NamedList<?>> resul
* @see IndexDeletionPolicyWrapper#saveCommitPoint
* @see IndexDeletionPolicyWrapper#releaseCommitPoint
*/
- protected NamedList<Object> createSnapshot(final IndexCommit indexCommit) throws Exception {
+ protected SnapShooterBackupCoreResponse createSnapshot(final IndexCommit indexCommit)
Review Comment:
`CoreSnapshotResponse` looks good because most of our JerseyResponse classes ends with 'Response' keyword. There is another class named `IncrementalBackupCoreResponse.java`. Should I change it to `IncrementalShardSnapshotResponse.java`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1262559312
##########
solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java:
##########
@@ -17,84 +17,48 @@
package org.apache.solr.handler.admin;
-import java.net.URI;
-import java.nio.file.Paths;
-import java.util.Optional;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.backup.ShardBackupId;
-import org.apache.solr.core.backup.repository.BackupRepository;
-import org.apache.solr.handler.IncrementalShardBackup;
-import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.api.BackupCoreAPI;
+import org.apache.solr.handler.api.V2ApiUtils;
+import org.apache.solr.jersey.SolrJerseyResponse;
class BackupCoreOp implements CoreAdminHandler.CoreAdminOp {
@Override
public void execute(CoreAdminHandler.CallInfo it) throws Exception {
final SolrParams params = it.req.getParams();
-
- String cname = params.required().get(CoreAdminParams.CORE);
- boolean incremental = isIncrementalBackup(params);
- final String name = parseBackupName(params);
- final ShardBackupId shardBackupId = parseShardBackupId(params);
- String prevShardBackupIdStr = params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
- String repoName = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ BackupCoreAPI.BackupCoreRequestBody backupCoreRequestBody =
+ new BackupCoreAPI.BackupCoreRequestBody();
+ backupCoreRequestBody.repository = params.get(CoreAdminParams.BACKUP_REPOSITORY);
+ backupCoreRequestBody.location = params.get(CoreAdminParams.BACKUP_LOCATION);
// An optional parameter to describe the snapshot to be backed-up. If this
// parameter is not supplied, the latest index commit is backed-up.
- String commitName = params.get(CoreAdminParams.COMMIT_NAME);
-
- try (BackupRepository repository = it.handler.coreContainer.newBackupRepository(repoName);
- SolrCore core = it.handler.coreContainer.getCore(cname)) {
- String location = repository.getBackupLocation(params.get(CoreAdminParams.BACKUP_LOCATION));
- if (location == null) {
- throw new SolrException(
- SolrException.ErrorCode.BAD_REQUEST,
- "'location' is not specified as a query"
- + " parameter or as a default repository property");
- }
+ backupCoreRequestBody.commitName = params.get(CoreAdminParams.COMMIT_NAME);
- URI locationUri = repository.createDirectoryURI(location);
- repository.createDirectory(locationUri);
+ String cname = params.required().get(CoreAdminParams.CORE);
+ final String name = parseBackupName(params);
+ boolean incremental = isIncrementalBackup(params);
+ if (incremental) {
+ backupCoreRequestBody.shardBackupId = params.required().get(CoreAdminParams.SHARD_BACKUP_ID);
+ backupCoreRequestBody.prevShardBackupId =
+ params.get(CoreAdminParams.PREV_SHARD_BACKUP_ID, null);
+ backupCoreRequestBody.incremental = true;
+ }
+ BackupCoreAPI backupCoreAPI =
+ new BackupCoreAPI(
+ it.handler.coreContainer, it.req, it.rsp, it.handler.coreAdminAsyncTracker);
+ try {
+ SolrJerseyResponse response =
+ backupCoreAPI.createBackup(cname, name, backupCoreRequestBody, null);
Review Comment:
OK, makes sense; good catch.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1262563121
##########
solr/core/src/java/org/apache/solr/handler/SnapShooter.java:
##########
@@ -277,7 +281,8 @@ public void createSnapAsync(final int numberToKeep, Consumer<NamedList<?>> resul
* @see IndexDeletionPolicyWrapper#saveCommitPoint
* @see IndexDeletionPolicyWrapper#releaseCommitPoint
*/
- protected NamedList<Object> createSnapshot(final IndexCommit indexCommit) throws Exception {
+ protected SnapShooterBackupCoreResponse createSnapshot(final IndexCommit indexCommit)
Review Comment:
Sure, renaming them both consistently makes sense to me?
##########
solr/core/src/java/org/apache/solr/handler/SnapShooter.java:
##########
@@ -277,7 +281,8 @@ public void createSnapAsync(final int numberToKeep, Consumer<NamedList<?>> resul
* @see IndexDeletionPolicyWrapper#saveCommitPoint
* @see IndexDeletionPolicyWrapper#releaseCommitPoint
*/
- protected NamedList<Object> createSnapshot(final IndexCommit indexCommit) throws Exception {
+ protected SnapShooterBackupCoreResponse createSnapshot(final IndexCommit indexCommit)
Review Comment:
Sure, renaming them both consistently makes sense to me.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256690342
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
Review Comment:
Not sure. Going to remove the extra ones!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272653851
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
Review Comment:
[-1] I think I steered you towards this using this path value, so this is totally my fault, but I don't think we can put the backup name in the path.
I hadn't realized it until debugging some tests this afternoon, but the backup name only exists for non-incremental core backups. Incremental core backups don't even have a concept of "backup names" (for reference see [this code in BackupCoreOp that parses the param](https://github.com/apache/solr/pull/1740/files#diff-0c6a9444b6016570c565957acf8a067084b4808a50cd96e89e3e514cdcbbb675R80))
Path parameters are almost always required values, so we'll have to move the param elsewhere (probably into the request body).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272725539
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ backupCoreRequestBody.async,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' parameter is not specified in the request body or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ ensureRequiredParameterProvided("shardBackupId", backupCoreRequestBody.shardBackupId);
Review Comment:
My mistake - I thought I was tracing a test failure to this, but was misreading the stack. Ignore
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] sonatype-lift[bot] commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "sonatype-lift[bot] (via GitHub)" <gi...@apache.org>.
sonatype-lift[bot] commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1248254353
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ if (backupCoreRequestBody.shardBackupId == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: shardBackupId");
+ }
+ final ShardBackupId shardBackupId =
+ ShardBackupId.from(backupCoreRequestBody.shardBackupId);
+ final ShardBackupId prevShardBackupId =
+ backupCoreRequestBody.prevShardBackupId != null
+ ? ShardBackupId.from(backupCoreRequestBody.prevShardBackupId)
+ : null;
+ BackupFilePaths incBackupFiles = new BackupFilePaths(repository, locationUri);
+ IncrementalShardBackup incSnapShooter =
+ new IncrementalShardBackup(
+ repository,
+ core,
+ incBackupFiles,
+ prevShardBackupId,
+ shardBackupId,
+ Optional.ofNullable(backupCoreRequestBody.commitName));
+ return incSnapShooter.backup();
+ } else {
+ SnapShooter snapShooter =
+ new SnapShooter(
+ repository, core, locationUri, name, backupCoreRequestBody.commitName);
+ // validateCreateSnapshot will create parent dirs instead of throw; that choice is
+ // dubious.
+ // But we want to throw. One reason is that this dir really should, in fact must,
+ // already
+ // exist here if triggered via a collection backup on a shared file system. Otherwise,
+ // perhaps the FS location isn't shared -- we want an error.
+ if (!snapShooter.getBackupRepository().exists(snapShooter.getLocation())) {
Review Comment:
<picture><img alt="14% of developers fix this issue" src="https://lift.sonatype.com/api/commentimage/fixrate/14/display.svg"></picture>
<b>*NULL_DEREFERENCE:</b>* object returned by `getBackupRepository(snapShooter)` could be null and is dereferenced at line 132.
---
<details><summary>ℹ️ Expand to see all <b>@sonatype-lift</b> commands</summary>
You can reply with the following commands. For example, reply with ***@sonatype-lift ignoreall*** to leave out all findings.
| **Command** | **Usage** |
| ------------- | ------------- |
| `@sonatype-lift ignore` | Leave out the above finding from this PR |
| `@sonatype-lift ignoreall` | Leave out all the existing findings from this PR |
| `@sonatype-lift exclude <file\|issue\|path\|tool>` | Exclude specified `file\|issue\|path\|tool` from Lift findings by updating your config.toml file |
**Note:** When talking to LiftBot, you need to **refresh** the page to see its response.
<sub>[Click here](https://github.com/apps/sonatype-lift/installations/new) to add LiftBot to another repo.</sub></details>
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
Review Comment:
<picture><img alt="9% of developers fix this issue" src="https://lift.sonatype.com/api/commentimage/fixrate/9/display.svg"></picture>
<b>*[PATH_TRAVERSAL_IN](https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN):</b>* This API (java/nio/file/Paths.get(Ljava/net/URI;)Ljava/nio/file/Path;) reads a file whose location might be specified by user input
---
<details><summary>ℹ️ Expand to see all <b>@sonatype-lift</b> commands</summary>
You can reply with the following commands. For example, reply with ***@sonatype-lift ignoreall*** to leave out all findings.
| **Command** | **Usage** |
| ------------- | ------------- |
| `@sonatype-lift ignore` | Leave out the above finding from this PR |
| `@sonatype-lift ignoreall` | Leave out all the existing findings from this PR |
| `@sonatype-lift exclude <file\|issue\|path\|tool>` | Exclude specified `file\|issue\|path\|tool` from Lift findings by updating your config.toml file |
**Note:** When talking to LiftBot, you need to **refresh** the page to see its response.
<sub>[Click here](https://github.com/apps/sonatype-lift/installations/new) to add LiftBot to another repo.</sub></details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256702327
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
+ + " parameter or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ if (backupCoreRequestBody.shardBackupId == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: shardBackupId");
+ }
+ final ShardBackupId shardBackupId =
+ ShardBackupId.from(backupCoreRequestBody.shardBackupId);
+ final ShardBackupId prevShardBackupId =
+ backupCoreRequestBody.prevShardBackupId != null
+ ? ShardBackupId.from(backupCoreRequestBody.prevShardBackupId)
+ : null;
+ BackupFilePaths incBackupFiles = new BackupFilePaths(repository, locationUri);
+ IncrementalShardBackup incSnapShooter =
+ new IncrementalShardBackup(
+ repository,
+ core,
+ incBackupFiles,
+ prevShardBackupId,
+ shardBackupId,
+ Optional.ofNullable(backupCoreRequestBody.commitName));
+ return incSnapShooter.backup();
+ } else {
+ SnapShooter snapShooter =
+ new SnapShooter(
+ repository, core, locationUri, name, backupCoreRequestBody.commitName);
+ // validateCreateSnapshot will create parent dirs instead of throw; that choice is
+ // dubious.
+ // But we want to throw. One reason is that this dir really should, in fact must,
+ // already
+ // exist here if triggered via a collection backup on a shared file system. Otherwise,
+ // perhaps the FS location isn't shared -- we want an error.
+ if (!snapShooter.getBackupRepository().exists(snapShooter.getLocation())) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Directory to contain snapshots doesn't exist: "
+ + snapShooter.getLocation()
+ + ". "
+ + "Note that Backup/Restore of a SolrCloud collection "
+ + "requires a shared file system mounted at the same path on all nodes!");
+ }
+ snapShooter.validateCreateSnapshot();
+ return snapShooter.createSnapshot();
+ }
+ } catch (Exception exp) {
+ throw new SolrException(
+ SolrException.ErrorCode.SERVER_ERROR,
+ "Failed to backup core=" + coreName + " because " + exp,
+ exp);
+ }
+ });
+ }
+
+ public static class BackupCoreRequestBody extends SolrJerseyResponse {
+
+ @Schema(description = "The name of the repository to be used for backup.")
+ @JsonProperty("repository")
+ public String repository;
+
+ @Schema(description = "The path where the backup will be created")
+ @JsonProperty("location")
+ public String location;
+
+ @JsonProperty("shardBackupId")
+ public String shardBackupId;
+
+ @JsonProperty("prevShardBackupId")
+ public String prevShardBackupId;
+
+ @Schema(
+ description =
+ "The name of the commit which was used while taking a snapshot using the CREATESNAPSHOT command.")
+ @JsonProperty("commitName")
+ public String commitName;
+
+ @Schema(description = "To turn on incremental backup feature")
+ @JsonProperty("incremental")
+ public boolean incremental;
Review Comment:
I will change it to `Boolean`. Also,
[Q] Should I set default value to 'true' here? Because, and also you mentioned, in `BackupCoreOp.java, If `incremental` is missing they set it to 'true'.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272661264
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
Review Comment:
[-1] This value cannot be 'null' - `handlePotentiallyAsynchronousTask` uses it to squash receive whatever response data is generated by the lambda below. I think we're getting an NPE in some tests because of this.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272774432
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ backupCoreRequestBody.async,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' parameter is not specified in the request body or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
Review Comment:
Fixed - there's a nice little recipe to handle the extra 'null' case around `Boolean` types: `Boolean.TRUE.equals(backupCoreRequestBody.incremental)`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija merged pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija merged PR #1740:
URL: https://github.com/apache/solr/pull/1740
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256689988
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
Review Comment:
It should be the same name as the one in parenthesis. Will change it!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256693172
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
+ String taskId)
+ throws Exception {
+ if (coreName == null)
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "Missing required parameter: " + CoreAdminParams.CORE);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ taskId,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' is not specified as a query"
Review Comment:
I was thinking of using the `JerseyResource.ensureRequiredParameterProvided` here as well. But looks like here we need more custom error message. I will just change the error message!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1256692056
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path(("/cores/{coreName}/backup/{name}"))
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Schema(description = "The name of the core.") @PathParam("core") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody,
+ @Parameter(description = "The id to associate with the async task.") @QueryParam("async")
Review Comment:
There is one API (`CoreSnapshotAPI.java`) class in which it used as QueryParam. But most of the classes are using via RequestBody. So I am going to include in RequestBody as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272544000
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ backupCoreRequestBody.async,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' parameter is not specified in the request body or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
+ if ("file".equals(locationUri.getScheme())) {
+ core.getCoreContainer().assertPathAllowed(Paths.get(locationUri));
+ }
+ ensureRequiredParameterProvided("shardBackupId", backupCoreRequestBody.shardBackupId);
Review Comment:
[-1] `shardBackupId` shouldn't be required idt, since we technically still support "non-incremental" backups which don't build off of a previous backup.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272662520
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
+ coreName,
+ backupCoreRequestBody.async,
+ "backup",
+ () -> {
+ try (BackupRepository repository =
+ coreContainer.newBackupRepository(backupCoreRequestBody.repository);
+ SolrCore core = coreContainer.getCore(coreName)) {
+ String location = repository.getBackupLocation(backupCoreRequestBody.location);
+ if (location == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST,
+ "'location' parameter is not specified in the request body or as a default repository property");
+ }
+ URI locationUri = repository.createDirectoryURI(location);
+ repository.createDirectory(locationUri);
+
+ if (backupCoreRequestBody.incremental) {
Review Comment:
[-1] If a v2 request comes in that doesn't specify "incremental" in the request body, the `Boolean` value here might be null and this conditional will cause a NPE
EDIT: I'm fixing this in a forthcoming commit.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] gerlowskija commented on a diff in pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1740:
URL: https://github.com/apache/solr/pull/1740#discussion_r1272725984
##########
solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Optional;
+import javax.inject.Inject;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.backup.BackupFilePaths;
+import org.apache.solr.core.backup.ShardBackupId;
+import org.apache.solr.core.backup.repository.BackupRepository;
+import org.apache.solr.handler.IncrementalShardBackup;
+import org.apache.solr.handler.SnapShooter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/cores/{coreName}/backup/{name}")
+public class BackupCoreAPI extends CoreAdminAPIBase {
+ @Inject
+ public BackupCoreAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse,
+ CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker) {
+ super(coreContainer, coreAdminAsyncTracker, solrQueryRequest, solrQueryResponse);
+ }
+
+ @POST
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse createBackup(
+ @Parameter(description = "The name of the core.") @PathParam("coreName") String coreName,
+ @Schema(description = "The backup will be created in a directory called snapshot.<name>")
+ @PathParam("name")
+ String name,
+ @Schema(description = "The POJO for representing additional backup params.") @RequestBody
+ BackupCoreRequestBody backupCoreRequestBody)
+ throws Exception {
+ ensureRequiredParameterProvided("coreName", coreName);
+ return handlePotentiallyAsynchronousTask(
+ null,
Review Comment:
Gah - another misconception I had while debugging test failures. Forget I said anything.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org
[GitHub] [solr] iamsanjay commented on pull request #1740: SOLR-16490: Create a v2 equivalent for /admin/cores BACKUPCORE
Posted by "iamsanjay (via GitHub)" <gi...@apache.org>.
iamsanjay commented on PR #1740:
URL: https://github.com/apache/solr/pull/1740#issuecomment-1626404187
> Thanks for the PR Sanjay! Exciting to close these gaps in v2 coverage. The bones of this all look pretty good, though there were a few things I commented on that I think will need changed. Feel free to reply inline and we can go from there.
>
> I know our ref-guide docs around the core-backup functionality is pretty patchy, we'll probably want to update those to include the new "v2" version of the API.
I search through documentation we never really mentioned 'BACKUPCORE' operation. We only provided documentation where the backup is done via `ReplicationHandler` for single core mode.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org