Skip to content

Commit

Permalink
REP-45 Add option to delete replication data through UI
Browse files Browse the repository at this point in the history
  • Loading branch information
peterhuffer committed Mar 27, 2019
1 parent f017cb0 commit 65c3768
Show file tree
Hide file tree
Showing 58 changed files with 1,234 additions and 155 deletions.
2 changes: 1 addition & 1 deletion admin/query/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.71</minimum>
<minimum>0.72</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>BRANCH</counter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.codice.ditto.replication.admin.query.replications.fields.ReplicationField;
import org.codice.ditto.replication.admin.query.sites.fields.ReplicationSiteField;
import org.codice.ditto.replication.api.ReplicationException;
import org.codice.ditto.replication.api.ReplicationPersistenceException;
import org.codice.ditto.replication.api.ReplicationStatus;
import org.codice.ditto.replication.api.Replicator;
import org.codice.ditto.replication.api.ReplicatorHistory;
Expand All @@ -32,10 +33,14 @@
import org.codice.ditto.replication.api.data.ReplicatorConfig;
import org.codice.ditto.replication.api.persistence.ReplicatorConfigManager;
import org.codice.ditto.replication.api.persistence.SiteManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Utility class that does all the heavy lifting for the graphql operations */
public class ReplicationUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(ReplicationUtils.class);

private static final long BYTES_PER_MB = 1024L * 1024L;

private final SiteManager siteManager;
Expand Down Expand Up @@ -105,7 +110,11 @@ public boolean deleteSite(String id) {
}

public boolean replicationConfigExists(String name) {
return configManager.objects().map(ReplicatorConfig::getName).anyMatch(name::equals);
return configManager.objects().map(ReplicatorConfig::getName).anyMatch(name::equalsIgnoreCase);
}

public boolean configExists(String id) {
return configManager.configExists(id);
}

