Skip to content

Commit

Permalink
BatchProcessor works for delete-draft
Browse files Browse the repository at this point in the history
  • Loading branch information
janvanmansum committed Jun 20, 2024
1 parent b7e9453 commit 155959a
Show file tree
Hide file tree
Showing 13 changed files with 282 additions and 73 deletions.
8 changes: 0 additions & 8 deletions src/main/java/nl/knaw/dans/dvcli/ItemProvider.java

This file was deleted.

19 changes: 0 additions & 19 deletions src/main/java/nl/knaw/dans/dvcli/action/Action.java

This file was deleted.

6 changes: 0 additions & 6 deletions src/main/java/nl/knaw/dans/dvcli/action/ActionSource.java

This file was deleted.

68 changes: 59 additions & 9 deletions src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,75 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

import lombok.Builder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.function.Function;

/**
* Processes a batch of labeled items by applying an action to each item. The labels are used for reporting. Typically, the label is the ID of the item. After each action, the processor waits for a
* delay, if specified. The processor reports the results of the actions to a report.
*
* @param <I> the type of the items
* @param <R> the type of action results
* @see Report for the interface that the report must implement
*/
@Builder
@Slf4j
public class BatchProcessor<I> {
private Iterable<I> items;
private Action action;
public class BatchProcessor<I, R> {
/**
* The labeled items to process.
*/
private final Iterable<Pair<String, I>> labeledItems;

private long delay;
/**
* The action to apply to each item.
*/
private final ThrowingFunction<I, R, Exception> action;

/**
* The report to which the results of the actions are reported.
*/
private final Report<I, R> report;

/**
* The delay in milliseconds between processing items. A delay of 0 or less means no delay.
*/
@Builder.Default
private final long delay = 1000;

public void process() {
log.info("Starting batch processing");
int i = 0;
for (var item : items) {
for (var labeledItem : labeledItems) {
delayIfNeeded(i);
logStartAction(++i);
action.apply(item);
callAction(labeledItem.getFirst(), labeledItem.getSecond());
}
log.info("Finished batch processing");
}

private void callAction(String label, I item) {
try {
R r = action.apply(item);
report.reportSuccess(label, item, r);
}
catch (Exception e) {
report.reportFailure(label, item, e);
}
}

Expand All @@ -37,8 +87,8 @@ private void delayIfNeeded(int i) {
}

private void logStartAction(int i) {
if (items instanceof List) {
log.info("Processing item {} of {}", i, ((List<?>) items).size());
if (labeledItems instanceof List) {
log.info("Processing item {} of {}", i, ((List<?>) labeledItems).size());
}
else {
log.info("Processing item {}", i);
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/nl/knaw/dans/dvcli/action/ConsoleReport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

/**
* Implements a report to the console.
*
* @param <I> the type of the item that was processed
* @param <R> the type of the result of the action
*/
public class ConsoleReport<I, R> implements Report<I, R> {

@Override
public void reportSuccess(String label, I i, R r) {
System.err.println(label + ": OK");
}

@Override
public void reportFailure(String label, I i, Exception e) {
System.err.println(label + ": FAILED: " + e.getMessage());
}
}
4 changes: 0 additions & 4 deletions src/main/java/nl/knaw/dans/dvcli/action/Item.java

This file was deleted.

24 changes: 24 additions & 0 deletions src/main/java/nl/knaw/dans/dvcli/action/Pair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

import lombok.Value;

@Value
public class Pair<F,S> {
F first;
S second;
}
43 changes: 40 additions & 3 deletions src/main/java/nl/knaw/dans/dvcli/action/Report.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

public interface Report {

void report(String message);
/**
* Report the success or failure of an action.
*
* @param <T> the type of the item that was processed
* @param <R> the type of the result of the action
*/
public interface Report<T, R> {

/**
* Report a successful action.
*
* @param label a label for the item that was processed
* @param t the item that was processed
* @param r the result of the action
*/
void reportSuccess(String label, T t, R r);

/**
* Report a failed action.
*
* @param label a label for the item for which the action was attempted
* @param t the item for which the action was attempted
* @param e the exception that was thrown
*/
void reportFailure(String label, T t, Exception e);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

import nl.knaw.dans.lib.dataverse.DatasetApi;
import nl.knaw.dans.lib.dataverse.DataverseClient;

import java.io.IOException;
import java.util.stream.Stream;

public class SingleDatasetOrDatasetsFile {
private final SingleIdOrIdsFile singleIdOrIdsFile;
private final DataverseClient dataverseClient;

public SingleDatasetOrDatasetsFile(String singleDatasetOrDatasetsFile, DataverseClient dataverseClient) {
this.singleIdOrIdsFile = new SingleIdOrIdsFile(singleDatasetOrDatasetsFile);
this.dataverseClient = dataverseClient;
}

public Stream<Pair<String, DatasetApi>> getDatasets() throws IOException {
return singleIdOrIdsFile.getPids().map(
id -> {
try {
var dbId = Integer.parseInt(id);
return new Pair<>(id, dataverseClient.dataset(dbId));
}
catch (NumberFormatException e) {
// Assume it is a PID
}
return new Pair<>(id, dataverseClient.dataset(id));
});
}
}
36 changes: 36 additions & 0 deletions src/main/java/nl/knaw/dans/dvcli/action/SingleIdOrIdsFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

import lombok.AllArgsConstructor;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

@AllArgsConstructor
public class SingleIdOrIdsFile {
private final String singleIdOrIdFile;

public Stream<String> getPids() throws IOException {
var pidFile = Paths.get(singleIdOrIdFile);
if (Files.exists(pidFile)) {
return Files.readAllLines(pidFile).stream().map(String::trim);
}
return Stream.of(singleIdOrIdFile);
}
}
21 changes: 21 additions & 0 deletions src/main/java/nl/knaw/dans/dvcli/action/ThrowingFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2024 DANS - Data Archiving and Networked Services ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.knaw.dans.dvcli.action;

@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
R apply(T t) throws E;
}
26 changes: 9 additions & 17 deletions src/main/java/nl/knaw/dans/dvcli/command/DatasetCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,33 @@
*/
package nl.knaw.dans.dvcli.command;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import nl.knaw.dans.dvcli.action.Pair;
import nl.knaw.dans.dvcli.action.SingleDatasetOrDatasetsFile;
import nl.knaw.dans.dvcli.action.SingleIdOrIdsFile;
import nl.knaw.dans.lib.dataverse.DatasetApi;
import nl.knaw.dans.lib.dataverse.DataverseClient;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Command(name = "dataset",
mixinStandardHelpOptions = true,
description = "Manage Dataverse datasets")
@Slf4j
public class DatasetCmd extends AbstractSubcommandContainer {
@Parameters(index = "0", paramLabel = "id", description = "The id or PID of the dataset")
@Parameters(index = "0", paramLabel = "id", description = "The ID or PID of the dataset, or a file with a list of IDs or PIDs.")
private String id;

public DatasetCmd(DataverseClient dataverseClient) {
super(dataverseClient);
}



List<DatasetApi> getDatasets() {
// If id is a number convert it to an integer
try {
var databaseId = Integer.parseInt(id);
log.debug("ID {} is a number, assuming it is a database ID", id);
return List.of(dataverseClient.dataset(databaseId));
}
catch (NumberFormatException e) {
// Do nothing
}
log.debug("ID {} is not a number, assuming it is a PID", id);
return List.of(dataverseClient.dataset(id));
List<Pair<String, DatasetApi>> getDatasets() throws IOException {
return new SingleDatasetOrDatasetsFile(id, dataverseClient).getDatasets().collect(Collectors.toList());

}

}
Loading

0 comments on commit 155959a

Please sign in to comment.