/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.listener.s3;
import java.io.StringWriter;
import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.orcid.jaxb.model.error_v2.OrcidError;
import org.orcid.jaxb.model.message.OrcidDeprecated;
import org.orcid.jaxb.model.message.OrcidMessage;
import org.orcid.jaxb.model.record_v2.Record;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
@Component
public class S3Updater {
Logger LOG = LoggerFactory.getLogger(S3Updater.class);
private final ObjectMapper mapper;
private final String bucketPrefix;
private final JAXBContext jaxbContext_1_2_api;
private final JAXBContext jaxbContext_2_0_api;
@Resource
private S3MessagingService s3MessagingService;
public void setS3MessagingService(S3MessagingService s3MessagingService) {
this.s3MessagingService = s3MessagingService;
}
/**
* Writes a profile to S3
*
* @param writeToFileNotS3
* if true, write to local file system temp directory instead of
* S3
* @throws JAXBException
*/
@Autowired
public S3Updater(@Value("${org.orcid.message-listener.s3.bucket_prefix}") String bucketPrefix)
throws JAXBException {
mapper = new ObjectMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
this.bucketPrefix = bucketPrefix;
//Initialize JAXBContext
this.jaxbContext_1_2_api = JAXBContext.newInstance(OrcidMessage.class, OrcidDeprecated.class);
this.jaxbContext_2_0_api = JAXBContext.newInstance(Record.class, OrcidError.class);
}
public void updateS3(String orcid, Object object) throws JsonProcessingException, AmazonClientException, JAXBException {
// API 1.2
if(OrcidMessage.class.isAssignableFrom(object.getClass())) {
OrcidMessage orcidProfile = (OrcidMessage) object;
putJsonElement(orcid, orcidProfile);
putXmlElement(orcid, orcidProfile);
return;
}
// API 1.2 ERROR
if(OrcidDeprecated.class.isAssignableFrom(object.getClass())) {
OrcidDeprecated error = (OrcidDeprecated) object;
putJsonElement(orcid, error);
putXmlElement(orcid, error);
return;
}
// API 2.0_v2
if(Record.class.isAssignableFrom(object.getClass())) {
Record record = (Record) object;
putJsonElement(orcid, record);
putXmlElement(orcid, record);
return;
}
// API 2.0 Error
if(OrcidError.class.isAssignableFrom(object.getClass())) {
OrcidError error = (OrcidError) object;
putJsonElement(orcid, error);
putXmlElement(orcid, error);
return;
}
}
private void putJsonElement(String orcid, OrcidMessage profile) throws JsonProcessingException {
try {
String bucket = bucketPrefix + "-api-1-2-json-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".json", toJson(profile));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putXmlElement(String orcid, OrcidMessage profile) throws AmazonClientException, JAXBException {
try {
String bucket = bucketPrefix + "-api-1-2-xml-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".xml", toXML(profile));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putJsonElement(String orcid, OrcidDeprecated error) throws JsonProcessingException {
try {
String bucket = bucketPrefix + "-api-1-2-json-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".json", toJson(error));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putXmlElement(String orcid, OrcidDeprecated error) throws AmazonClientException, JAXBException {
try {
String bucket = bucketPrefix + "-api-1-2-xml-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".xml", toXML(error));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putJsonElement(String orcid, Record record) throws JsonProcessingException {
try {
String bucket = bucketPrefix + "-api-2-0-json-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".json", toJson(record));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putXmlElement(String orcid, Record record) throws AmazonClientException, JAXBException {
try {
String bucket = bucketPrefix + "-api-2-0-xml-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".xml", toXML(record));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putJsonElement(String orcid, OrcidError error) throws JsonProcessingException {
try {
String bucket = bucketPrefix + "-api-2-0-json-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".json", toJson(error));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private void putXmlElement(String orcid, OrcidError error) throws AmazonClientException, JAXBException {
try {
String bucket = bucketPrefix + "-api-2-0-xml-" + getBucketCheckSum(orcid);
s3MessagingService.send(bucket, orcid + ".xml", toXML(error));
} catch (AmazonServiceException e) {
LOG.error(e.getMessage());
}
}
private String toJson(Object profile) throws JsonProcessingException {
return mapper.writeValueAsString(profile);
}
private String toXML(Object object) throws JAXBException {
StringWriter sw = new StringWriter();
Marshaller marshaller = null;
if (OrcidMessage.class.isAssignableFrom(object.getClass()) || OrcidDeprecated.class.isAssignableFrom(object.getClass())) {
marshaller = jaxbContext_1_2_api.createMarshaller();
} else if (Record.class.isAssignableFrom(object.getClass()) || OrcidError.class.isAssignableFrom(object.getClass())) {
marshaller = jaxbContext_2_0_api.createMarshaller();
} else {
throw new IllegalArgumentException("Unable to unmarshall class " + object.getClass());
}
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(object, sw);
return sw.toString();
}
public String getBucketCheckSum(String orcid) {
if(bucketPrefix.endsWith("-qa") || bucketPrefix.endsWith("-sandbox")) {
return "all";
} else {
String c = String.valueOf(orcid.charAt(orcid.length() - 1));
if("X".equals(c)){
c = "x";
}
return c;
}
}
}