package org.gcube.data.publishing.gCatFeeder.collectors.dm; import java.time.LocalDateTime; import java.time.Month; import java.time.ZoneId; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.gcube.data.analysis.dataminermanagercl.server.DataMinerService; import org.gcube.data.analysis.dataminermanagercl.server.dmservice.SClient; import org.gcube.data.analysis.dataminermanagercl.shared.process.Operator; import org.gcube.data.analysis.dataminermanagercl.shared.process.OperatorCategory; import org.gcube.data.analysis.dataminermanagercl.shared.process.OperatorsClassification; import org.gcube.data.publishing.gCatFeeder.collectors.dm.model.InternalAlgorithmDescriptor; import org.gcube.data.publishing.gCatFeeder.collectors.dm.model.Parameter; import org.gcube.data.publishing.gCatFeeder.collectors.dm.model.UserIdentity; import org.gcube.data.publishing.gCatFeeder.model.EnvironmentConfiguration; import org.gcube.data.publishing.gCatFeeder.utils.ISUtils; import org.gcube.data.publishing.gCatfeeder.collectors.DataCollector; import org.gcube.data.publishing.gCatfeeder.collectors.model.faults.CollectorFault; import lombok.extern.slf4j.Slf4j; import org.gcube.portlets.user.uriresolvermanager.exception.IllegalArgumentException; import org.gcube.portlets.user.uriresolvermanager.exception.UriResolverMapException; @Slf4j public class DMAlgorithmsInfoCollector implements DataCollector { /* * i.e. "Basic statistic max min average {Published by Giancarlo Panichi (giancarlo.panichi) on 2018/07/20 10:24 GMT}" */ private static final Pattern descriptionPattern = Pattern.compile("\\{Published by (.*)\\((.*(\\.)?.*\\)) on (.*)\\}$"); static final DateTimeFormatter versionDateParser= DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm 'GMT'[Z]") .withResolverStyle(ResolverStyle.STRICT) .withLocale(Locale.getDefault()) .withZone(ZoneId.systemDefault()); /* static final DateTimeFormatter versionDateParser=new DateTimeFormatterBuilder() .parseCaseInsensitive().parseLenient() .appendValue(ChronoField.YEAR,4) .appendLiteral('/') .appendValue(ChronoField.MONTH_OF_YEAR,2) .appendLiteral('/') .appendValue(ChronoField.DAY_OF_MONTH,2) .appendLiteral(' ') .appendValue(ChronoField.HOUR_OF_DAY,2) .appendLiteral(':') .appendValue(ChronoField.MINUTE_OF_HOUR,2) .appendLiteral(' ') .appendOffset("+HHMM", "GMT") .toFormatter().withChronology(IsoChronology.INSTANCE) .withResolverStyle(ResolverStyle.SMART); */ private Map env=null; public void setEnvironmentConfiguration(EnvironmentConfiguration envConfig) { if(envConfig!=null) { log.debug("Current Environment Configuration is : "+envConfig.getCurrentConfiguration()); this.env=envConfig.getCurrentConfiguration(); }else { env=Collections.emptyMap(); log.warn("NO ENVIRONMENT CONFIGURATION FOUND"); } } @Override public Set collect() throws CollectorFault { try { log.trace("Collecting information for Dataminer algorithms"); HashSet toReturn=new HashSet(); SClient client=new DataMinerService().getClient(); String wpsbaseUrl=getWPSBasePath(); List opClassifications=client.getOperatorsClassifications(); log.debug("Found {} classifications.",opClassifications.size()); for(OperatorsClassification opClass: opClassifications) { // Load info String opClassName =opClass.getName(); List ops=opClass.getOperators(); log.debug("Found {} operators under classification {} ",ops.size(),opClassName); for(Operator op : ops) { InternalAlgorithmDescriptor desc=new InternalAlgorithmDescriptor(); desc.setClassName(opClassName); // OperatorCategory Info OperatorCategory cat = op.getCategory(); String categoryBriefDescription = cat.getBriefDescription(); String categoryDescription= cat.getDescription(); String categoryID=cat.getId(); String categoryName=cat.getName(); desc.setCategoryBriefDescription(categoryBriefDescription); desc.setCategoryID(categoryID); desc.setCategoryName(categoryName); desc.setCategoryDescription(categoryDescription); // Operator info String opBriefDescription=op.getBriefDescription(); String opDescription=op.getDescription(); String opID=op.getId(); String operatorName=op.getName(); desc.setBriefDescription(opBriefDescription); desc.setDescription(opDescription); desc.setId(opID); desc.setName(operatorName); desc.setAuthor(parseUser(getAuthor(opDescription))); desc.setMaintainer(parseUser(getAuthor(opDescription))); desc.setVersion(parseDescriptionForDate(opDescription)); // Try to use version as creation time LocalDateTime toSetCreationDate=null; try{ toSetCreationDate=LocalDateTime.parse(desc.getVersion(),versionDateParser); }catch(Throwable t){ log.debug("Version {} is not a date. Using 1900-01-01 as Creation date..",desc.getVersion()); toSetCreationDate = LocalDateTime.of(1900, Month.JANUARY,1,0,0); } desc.setCreationDate(toSetCreationDate); // Parameters info for(org.gcube.data.analysis.dataminermanagercl.shared.parameters.Parameter param:client.getInputParameters(op)) { String paramDescription=param.getDescription(); String paramName=param.getName(); String paramType=param.getTypology().toString(); String paramValue=param.getValue(); desc.getInputParameters().add( new Parameter(paramName, paramType, paramDescription, paramValue)); } for(org.gcube.data.analysis.dataminermanagercl.shared.parameters.Parameter param:client.getOutputParameters(op)) { String paramDescription=param.getDescription(); String paramName=param.getName(); String paramType=param.getTypology().toString(); String paramValue=param.getValue(); desc.getOutputParameters().add( new Parameter(paramName, paramType, paramDescription, paramValue)); } desc.getTags().add(categoryName); String guiBasePath=getGUIBasePath(); if(guiBasePath!=null) desc.setGuiLink(getGUIBasePath()+"?"+ DataMinerCollectorProperties.getProperty(DataMinerCollectorProperties.GUI_PARAM_NAME)+"="+opID); desc.setGatewayName(env.get(Constants.GATEWAY_NAME)); if(wpsbaseUrl!=null) { desc.setWpsLink(wpsbaseUrl+"?Request=DescribeProcess&Version=1.0.0&Service=WPS"+"&Identifier="+opID); } desc.setPrivateFlag(Boolean.parseBoolean(env.get(Constants.PRIVATE))); toReturn.add(desc); } // Create bean } return toReturn; }catch(Exception e) { throw new CollectorFault("Unable to retrieve information",e); } } private String getGUIBasePath() { return env.get(Constants.GUI_BASE_URL); } private String getAuthor(String algorithmDescription) { String toReturn=parseDescriptionForUser(algorithmDescription); if(toReturn==null) toReturn=env.get(Constants.DEFAULT_AUTHOR); if(toReturn==null) toReturn=DataMinerCollectorProperties.getProperty(DataMinerCollectorProperties.DEFAULT_AUTHOR); return toReturn; } static final UserIdentity parseUser(String userString) { try{ String splitter=null; if(userString.contains(" ")) splitter=" "; else if (userString.contains(".")) splitter="\\."; String[] splitted=userString.split(splitter); return new UserIdentity(splitted[0], splitted[1], null, null); }catch(NullPointerException e){ System.err.println("Error with userString "+userString); e.printStackTrace(System.err); throw e; } } /* * e.g. "Basic statistic max min average {Published by Giancarlo Panichi (giancarlo.panichi) on 2018/07/20 10:24 GMT}" */ static final String parseDescriptionForUser(String description) { Matcher m=descriptionPattern.matcher(description); if(m.find()) return m.group(1); // group 0 == {...}, group 1 == Giancarlo Panichi, group 2 == giancarlo.panichi else return null; } static final String parseDescriptionForDate(String description) { Matcher m=descriptionPattern.matcher(description); if(m.find()) return m.group(4); // group 0 == {...}, group 1 == Giancarlo Panichi, group 2 == giancarlo.panichi, group 4 == 2018/07/20 10:24 GMT else return "n.d."; } static final String getWPSBasePath() { try{ return ISUtils.queryForServiceEndpointsByName("DataAnalysis", "DataMiner").get(0).profile(). accessPoints().iterator().next().address(); }catch(Throwable t) { log.warn("Unable to find DM proxy. No WPS URL will be provided",t); return null; } } }