Commit 1d8479c9 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Customized Jackson configuration for JobInfo class; Added tests

parent af27a456
target/**
/nbproject/
......@@ -29,5 +29,50 @@
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package it.inaf.oats.vospace.datamodel;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.util.Map;
import net.ivoa.xml.uws.v1.JobSummary.JobInfo;
import net.ivoa.xml.vospace.v2.Transfer;
public class JobInfoDeserializer extends StdDeserializer<JobInfo> {
private static final ObjectMapper MAPPER = new ObjectMapper();
public JobInfoDeserializer() {
super(JobInfo.class);
}
@Override
public JobInfo deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
Object content = jp.getCodec().readValue(jp, Object.class);
if (content == null) {
return null;
}
if (!(content instanceof Map)) {
throw new UnsupportedOperationException("JobInfo contains an instance of " + content.getClass().getCanonicalName());
}
Map<String, Object> map = (Map<String, Object>) content;
if (map.isEmpty()) {
return null;
}
if (map.keySet().size() > 1) {
throw new UnsupportedOperationException("Multiple keys found in JobInfo content");
}
String name = map.keySet().toArray(String[]::new)[0];
JobInfo jobInfo = new JobInfo();
switch (name) {
case "transfer":
String transferJson = MAPPER.writeValueAsString(map.get(name));
Transfer transfer = MAPPER.readValue(transferJson, Transfer.class);
jobInfo.getAny().add(transfer);
break;
default:
throw new UnsupportedOperationException("JobInfo map key is " + name);
}
return jobInfo;
}
}
package it.inaf.oats.vospace.datamodel;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.ivoa.xml.uws.v1.JobSummary.JobInfo;
public class JobInfoSerializer extends StdSerializer<JobInfo> {
public JobInfoSerializer() {
super(JobInfo.class);
}
@Override
public void serialize(JobInfo jobInfo, JsonGenerator jg, SerializerProvider sp) throws IOException {
List<Object> any = jobInfo.getAny();
if (any == null || any.isEmpty()) {
jg.getCodec().writeValue(jg, null);
return;
}
if (jobInfo.getAny().size() == 1) {
Object content = jobInfo.getAny().get(0);
Map<String, Object> map = new HashMap<>();
String name = content.getClass().getSimpleName().toLowerCase();
map.put(name, content);
jg.getCodec().writeValue(jg, map);
} else {
jg.getCodec().writeValue(jg, jobInfo.getAny());
}
}
}
......@@ -8,6 +8,10 @@
package net.ivoa.xml.uws.v1;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import it.inaf.oats.vospace.datamodel.JobInfoDeserializer;
import it.inaf.oats.vospace.datamodel.JobInfoSerializer;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
......@@ -17,9 +21,12 @@ import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;
import net.ivoa.xml.vospace.v2.Transfer;
import org.w3c.dom.Element;
......@@ -87,6 +94,8 @@ import org.w3c.dom.Element;
"errorSummary",
"jobInfo"
})
@XmlSeeAlso({Transfer.class}) // Necessary for setting a Transfer inside the jobInfo property.
@XmlRootElement(name = "job")
public class JobSummary {
@XmlElement(required = true)
......@@ -501,6 +510,8 @@ public class JobSummary {
@XmlType(name = "", propOrder = {
"any"
})
@JsonSerialize(using = JobInfoSerializer.class)
@JsonDeserialize(using = JobInfoDeserializer.class)
public static class JobInfo {
@XmlAnyElement(lax = true)
......
......@@ -5,5 +5,16 @@
// Generated on: 2020.10.24 at 09:39:16 AM CEST
//
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ivoa.net/xml/UWS/v1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://www.ivoa.net/xml/UWS/v1.0",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
// Defining the namespace prefix is necessary otherwise
// deserialized XML will have no prefixes
xmlns = {
@javax.xml.bind.annotation.XmlNs(
namespaceURI = "http://www.ivoa.net/xml/UWS/v1.0",
prefix = "uws"
)
}
)
package net.ivoa.xml.uws.v1;
package net.ivoa.xml.uws.v1;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXB;
import net.ivoa.xml.uws.v1.JobSummary.JobInfo;
import net.ivoa.xml.vospace.v2.Protocol;
import net.ivoa.xml.vospace.v2.Transfer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class JobSummaryTest {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Test
public void testXmlSerialization() throws Exception {
JobSummary job = getJobSummary();
String xml;
try ( StringWriter sw = new StringWriter()) {
JAXB.marshal(job, sw);
xml = sw.toString();
System.out.println(xml);
}
assertTrue(xml.contains("<uws:job"));
assertTrue(xml.contains("<uws:jobInfo"));
assertTrue(xml.contains("<vos:transfer"));
try ( StringReader sr = new StringReader(xml)) {
JobSummary deserialized = JAXB.unmarshal(sr, JobSummary.class);
verifyJobsAreEquals(deserialized);
}
}
@Test
public void testJsonSerialization() throws Exception {
JobSummary job = getJobSummary();
String json = MAPPER.writeValueAsString(job);
System.out.println(json);
JobSummary deserialized = MAPPER.readValue(json, JobSummary.class);
verifyJobsAreEquals(deserialized);
}
private JobSummary getJobSummary() {
JobSummary job = new JobSummary();
job.setJobId("job_id");
job.setPhase(ExecutionPhase.PENDING);
JobInfo jobInfo = new JobInfo();
Transfer transfer = new Transfer();
transfer.setVersion("2.1");
transfer.setTarget("vos://example.com!vospace/mydata1");
transfer.setDirection("pullFromVoSpace");
Protocol protocol = new Protocol();
protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
transfer.getProtocol().add(protocol);
jobInfo.getAny().add(transfer);
job.setJobInfo(jobInfo);
return job;
}
private void verifyJobsAreEquals(JobSummary deserializedJob) {
assertEquals("job_id", deserializedJob.getJobId());
assertEquals(ExecutionPhase.PENDING, deserializedJob.getPhase());
Transfer transfer = (Transfer) deserializedJob.getJobInfo().getAny().get(0);
assertEquals("2.1", transfer.getVersion());
assertEquals("pullFromVoSpace", transfer.getDirection());
assertEquals("vos://example.com!vospace/mydata1", transfer.getTarget());
Protocol protocol = transfer.getProtocol().get(0);
assertEquals("ivo://ivoa.net/vospace/core#httpget", protocol.getUri());
}
}
Supports Markdown
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