Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REP-45 Add option to delete replication data through UI #60

Merged
merged 9 commits into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions admin/query/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,17 @@
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.71</minimum>
<minimum>0.75</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.68</minimum>
<minimum>0.74</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.58</minimum>
<minimum>0.61</minimum>
</limit>
</limits>
</rule>
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 @@ -71,12 +76,7 @@ public boolean siteExists(String name) {
}

public boolean siteIdExists(String id) {
try {
siteManager.get(id);
return true;
} catch (NotFoundException e) {
return false;
}
return siteManager.exists(id);
}

public ReplicationSiteField updateSite(String id, String name, AddressField address) {
Expand Down Expand Up @@ -109,7 +109,7 @@ public boolean replicationConfigExists(String name) {
}

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

public ReplicationField createReplication(
Expand Down Expand Up @@ -215,12 +215,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 @@ -253,9 +262,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 @@ -29,24 +29,32 @@ 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 and its history (statistics). 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;
}
Expand All @@ -70,7 +78,7 @@ public BooleanField getReturnType() {

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

@Override
Expand Down
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(true);
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.shouldDeleteData(), 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 Expand Up @@ -393,7 +416,7 @@ public void enableConfig() {

@Test
public void siteIdExists() {
when(siteManager.get(anyString())).thenReturn(new ReplicationSiteImpl());
when(siteManager.exists(anyString())).thenReturn(true);
assertThat(utils.siteIdExists("id"), 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";

private DeleteReplication deleteReplication;

private 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);
}
}
6 changes: 3 additions & 3 deletions replication-api-impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,17 @@
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.54</minimum>
<minimum>0.57</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.44</minimum>
<minimum>0.49</minimum>
</limit>
<limit implementation="org.codice.jacoco.LenientLimit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.47</minimum>
<minimum>0.52</minimum>
</limit>
</limits>
</rule>
Expand Down
Loading