Commit 50754f54 authored by Matija Obreza's avatar Matija Obreza

Accession API: resetting some properties (collNumb) fails

parent 6e2ea87c
......@@ -124,6 +124,12 @@
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
......
......@@ -17,6 +17,8 @@ package org.genesys2.server.service.worker;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
......@@ -26,6 +28,7 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
import org.genesys2.server.api.PleaseRetryException;
import org.genesys2.server.api.model.AccessionHeaderJson;
import org.genesys2.server.exception.InvalidApiUsageException;
......@@ -64,6 +67,8 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.Iterators;
import javassist.util.proxy.Proxy;
/**
* The Class AccessionUploader.
*/
......@@ -245,14 +250,14 @@ public class AccessionUploader implements InitializingBean {
} else if (ArrayUtils.contains(ACCESSIONID_FIELDS, fieldName)) {
try {
copy(AccessionId.class, updateA.getAccessionId(), accession.getAccessionId(), Iterators.forArray(fieldName));
} catch (IllegalArgumentException | IllegalAccessException e) {
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
throw new InvalidApiUsageException(e.getMessage(), e);
}
} else {
try {
copy(Accession.class, updateA, accession, Iterators.forArray(fieldName));
} catch (IllegalArgumentException | IllegalAccessException e) {
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
throw new InvalidApiUsageException(e.getMessage(), e);
}
}
......@@ -349,10 +354,12 @@ public class AccessionUploader implements InitializingBean {
try {
copy(AccessionCollect.class, source, coll, jsonNode.fieldNames());
} catch (IllegalArgumentException | IllegalAccessException e) {
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
throw new InvalidApiUsageException(e.getMessage(), e);
}
updateAliases("collNumb", jsonNode.get("collNumb"), accession);
// removes empty
accession.setColl(coll.isEmpty() ? null : coll);
}
......@@ -366,7 +373,7 @@ public class AccessionUploader implements InitializingBean {
try {
copy(AccessionGeo.class, source, geo, jsonNode.fieldNames());
} catch (IllegalArgumentException | IllegalAccessException e) {
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
throw new InvalidApiUsageException(e.getMessage(), e);
}
......@@ -380,8 +387,10 @@ public class AccessionUploader implements InitializingBean {
if (remarks == null || remarks.isEmpty()) {
existing.clear();
} else {
List<AccessionRemark> toAdd = remarks.stream().filter(rem -> rem != null && ! rem.isEmpty()).filter(rem -> existing.stream().filter(ex -> rem.equalTo(ex)).count() == 0).collect(Collectors.toList());
List<AccessionRemark> toRemove = existing.stream().filter(ex -> ex == null || ex.isEmpty() || remarks.stream().filter(rem -> ex.equalTo(rem)).count() == 0).collect(Collectors.toList());
List<AccessionRemark> toAdd = remarks.stream().filter(rem -> rem != null && !rem.isEmpty()).filter(rem -> existing.stream().filter(ex -> rem.equalTo(ex))
.count() == 0).collect(Collectors.toList());
List<AccessionRemark> toRemove = existing.stream().filter(ex -> ex == null || ex.isEmpty() || remarks.stream().filter(rem -> ex.equalTo(rem)).count() == 0).collect(
Collectors.toList());
if (!toRemove.isEmpty() || !toAdd.isEmpty()) {
LOG.info("Removing: {} Adding: {}", toRemove, toAdd);
}
......@@ -399,32 +408,66 @@ public class AccessionUploader implements InitializingBean {
}
@SuppressWarnings({ "unchecked" })
private <T> void copy(Class<T> clazz, T source, T target, Iterator<String> fieldNames) throws IllegalArgumentException, IllegalAccessException {
private <T> void copy(Class<T> clazz, T source, T target, Iterator<String> fieldNames) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
String fieldName = null;
while (fieldNames.hasNext() && (fieldName = fieldNames.next()) != null) {
LOG.trace("Copying {}.{}", clazz.getName(), fieldName);
Field field = ReflectionUtils.findField(clazz, fieldName);
if (field != null) {
ReflectionUtils.makeAccessible(field);
ReflectionUtils.makeAccessible(field);
// Find getter for lazy-loading
Method getter = findGetter(target.getClass(), field.getType(), fieldName);
if (getter != null && field != null) {
final Object srcValue = field.get(source);
final Object dest = field.get(target);
final Object dest = getter.invoke(target);
// handle collections better
if (dest != null && dest instanceof Collection) {
Collection<Object> collection = (Collection<Object>) dest;
collection.clear();
if (srcValue != null && srcValue instanceof Collection) {
collection.addAll(((Collection<Object>) srcValue).stream().filter(o -> o != null).collect(Collectors.toList()));
LOG.trace("Reset {} to {}", fieldName, srcValue);
} else {
LOG.trace("Clearing {}, source was empty", fieldName);
LOG.trace("Cleared {}, source was empty", fieldName);
}
} else {
field.set(target, srcValue);
if (target instanceof Proxy) {
Method setter = findSetter(target.getClass(), field.getType(), fieldName);
setter.invoke(target, srcValue);
LOG.trace("Set {} to {}", fieldName, srcValue);
} else {
field.set(target, srcValue);
LOG.trace("Set {} to {}", fieldName, srcValue);
}
}
LOG.trace("Set {} to {}", fieldName, srcValue);
} else {
LOG.warn("No such field {}.{}", clazz.getName(), fieldName);
LOG.warn("No getter|setter for field {}.{}", clazz.getName(), fieldName);
}
}
}
private Method findGetter(Class<?> clazz, Class<?> returnType, String fieldName) {
String getterName = "get" + WordUtils.capitalize(fieldName);
LOG.trace("Looking for getter {}", getterName);
for (Method method : clazz.getMethods()) {
if (method.getParameterCount() == 0 && returnType.isAssignableFrom(method.getReturnType()) && method.getName().equals(getterName)) {
LOG.trace("Found getter {}", method);
return method;
}
}
throw new RuntimeException("No getter for field " + fieldName + " in " + clazz.getName());
}
private Method findSetter(Class<?> clazz, Class<?> parameterType, String fieldName) {
String setterName = "set" + WordUtils.capitalize(fieldName);
for (Method method : clazz.getMethods()) {
if (method.getParameterCount() == 1 && method.getParameterTypes()[0].isAssignableFrom(parameterType) && method.getName().equals(setterName)) {
LOG.trace("Found setter {}", method);
return method;
}
}
throw new RuntimeException("No setter for field " + fieldName + " in " + clazz.getName());
}
@Transactional(timeout = 250, isolation = Isolation.READ_UNCOMMITTED, rollbackFor = Throwable.class)
......
......@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.genesys.test.base.AbstractApiTest;
import org.genesys2.server.api.v0.AccessionController;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionAlias.AliasType;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.persistence.AccessionIdRepository;
import org.genesys2.server.persistence.AccessionRepository;
......@@ -155,6 +156,9 @@ public class AccessionControllerTest extends AbstractApiTest {
/*@formatter:on*/
assertThat(accessionRepository.count(), is(1L));
UUID uuid = accessionRepository.findAll().get(0).getUuid();
Accession result = fetch(uuid);
assertThat(result.getAccessionNumber(), is(accessionJson.get("accessionNumber").textValue()));
/*@formatter:off*/
upsert(accessionJson)
......@@ -203,7 +207,6 @@ public class AccessionControllerTest extends AbstractApiTest {
result = fetch(uuid);
assertThat(result.getAccessionId().getStorage().size(), is(0));
}
@Test
public void updateRemarks() throws Exception {
......@@ -211,8 +214,7 @@ public class AccessionControllerTest extends AbstractApiTest {
upsert(accessionJson);
assertThat(accessionRepository.count(), is(1L));
ArrayNode remarks = accessionJson.putArray("remarks");
remarks.add("SAMPSTAT: Cultivated. Relation to parent is unknown");
......@@ -238,19 +240,19 @@ public class AccessionControllerTest extends AbstractApiTest {
remarks.add("WEIRD:");
upsert(accessionJson);
result = fetch(uuid);
System.err.println(result.getAccessionId().getRemarks());
// System.err.println(result.getAccessionId().getRemarks());
assertThat(result.getAccessionId().getRemarks().size(), is(1));
assertThat(result.getAccessionId().getRemarks().get(0).getRemark(), is("WEIRD:"));
// Set blank remark
remarks.removeAll();
remarks.add("FAIL: ");
upsert(accessionJson);
result = fetch(uuid);
System.err.println(result.getAccessionId().getRemarks());
// System.err.println(result.getAccessionId().getRemarks());
assertThat(result.getAccessionId().getRemarks().size(), is(0));
}
@Test
public void testUpgradeToArray() throws Exception {
ObjectNode accessionJson = setUpAccession();
......@@ -268,14 +270,72 @@ public class AccessionControllerTest extends AbstractApiTest {
UUID uuid = accessionRepository.findAll().get(0).getUuid();
Accession result = fetch(uuid);
assertThat(result.getAccessionId().getBreederCode(), containsInAnyOrder("BREEDER1"));
accessionJson.set("breederCode", null);
upsert(accessionJson);
result = fetch(uuid);
assertThat("breederCode must be an empty array", result.getAccessionId().getBreederCode().size(), is(0));
}
@Test
public void testAliases() throws Exception {
ObjectNode accessionJson = setUpAccession();
upsert(accessionJson);
assertThat(accessionRepository.count(), is(1L));
accessionJson.put("acceName", "ACCENAME1");
/*@formatter:off*/
upsert(accessionJson)
.andExpect(jsonPath("$[0].result.action", equalTo("UPDATE")));
/*@formatter:on*/
assertThat(accessionRepository.count(), is(1L));
UUID uuid = accessionRepository.findAll().get(0).getUuid();
Accession result = fetch(uuid);
assertThat(result.getAccessionId().getAliases().size(), is(1));
assertThat(result.getAccessionId().getAliases().get(0).getName(), is("ACCENAME1"));
assertThat(result.getAccessionId().getAliases().get(0).getAliasType(), is(AliasType.ACCENAME));
accessionJson.set("acceName", null);
upsert(accessionJson);
result = fetch(uuid);
assertThat("acceName must be an empty array", result.getAccessionId().getAliases().size(), is(0));
}
@Test
public void testCollNumb() throws Exception {
ObjectNode accessionJson = setUpAccession();
upsert(accessionJson);
assertThat(accessionRepository.count(), is(1L));
ObjectNode coll = accessionJson.putObject("coll");
coll.put("collNumb", "COLLNAME1");
/*@formatter:off*/
upsert(accessionJson)
.andExpect(jsonPath("$[0].result.action", equalTo("UPDATE")));
/*@formatter:on*/
assertThat(accessionRepository.count(), is(1L));
UUID uuid = accessionRepository.findAll().get(0).getUuid();
Accession result = fetch(uuid);
assertThat(result.getAccessionId().getColl().getCollNumb(), is("COLLNAME1"));
assertThat(result.getAccessionId().getAliases().size(), is(1));
assertThat(result.getAccessionId().getAliases().get(0).getName(), is("COLLNAME1"));
assertThat(result.getAccessionId().getAliases().get(0).getAliasType(), is(AliasType.COLLNUMB));
coll.set("collNumb", null);
LOG.debug("Push JSON\n{}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(accessionJson));
upsert(accessionJson);
result = fetch(uuid);
LOG.debug("Response JSON\n{}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(result));
assertThat("coll must be null", result.getAccessionId().getColl(), nullValue());
assertThat("coll.collNumb must be an empty array", result.getAccessionId().getAliases().size(), is(0));
}
private ResultActions upsert(ObjectNode accessionJson) throws Exception, JsonProcessingException {
LOG.debug("Upsering {}", verboseMapper.writerWithDefaultPrettyPrinter().writeValueAsString(accessionJson));
/*@formatter:off*/
return mockMvc.perform(post(AccessionController.API_BASE + "/" + institute.getCode() + "/upsert")
.contentType(MediaType.APPLICATION_JSON)
......
......@@ -32,6 +32,8 @@ log4j.rootLogger=warn, stdout
#log4j.category.org.genesys2=info
log4j.category.org.genesys.blocks.security=error
log4j.category.org.genesys2.server=warn
#log4j.category.org.genesys.test=debug
#log4j.category.org.genesys2.server.service.worker.AccessionUploader=trace
#log4j.category.org.genesys2.server.service.worker.AccessionCounter=trace
#log4j.category.org.hibernate.cache=debug
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment