gcube-cms-suite/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/SingleISResourceUCDProvider...

149 lines
5.2 KiB
Java

package org.gcube.application.geoportal.service.engine.providers.ucd;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.caches.AbstractScopedMap;
import org.gcube.application.cms.implementations.ISInterface;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.common.resources.gcore.GenericResource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.GenericArrayType;
import java.net.URL;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Scanner;
/**
* Retrieves available UCDs from a single Generic Resource
* - secondary Type : "CMS"
* - name : "UCDs"
*
* containing e.g.
* <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
* <UCDs>
* <record label="Human readable name" ucdUrl="some url" defaultForRegex="[opt] regex"/>
* <record label="Another readable name" ucdUrl="some other url" defaultForRegex="[opt] regex"/>
* </UCDs>
*
*/
@Slf4j
public class SingleISResourceUCDProvider extends AbstractScopedMap<ProfileMap> {
public SingleISResourceUCDProvider() {
super("Single IS Resource UCD Provider");
setTTL(Duration.of(2, ChronoUnit.MINUTES));
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "UCDs")
@Data
@EqualsAndHashCode
public static class ISBean {
@NoArgsConstructor
@ToString
@Getter
@Setter
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@EqualsAndHashCode
public static class Record {
@XmlAttribute
private String label;
@XmlAttribute
private String ucdUrl;
@XmlAttribute
private String defaultForRegex;
}
@XmlElement(name = "record")
private List<Record> records;
}
@Override
public void init() {
super.init();
try{
directInit();
}catch(Throwable t){
throw new RuntimeException("Unable to initialize. Can't read Use case descriptors ",t);
}
}
static void directInit() throws JAXBException {
jaxbContext = JAXBContext.newInstance(ISBean.class);
marshaller = jaxbContext.createMarshaller();
unmarshaller = jaxbContext.createUnmarshaller();
}
private static JAXBContext jaxbContext=null;
private static Marshaller marshaller=null;
private static Unmarshaller unmarshaller = null;
static ISBean read(String xml) throws JAXBException {
log.trace("Loading from xml {}",xml);
return (ISBean) unmarshaller.unmarshal(new StringReader(xml));
}
static String write(ISBean obj) throws JAXBException {
log.trace("Writing {} to xml",obj);
StringWriter writer = new StringWriter();
marshaller.marshal(obj,writer);
writer.flush();
return writer.toString();
}
@Override
protected ProfileMap retrieveObject(String key) throws ConfigurationException {
try {
log.info("Loading UCDs for context {} ",key);
ISInterface is = ImplementationProvider.get().getEngineByManagedClass(ISInterface.class);
List<GenericResource> l = is.getGenericResource("CMS","UCDs");
log.debug("Found {} resources ",l.size());
ProfileMap toReturn = new ProfileMap();
l.forEach(g->{
try {
log.debug("Reading from ID {} ", g.id());
ISBean bean = read(g.profile().bodyAsString());
log.debug("Found {} records ", bean.getRecords().size());
int before = toReturn.size();
bean.getRecords().forEach(record -> {
try {
log.debug("Loading UCD From {} ", record);
String json = new Scanner(
new URL(record.getUcdUrl()).openStream(),
"UTF-8").useDelimiter("\\A").next();
log.trace("JSON IS {} ",json);
UseCaseDescriptor ucd = Serialization.read(json, UseCaseDescriptor.class);
toReturn.put(ucd.getId(), ucd);
}catch (Throwable t){
log.warn("Unable to read record {} from GR ID {} ",record,g.id(),t);
}
});
log.debug("Loaded {} from {} ",toReturn.size()-before,g.id());
}catch (Throwable t){
log.warn("Unable to read from GR {} ",g.id(),t);
}
});
return toReturn;
}catch(Throwable t){
throw new ConfigurationException("Unable to load UCDs for "+key,t);
}
}
}