public ReplicationField createReplication(
Expand Down Expand Up @@ -211,12 +220,21 @@ private ReplicationField getReplicationFieldForConfig(ReplicatorConfig config) {
return field;
}

public boolean deleteConfig(String id) {
public boolean markConfigDeleted(String id, boolean deleteData) {
try {
configManager.remove(id);
ReplicatorConfig config = configManager.get(id);
config.setDeleted(true);
config.setDeleteData(deleteData);
config.setSuspended(true);
configManager.save(config);
replicator.cancelSyncRequest(id);
return true;
} catch (NotFoundException e) {
} catch (ReplicationPersistenceException e) {
LOGGER.debug("Unable to delete replicator configuration with id {}", id, e);
return false;
} catch (NotFoundException e) {
LOGGER.debug("Config with id {}", id, e);
return true;
}
}

Expand Down Expand Up @@ -249,9 +267,18 @@ public ListField<ReplicationSiteField> getSites() {
return siteFields;
}

public ListField<ReplicationField> getReplications() {
public ListField<ReplicationField> getReplications(boolean filterDeleted) {
ListField<ReplicationField> fields = new ReplicationField.ListImpl();
configManager.objects().map(this::getReplicationFieldForConfig).forEach(fields::add);

if (filterDeleted) {
configManager
.objects()
.filter(c -> !c.isDeleted())
.map(this::getReplicationFieldForConfig)
.forEach(fields::add);
} else {
configManager.objects().map(this::getReplicationFieldForConfig).forEach(fields::add);
}
return fields;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public GetReplications(ReplicationUtils replicationUtils) {

@Override
public ListField<ReplicationField> performFunction() {
return replicationUtils.getReplications();
return replicationUtils.getReplications(true);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,63 @@
import org.codice.ddf.admin.common.fields.base.BaseFunctionField;
import org.codice.ddf.admin.common.fields.base.scalar.BooleanField;
import org.codice.ddf.admin.common.fields.common.PidField;
import org.codice.ditto.replication.admin.query.ReplicationMessages;
import org.codice.ditto.replication.admin.query.ReplicationUtils;

public class DeleteReplication extends BaseFunctionField<BooleanField> {

public static final String FIELD_NAME = "deleteReplication";

public static final String DESCRIPTION = "Deletes a replication.";
public static final String DESCRIPTION =
"Deletes a Replication. Optionally delete the data of the Replication. Deleting data will delete "
+ "any local resources and metadata that were replicated by this Replication, but not any resources replicated to a remote Node.";

public static final BooleanField RETURN_TYPE = new BooleanField();

private PidField id;

private BooleanField deleteData;

private ReplicationUtils replicationUtils;

public DeleteReplication(ReplicationUtils replicationUtils) {
super(FIELD_NAME, DESCRIPTION);
this.replicationUtils = replicationUtils;
id = new PidField("id");
deleteData = new BooleanField("deleteData");
deleteData.setValue(false);

id.isRequired();
}

@Override
public BooleanField performFunction() {
BooleanField successful = new BooleanField();
successful.setValue(replicationUtils.deleteConfig(id.getValue()));
successful.setValue(replicationUtils.markConfigDeleted(id.getValue(), deleteData.getValue()));

return successful;
}

@Override
public void validate() {
super.validate();
if (containsErrorMsgs()) {
return;
}

if (!replicationUtils.configExists(id.getValue())) {
addErrorMessage(ReplicationMessages.configDoesNotExist());
}
}

@Override
public BooleanField getReturnType() {
return RETURN_TYPE;
}

@Override
public List<Field> getArguments() {
return ImmutableList.of(id);
return ImmutableList.of(id, deleteData);
}

@Override
Expand All @@ -67,6 +88,6 @@ public FunctionField<BooleanField> newInstance() {

@Override
public Set<String> getFunctionErrorCodes() {
return ImmutableSet.of();
return ImmutableSet.of(ReplicationMessages.CONFIG_DOES_NOT_EXIST);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void validate() {
return;
}

ListField<ReplicationField> repFields = replicationUtils.getReplications();
ListField<ReplicationField> repFields = replicationUtils.getReplications(false);
String idToDelete = id.getValue();
for (ReplicationField repField : repFields.getList()) {
if (idToDelete.equals(repField.source().id())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.codice.ditto.replication.admin.query.replications.fields.ReplicationField;
import org.codice.ditto.replication.admin.query.sites.fields.ReplicationSiteField;
import org.codice.ditto.replication.api.ReplicationException;
import org.codice.ditto.replication.api.ReplicationPersistenceException;
import org.codice.ditto.replication.api.ReplicationStatus;
import org.codice.ditto.replication.api.Replicator;
import org.codice.ditto.replication.api.ReplicatorHistory;
Expand All @@ -54,7 +55,7 @@
@RunWith(MockitoJUnitRunner.class)
public class ReplicationUtilsTest {

ReplicationUtils utils;
private ReplicationUtils utils;

@Mock SiteManager siteManager;

Expand Down Expand Up @@ -292,18 +293,31 @@ public void updateReplicationActiveSyncRequest() {
}

@Test
public void deleteConfig() {
public void testMarkConfigDeleted() {
ReplicatorConfigImpl config = new ReplicatorConfigImpl();
config.setId("id");
config.setName("name");
assertThat(utils.deleteConfig("id"), is(true));
verify(configManager).remove(anyString());

when(configManager.get("id")).thenReturn(config);

assertThat(utils.markConfigDeleted("id", true), is(true));
assertThat(config.deleteData(), is(true));
assertThat(config.isDeleted(), is(true));
assertThat(config.isSuspended(), is(true));
verify(replicator).cancelSyncRequest("id");
verify(configManager).save(config);
}

@Test
public void testMarkConfigDeletedNotFound() {
doThrow(new NotFoundException()).when(configManager).get("id");
assertThat(utils.markConfigDeleted("id", true), is(true));
}

@Test
public void deleteConfigFailed() {
doThrow(new NotFoundException()).when(configManager).remove(anyString());
assertThat(utils.deleteConfig("id"), is(false));
public void testMarkConfigDeletedErrorRetrievingConfig() {
doThrow(new ReplicationPersistenceException("")).when(configManager).get("id");
assertThat(utils.markConfigDeleted("id", true), is(false));
}

@Test
Expand Down Expand Up @@ -336,7 +350,7 @@ public void getReplications() throws Exception {
config.setDestination("destId");
config.setBidirectional(false);
when(configManager.objects()).thenReturn(Stream.of(config));
ReplicationField field = utils.getReplications().getList().get(0);
ReplicationField field = utils.getReplications(false).getList().get(0);
assertThat(field.name(), is("test"));
assertThat(field.source().id(), is("srcId"));
assertThat(field.destination().id(), is("destId"));
Expand All @@ -346,6 +360,15 @@ public void getReplications() throws Exception {
assertThat(field.dataTransferred(), is("15 MB"));
}

@Test
public void testGetReplicationsFilterDeleted() {
ReplicatorConfigImpl config = new ReplicatorConfigImpl();
config.setDeleted(true);

when(configManager.objects()).thenReturn(Stream.of(config));
assertThat(utils.getReplications(true).getList().size(), is(0));
}

@Test
public void cancelConfig() {
assertThat(utils.cancelConfig("test"), is(true));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright (c) Connexta
*
* <p>This is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or any later version.
*
* <p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public
* License is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ditto.replication.admin.query.replications.persist;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.codice.ddf.admin.api.report.ErrorMessage;
import org.codice.ddf.admin.api.report.FunctionReport;
import org.codice.ditto.replication.admin.query.ReplicationMessages;
import org.codice.ditto.replication.admin.query.ReplicationUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class DeleteReplicationTest {

private static final String ID = "abc123";

DeleteReplication deleteReplication;

Map<String, Object> args;

@Mock ReplicationUtils utils;

@Before
public void setup() {
deleteReplication = new DeleteReplication(utils);
args = new HashMap<>();
args.put("id", ID);
}

@Test
public void testValidateNoConfig() {
when(utils.configExists(ID)).thenReturn(false);
FunctionReport report =
deleteReplication.execute(args, Collections.singletonList(DeleteReplication.FIELD_NAME));
assertThat(report.getErrorMessages().size(), is(1));
assertThat(
((ErrorMessage) report.getErrorMessages().get(0)).getCode(),
is(ReplicationMessages.CONFIG_DOES_NOT_EXIST));
}

@Test
public void testGetFunctionErrorCodes() {
assertThat(
deleteReplication
.getFunctionErrorCodes()
.contains(ReplicationMessages.CONFIG_DOES_NOT_EXIST),
is(true));
}

@Test
public void testDeleteDataArgDefaultsToFalse() {
when(utils.configExists(ID)).thenReturn(true);
FunctionReport report =
deleteReplication.execute(args, Collections.singletonList(DeleteReplication.FIELD_NAME));
assertThat(report.getErrorMessages().size(), is(0));
verify(utils, times(1)).markConfigDeleted(ID, false);
}
}
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
<maven-checkstyle-plugin.version>3.0.0</maven-checkstyle-plugin.version>
<maven-jacoco-plugin.version>0.8.2</maven-jacoco-plugin.version>

<project.report.output.directory>project-info</project.report.output.directory>

<!-- documentation replacements -->
<platform>DDF Base</platform>
<admin-console>Admin Console</admin-console>
Expand Down
4 changes: 2 additions & 2 deletions replication-api-impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,12 @@
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.54</minimum>
<minimum>0.49</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.44</minimum>
<minimum>0.40</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>COMPLEXITY</counter>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading

0 comments on commit 65c3768

Please sign in to comment.