dnet-core/dnet-modular-ui/src/main/java/eu/dnetlib/functionality/modular/ui/is/InformationServiceInternalC...

308 lines
12 KiB
Java

package eu.dnetlib.functionality.modular.ui.is;
import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.xml.transform.dom.DOMResult;
import javax.xml.xpath.XPathFactory;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.is.sn.SubscriptionRegistry;
import eu.dnetlib.enabling.is.sn.resourcestate.ResourceStateSubscription;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.functionality.modular.ui.AbstractAjaxController;
import eu.dnetlib.functionality.modular.ui.is.bulk.ProfileImporter;
import eu.dnetlib.functionality.modular.ui.is.objects.*;
import eu.dnetlib.functionality.modular.ui.is.objects.ServiceDesc.ServiceStatus;
import eu.dnetlib.miscutils.datetime.DateUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class InformationServiceInternalController extends AbstractAjaxController {
@Resource
private UniqueServiceLocator serviceLocator;
@Resource(name = "modularUiProfileImporter")
private ProfileImporter profileImporter;
/**
* is sn subscription registries.
*/
@Resource(name = "issResourceStateNotificationRegistry")
private transient SubscriptionRegistry registry;
private static final Log log = LogFactory.getLog(InformationServiceInternalController.class);
@RequestMapping("/ui/is/xquery.do")
public @ResponseBody
List<String> query(@RequestParam(value = "query", required = true) final String query) throws Exception {
log.debug("Executing xquery: " + query);
return serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query);
}
@RequestMapping("/ui/is/listSchemas.do")
public @ResponseBody
List<String> listSchemas() throws Exception {
return serviceLocator.getService(ISLookUpService.class).listResourceTypes();
}
@RequestMapping("/ui/is/getSchema.do")
public @ResponseBody
String getSchema(@RequestParam(value = "name", required = true) final String name) throws Exception {
return serviceLocator.getService(ISLookUpService.class).getResourceTypeSchema(name);
}
@RequestMapping("/ui/is/listCollections.do")
public @ResponseBody
List<CollectionDesc> listCollections() throws Exception {
final String xquery = "for $kind in xmldb:get-child-collections('/db/DRIVER') " +
"for $type in xmldb:get-child-collections(concat('/db/DRIVER/', $kind)) " +
"return concat ($kind, ' @@@ ', $type, ' @@@ ', count(xmldb:get-child-resources(concat('/db/DRIVER/', $kind, '/', $type))))";
final Map<String, CollectionDesc> map = Maps.newHashMap();
for (String s : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xquery)) {
final String[] arr = s.split("@@@");
final String kind = arr[0].trim();
final String type = arr[1].trim();
final int size = NumberUtils.toInt(arr[2].trim(), 0);
if (!map.containsKey(kind)) {
map.put(kind, new CollectionDesc(kind));
}
map.get(kind).addType(type, size);
}
final List<CollectionDesc> res = Lists.newArrayList(map.values());
for (CollectionDesc d : res) {
Collections.sort(d.getTypes());
}
Collections.sort(res);
return res;
}
@RequestMapping("/ui/is/listProfiles.do")
public @ResponseBody
List<String> listProfiles(@RequestParam(value = "kind", required = true) final String kind,
@RequestParam(value = "type", required = true) final String type) throws Exception {
final String collName = "/db/DRIVER/" + kind + "/" + type;
final String xquery = "distinct-values(for $x in collection('" + collName + "') return $x//RESOURCE_IDENTIFIER/@value/string())";
final List<String> res = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xquery);
Collections.sort(res);
return res;
}
@RequestMapping("/ui/is/getProfile.do")
public @ResponseBody
String getProfiles(@RequestParam(value = "id", required = true) final String id) throws Exception {
return serviceLocator.getService(ISLookUpService.class).getResourceProfile(id);
}
@RequestMapping("/ui/is/registerProfile.do")
public @ResponseBody
String registerProfile(@RequestParam(value = "profile", required = true) final String profile) throws Exception {
return serviceLocator.getService(ISRegistryService.class).registerProfile(profile);
}
@RequestMapping("/ui/is/updateProfile.do")
public @ResponseBody
String updateProfile(@RequestParam(value = "profile", required = true) final String profile) throws Exception {
final SAXReader reader = new SAXReader();
final Document doc = reader.read(new StringReader(profile));
final String id = doc.valueOf("//RESOURCE_IDENTIFIER/@value");
final String type = doc.valueOf("//RESOURCE_TYPE/@value");
if (StringUtils.isEmpty(id)) {
throw new Exception("RESOURCE_IDENTIFIER is empty");
} else if (StringUtils.isEmpty(type)) {
throw new Exception("RESOURCE_TYPE is empty");
} else if (serviceLocator.getService(ISRegistryService.class).updateProfile(id, profile, type)) {
return id;
} else {
throw new Exception("Profile not updated");
}
}
@RequestMapping("/ui/is/deleteProfile.do")
public @ResponseBody
boolean deleteProfile(@RequestParam(value = "id", required = true) final String id) throws Exception {
return serviceLocator.getService(ISRegistryService.class).deleteProfile(id);
}
@RequestMapping("/ui/is/import.do")
public @ResponseBody
Map<String, Integer> importProfiles(
@RequestParam(value = "path", required = true) final String path,
@RequestParam(value = "profiles", required = true) final boolean profiles,
@RequestParam(value = "schemas", required = true) final boolean schemas) throws Exception {
log.info("importing profiles/schemas from " + path);
final Map<String, Integer> res = Maps.newHashMap();
if (schemas) {
res.putAll(profileImporter.importSchemas(path + "/**/*.xsd"));
}
if (profiles) {
res.putAll(profileImporter.importProfiles(path + "/**/*.xml"));
}
return res;
}
@RequestMapping("/ui/is/listBlackboards.do")
public @ResponseBody
List<BlackboardMessage> listBlackboards() throws Exception {
final List<BlackboardMessage> list = Lists.newArrayList();
final SAXReader reader = new SAXReader();
for (String xml : serviceLocator
.getService(ISLookUpService.class)
.quickSearchProfile(
"for $x in collection('/db/DRIVER/ServiceResources')//MESSAGE return <message>{$x/../../..//RESOURCE_TYPE}{$x/../../..//RESOURCE_IDENTIFIER}{$x}</message>")) {
final BlackboardMessage info = new BlackboardMessage();
final Document doc = reader.read(new StringReader(xml));
info.setProfId(doc.valueOf(".//RESOURCE_IDENTIFIER/@value"));
info.setMessageId(doc.valueOf(".//@id"));
info.setResourceType(doc.valueOf(".//RESOURCE_TYPE/@value"));
info.setAction(doc.valueOf(".//ACTION"));
info.setDate(doc.valueOf(".//@date"));
info.setActionStatus(doc.valueOf(".//ACTION_STATUS"));
info.setError(doc.valueOf(".//PARAMETER[@name='error']/@value"));
list.add(info);
}
return list;
}
@RequestMapping("/ui/is/getMetaWfIdForFamily.do")
public @ResponseBody
Map<String, String> getMetaWfId(@RequestParam(value = "family", required = true) final String family) throws ISLookUpException {
final String xq = "for $x in collection('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType') " +
"where $x//WORKFLOW_FAMILY='" + family + "' " +
"return concat($x//RESOURCE_IDENTIFIER/@value, ' @@@ ', $x//WORKFLOW_NAME/@menuSection)";
final Map<String, String> map = Maps.newHashMap();
try {
final String[] arr = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xq).split("@@@");
map.put("id", arr[0].trim());
map.put("section", arr[1].trim());
} catch (ISLookUpDocumentNotFoundException e) {
map.put("id", "");
map.put("section", "");
}
map.put("family", family);
return map;
}
@RequestMapping("/ui/is/listServices.do")
public @ResponseBody
Collection<ServiceGrouperDesc> listServices() throws Exception {
final String xq = IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/functionality/modular/xquery/listServices.xquery"));
final List<ServiceDesc> list = Lists.newArrayList();
final SAXReader reader = new SAXReader();
for (String s : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xq)) {
final Document doc = reader.read(new StringReader(s));
final String id = doc.valueOf("/service/id").trim();
final String name = doc.valueOf("/service/name").trim();
final String wsdl = doc.valueOf("/service/wsdl").trim();
list.add(new ServiceDesc(id, name, wsdl));
}
final XPathFactory xpathFactory = XPathFactory.newInstance();
for (ResourceStateSubscription sub : registry.listSubscriptions()) {
boolean notFound = true;
final DOMResult result = new DOMResult(); // NOPMD
sub.getSubscriberAsEpr().writeTo(result);
final String wsdl = xpathFactory.newXPath().evaluate("//*[local-name() = 'Address']", result.getNode()) + "?wsdl";
for (ServiceDesc s : list) {
if (s.getWsdl().equalsIgnoreCase(wsdl)) {
s.getSubscriptions().add(new SubscriptionDesc(sub));
notFound = false;
}
}
if (notFound) {
final ServiceDesc desc = new ServiceDesc("", "", wsdl);
desc.getSubscriptions().add(new SubscriptionDesc(sub));
desc.setStatus(ServiceStatus.MISSING);
list.add(desc);
}
}
final Map<String, ServiceGrouperDesc> map = Maps.newHashMap();
for (ServiceDesc s : list) {
final URL url = new URL(s.getWsdl());
final String host = url.getHost();
final int port = url.getPort();
final String context = Iterables.getFirst(Splitter.on("/").omitEmptyStrings().split(url.getPath()), "");
final String tmpKey = host + "@@@" + port + "@@@" + context;
if (!map.containsKey(tmpKey)) {
map.put(tmpKey, new ServiceGrouperDesc(host, port, context, new ArrayList<ServiceDesc>()));
}
map.get(tmpKey).getServices().add(s);
}
return map.values();
}
@RequestMapping("/ui/is/ping.do")
public @ResponseBody
long pingUrl(@RequestParam(value = "url", required = true) final String url, @RequestParam(value = "timeout", required = true) final int timeout)
throws IOException {
final long start = DateUtils.now();
final HttpURLConnection urlConn = (HttpURLConnection) new URL(url).openConnection();
urlConn.setConnectTimeout(timeout);
urlConn.setReadTimeout(timeout);
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return DateUtils.now() - start;
} else {
throw new IllegalArgumentException("Invalid Url");
}
}
public void sendXML(final ServletResponse response, final String xml) throws IOException {
response.setContentType("text/xml");
final ServletOutputStream out = response.getOutputStream();
IOUtils.copy(new StringReader(xml), out);
out.flush();
out.close();
}
}