diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index 2e1e495d1..ca3b4203a 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -46,6 +46,10 @@ org.springframework.boot spring-boot-starter-mail + + org.springframework.boot + spring-boot-starter-webflux + diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index c627bc16a..c6aae9b6d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -1,7 +1,5 @@ package eu.eudat.logic.managers; -import com.jayway.jsonpath.DocumentContext; -import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserDatasetProfile; @@ -10,8 +8,10 @@ import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteR import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException; import eu.eudat.logic.builders.model.models.DataTableDataBuilder; -import eu.eudat.logic.proxy.config.Semantic; +import eu.eudat.logic.proxy.config.*; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; +import eu.eudat.logic.proxy.config.entities.GeneralUrls; +import eu.eudat.logic.proxy.fetching.RemoteFetcher; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.builders.XmlBuilder; @@ -36,10 +36,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.http.*; -import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -56,6 +57,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.*; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.util.*; import java.util.stream.Collectors; @@ -66,20 +69,20 @@ public class DatasetProfileManager { private static final Logger logger = LoggerFactory.getLogger(DatasetProfileManager.class); private static final List cache = new ArrayList<>(); - private ApiContext apiContext; - private DatabaseRepository databaseRepository; - private Environment environment; - private ConfigLoader configLoader; - + private final ApiContext apiContext; + private final DatabaseRepository databaseRepository; + private final Environment environment; + private final ConfigLoader configLoader; private final MetricsManager metricsManager; - + private final RemoteFetcher remoteFetcher; @Autowired - public DatasetProfileManager(ApiContext apiContext, Environment environment, ConfigLoader configLoader, MetricsManager metricsManager) { + public DatasetProfileManager(ApiContext apiContext, Environment environment, ConfigLoader configLoader, MetricsManager metricsManager, RemoteFetcher remoteFetcher) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; this.configLoader = configLoader; this.metricsManager = metricsManager; + this.remoteFetcher = remoteFetcher; } @Transactional @@ -158,10 +161,10 @@ public class DatasetProfileManager { return field; } - public static List getAutocomplete(AutoCompleteData data, String like) { - List result = new LinkedList<>(); + public List getAutocomplete(AutoCompleteData data, String like) { + /*List result = new LinkedList<>(); SimpleClientHttpRequestFactory simpleFactory = new SimpleClientHttpRequestFactory(); - + RestTemplate restTemplate = new RestTemplate(simpleFactory); HttpHeaders headers = new HttpHeaders(); DocumentContext jsonContext = null; @@ -180,7 +183,7 @@ public class DatasetProfileManager { if (url.contains("zenodo")) { url = url.replace("?", "/?"); } - + url = url.replace("{like}", like.equals("") ? "*" : like); url = url.replace("%20", " "); url = url.replace("%22", "\""); @@ -196,7 +199,7 @@ public class DatasetProfileManager { headers.setContentType(MediaType.APPLICATION_JSON); entity = new HttpEntity<>("parameters", headers); - + response = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class); jsonContext = JsonPath.parse(response.getBody()); jsonItems = jsonContext.read(singleData.getOptionsRoot() + "['" + singleData.getAutoCompleteOptions().getLabel() + "','" + singleData.getAutoCompleteOptions().getValue() + "','" + singleData.getAutoCompleteOptions().getSource() + "','" + "uri" + "']"); @@ -222,8 +225,72 @@ public class DatasetProfileManager { } return result.stream().sorted(Comparator.comparing(ExternalAutocompleteFieldModel::getLabel)).collect(Collectors.toList()); - - //return result; +*/ + List result = new LinkedList<>(); + ExternalUrlCriteria urlCriteria = new ExternalUrlCriteria(); + GeneralUrls genericUrls = new GeneralUrls(); + int ordinal = 1; + List> rawResults = new ArrayList<>(); + genericUrls.setFetchMode(FetchStrategy.FIRST); + urlCriteria.setLike(like); + for (AutoCompleteData.AutoCompleteSingleData singleData : data.getAutoCompleteSingleDataList()) { + UrlConfiguration urlConfiguration = new UrlConfiguration(); + try { + URI uri; + if (singleData.getUrl().contains("?")) { + uri = new URI(singleData.getUrl().substring(0, singleData.getUrl().lastIndexOf("?"))); + } else { + uri = new URI(singleData.getUrl()); + } + String source = singleData.getAutoCompleteOptions().getSource(); + source = source != null && !source.isEmpty() ? source : uri.getHost(); + String uriString = singleData.getAutoCompleteOptions().getUri(); + uriString = uriString != null && !uriString.isEmpty() ? uriString : "uri"; + String parsedUrl = singleData.getUrl(); + parsedUrl = parsedUrl.replace("%20", " "); + parsedUrl = parsedUrl.replace("%22", "\""); + while (parsedUrl.contains("&")) { + parsedUrl = parsedUrl.replace("&", "&"); + } + urlConfiguration.setUrl(parsedUrl); + urlConfiguration.setOrdinal(ordinal); + urlConfiguration.setType("External"); + urlConfiguration.setContentType(MediaType.APPLICATION_JSON_VALUE); + urlConfiguration.setFirstpage("1"); + urlConfiguration.setRequestType(singleData.getMethod() != null ? singleData.getMethod() : "GET"); + DataUrlConfiguration dataUrlConfiguration = new DataUrlConfiguration(); + dataUrlConfiguration.setPath(singleData.getOptionsRoot()); + DataFieldsUrlConfiguration fieldsUrlConfiguration = new DataFieldsUrlConfiguration(); + fieldsUrlConfiguration.setId(singleData.getAutoCompleteOptions().getValue()); + fieldsUrlConfiguration.setName(singleData.getAutoCompleteOptions().getLabel()); + fieldsUrlConfiguration.setSource(singleData.getAutoCompleteOptions().getSource().isEmpty()? null : singleData.getAutoCompleteOptions().getSource()); + fieldsUrlConfiguration.setUri(uriString); + dataUrlConfiguration.setFieldsUrlConfiguration(fieldsUrlConfiguration); + urlConfiguration.setKey(source); + urlConfiguration.setLabel(source); + urlConfiguration.setData(dataUrlConfiguration); + if (singleData.getHasAuth()) { + AuthenticationConfiguration authenticationConfiguration = new AuthenticationConfiguration(); + authenticationConfiguration.setAuthUrl(singleData.getAuth().getUrl()); + authenticationConfiguration.setAuthMethod(singleData.getAuth().getMethod()); + authenticationConfiguration.setAuthTokenPath(singleData.getAuth().getPath()); + authenticationConfiguration.setAuthRequestBody(singleData.getAuth().getBody()); + authenticationConfiguration.setType(singleData.getAuth().getType()); + urlConfiguration.setAuth(authenticationConfiguration); + } + genericUrls.getUrls().add(urlConfiguration); + List> singleResults = this.remoteFetcher.getExternalGeneric(urlCriteria, genericUrls); + if (!singleResults.isEmpty() && !singleResults.get(0).containsKey("source") && !singleData.getAutoCompleteOptions().getSource().isEmpty()) { + singleResults.forEach(singleResult -> singleResult.put("source", singleData.getAutoCompleteOptions().getSource())); + } + rawResults.addAll(singleResults); + genericUrls.getUrls().clear(); + } catch (URISyntaxException e) { + logger.error(e.getMessage(), e); + } + } + rawResults.forEach(item -> result.add(new ExternalAutocompleteFieldModel(parseItem(item.get("pid")), parseItem(item.get("name")), parseItem(item.get("source")), parseItem(item.get("uri"))))); + return result; } private static String parseItem(Object item) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java index a2c7e789b..73d39b708 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java @@ -27,11 +27,13 @@ public class PrefillingManager { private final ObjectMapper objectMapper; private final DatasetManager datasetManager; private final LicenseManager licenseManager; + private final PrefillingMapper prefillingMapper; @Autowired - public PrefillingManager(ApiContext apiContext, ConfigLoader configLoader, DatasetManager datasetManager, LicenseManager licenseManager) { + public PrefillingManager(ApiContext apiContext, ConfigLoader configLoader, DatasetManager datasetManager, LicenseManager licenseManager, PrefillingMapper prefillingMapper) { this.apiContext = apiContext; this.configLoader = configLoader; + this.prefillingMapper = prefillingMapper; this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.datasetManager = datasetManager; this.licenseManager = licenseManager; @@ -62,14 +64,14 @@ public class PrefillingManager { PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); Map prefillingEntity = getSingle(prefillingGet.getUrl(), prefillId); DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); - return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); + return prefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } public DatasetWizardModel getPrefilledDatasetUsingData(Map data, String configId, UUID profileId) throws Exception { PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); - return PrefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); + return prefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } private Map getSingle(String url, String id) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 50e664e2b..2cac6179c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -27,6 +27,8 @@ import eu.eudat.models.data.license.LicenseModel; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -35,11 +37,18 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; +@Component public class PrefillingMapper { private static final Logger logger = LoggerFactory.getLogger(PrefillingMapper.class); private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + private final DatasetProfileManager datasetProfileManager; - public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, + @Autowired + public PrefillingMapper(DatasetProfileManager datasetProfileManager) { + this.datasetProfileManager = datasetProfileManager; + } + + public DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, DescriptionTemplate profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile)); @@ -77,7 +86,7 @@ public class PrefillingMapper { return datasetWizardModel; } - private static void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map properties, String type, LicenseManager licenseManager) throws InvocationTargetException, IllegalAccessException, JsonProcessingException { + private void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map properties, String type, LicenseManager licenseManager) throws InvocationTargetException, IllegalAccessException, JsonProcessingException { String trimRegex = prefillingMapping.getTrimRegex() != null ? prefillingMapping.getTrimRegex() : ""; if (!value.startsWith("\"") && !value.startsWith("[") && !value.equals("null")) { value = "\"" + value + "\""; @@ -216,7 +225,7 @@ public class PrefillingMapper { } } - private static Object parseComboBoxValues(JsonNode node, List parsedValues) throws JsonProcessingException { + private Object parseComboBoxValues(JsonNode node, List parsedValues) throws JsonProcessingException { List normalizedValues = new ArrayList<>(); boolean isMultiSelect; String type = node.isArray() ? node.get(0).get("data").get("type").asText() : node.get("data").get("type").asText(); @@ -227,7 +236,7 @@ public class PrefillingMapper { for (String format : parsedValues) { List result = new ArrayList<>(); try { - result = DatasetProfileManager.getAutocomplete(autoCompleteData, format); + result = datasetProfileManager.getAutocomplete(autoCompleteData, format); } catch (Exception e) { logger.error(e.getMessage(), e); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java new file mode 100644 index 000000000..b26ef708a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java @@ -0,0 +1,23 @@ +package eu.eudat.logic.proxy.config; + +public enum AuthType { + ; + private final String name; + + AuthType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static AuthType fromName(String name) { + for (AuthType authType : AuthType.values()) { + if (authType.getName().equals(name)) { + return authType; + } + } + throw new IllegalArgumentException("AuthType [" + name + "] is not supported"); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java new file mode 100644 index 000000000..149b957e2 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java @@ -0,0 +1,57 @@ +package eu.eudat.logic.proxy.config; + +import javax.xml.bind.annotation.XmlElement; + +public class AuthenticationConfiguration { + + private String authUrl; + private String authMethod = "GET"; + private String authTokenPath; + private String authRequestBody; + private String type; + + public String getAuthUrl() { + return authUrl; + } + + @XmlElement(name = "authUrl") + public void setAuthUrl(String authUrl) { + this.authUrl = authUrl; + } + + public String getAuthMethod() { + return authMethod; + } + + @XmlElement(name = "authUrlMethod") + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public String getAuthTokenPath() { + return authTokenPath; + } + + @XmlElement(name = "authTokenJpath") + public void setAuthTokenPath(String authTokenPath) { + this.authTokenPath = authTokenPath; + } + + public String getAuthRequestBody() { + return authRequestBody; + } + + @XmlElement(name = "authUrlBody") + public void setAuthRequestBody(String authRequestBody) { + this.authRequestBody = authRequestBody; + } + + public String getType() { + return type; + } + + @XmlElement(name = "authType") + public void setType(String type) { + this.type = type; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java index 50f2093fa..f9e018555 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java @@ -21,6 +21,7 @@ public class UrlConfiguration { private String requestType = "GET"; private String requestBody = ""; private String filterType = "remote"; + private AuthenticationConfiguration auth; private List queries; @@ -143,4 +144,13 @@ public class UrlConfiguration { public void setQueries(List queries) { this.queries = queries; } + + public AuthenticationConfiguration getAuth() { + return auth; + } + + @XmlElement(name="authentication") + public void setAuth(AuthenticationConfiguration auth) { + this.auth = auth; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java new file mode 100644 index 000000000..d6581d250 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java @@ -0,0 +1,31 @@ +package eu.eudat.logic.proxy.config.entities; + +import eu.eudat.logic.proxy.config.FetchStrategy; +import eu.eudat.logic.proxy.config.UrlConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public class GeneralUrls extends GenericUrls{ + + List urls; + FetchStrategy fetchMode; + + public GeneralUrls() { + this.urls = new ArrayList<>(); + } + + @Override + public List getUrls() { + return urls; + } + + @Override + public FetchStrategy getFetchMode() { + return fetchMode; + } + + public void setFetchMode(FetchStrategy fetchMode) { + this.fetchMode = fetchMode; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 4d228e7b7..92de62052 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -15,9 +15,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; @@ -33,10 +38,16 @@ public class RemoteFetcher { private static final Logger logger = LoggerFactory.getLogger(RemoteFetcher.class); private ConfigLoader configLoader; + private final WebClient client; @Autowired public RemoteFetcher(ConfigLoader configLoader) { this.configLoader = configLoader; + this.client = WebClient.builder().codecs(clientCodecConfigurer -> { + clientCodecConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON)); + clientCodecConfigurer.defaultCodecs().maxInMemorySize(2 * ((int) Math.pow(1024, 3))); //GK: Why here??? + } + ).clientConnector(new ReactorClientHttpConnector(HttpClient.create().followRedirect(true))).build(); } @Cacheable(value = "repositories", keyGenerator = "externalUrlsKeyGenerator") @@ -198,7 +209,11 @@ public class RemoteFetcher { ifFunderQueryExist(urlConfiguration, externalUrlCriteria); if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { try { - results.addAll(getAllResultsFromUrl(urlConfiguration.getUrl(), fetchStrategy, urlConfiguration.getData(), urlConfiguration.getPaginationPath(), externalUrlCriteria, urlConfiguration.getLabel(), urlConfiguration.getKey(), urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getFilterType(), urlConfiguration.getQueries())); + String auth = null; + if (urlConfiguration.getAuth() != null) { + auth = this.getAuthentication(urlConfiguration.getAuth()); + } + results.addAll(getAllResultsFromUrl(urlConfiguration.getUrl(), fetchStrategy, urlConfiguration.getData(), urlConfiguration.getPaginationPath(), externalUrlCriteria, urlConfiguration.getLabel(), urlConfiguration.getKey(), urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getFilterType(), urlConfiguration.getQueries(), auth)); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } @@ -217,6 +232,19 @@ public class RemoteFetcher { return results; } + private String getAuthentication(AuthenticationConfiguration authenticationConfiguration) { + HttpMethod method = HttpMethod.valueOf(authenticationConfiguration.getAuthMethod()); + Map reponse = this.client.method(method).uri(authenticationConfiguration.getAuthUrl()) + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(this.parseBodyString(authenticationConfiguration.getAuthRequestBody())) + .exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>() { + })).block(); + + + + return authenticationConfiguration.getType() + " " + reponse.get(authenticationConfiguration.getAuthTokenPath()); + } + private List> getAllWithData(List urlConfigs, ExternalUrlCriteria externalUrlCriteria) { List> results = new LinkedList<>(); @@ -273,7 +301,7 @@ public class RemoteFetcher { protected String replaceCriteriaOnUrl(String path, ExternalUrlCriteria externalUrlCriteria, String firstPage, List queries) { String completedPath = path; if (externalUrlCriteria.getLike() != null) { - if ((path.contains("openaire") || path.contains("orcid") || path.contains("ror")) && externalUrlCriteria.getLike().equals("")) { + if ((path.contains("openaire") || path.contains("orcid") || path.contains("ror") || path.contains("fairsharing")) && externalUrlCriteria.getLike().equals("")) { completedPath = completedPath.replaceAll("\\{like}", "*"); completedPath = completedPath.replaceAll("\\{query}", "*"); } else { @@ -329,13 +357,13 @@ public class RemoteFetcher { return completedPath; } - private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalUrlCriteria externalUrlCriteria, String tag, String key, String contentType, String firstPage, String requestBody, String requestType, String filterType, List queries) throws Exception { + private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalUrlCriteria externalUrlCriteria, String tag, String key, String contentType, String firstPage, String requestBody, String requestType, String filterType, List queries, String auth) throws Exception { Set pages = new HashSet<>(); String replacedPath = replaceCriteriaOnUrl(path, externalUrlCriteria, firstPage, queries); String replacedBody = replaceCriteriaOnUrl(requestBody, externalUrlCriteria, firstPage, queries); - Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType); + Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType, auth); if(results != null) { if (filterType != null && filterType.equals("local") && (externalUrlCriteria.getLike() != null && !externalUrlCriteria.getLike().isEmpty())) { results.setResults(results.getResults().stream() @@ -354,7 +382,7 @@ public class RemoteFetcher { throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); Optional optionalResults = pages.parallelStream() - .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType)) + .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType, auth)) .filter(Objects::nonNull) .reduce((result1, result2) -> { result1.getResults().addAll(result2.getResults()); @@ -387,7 +415,7 @@ public class RemoteFetcher { JsonNode jsonBody = new ObjectMapper().readTree(replacedBody); entity = new HttpEntity<>(jsonBody, headers); - response = restTemplate.exchange(replacedPath, HttpMethod.resolve(requestType), entity, String.class); + response = restTemplate.exchange(replacedPath, HttpMethod.valueOf(requestType), entity, String.class); if (response.getStatusCode() == HttpStatus.OK) { if (response.getHeaders().get("Content-Type").get(0).contains("json")) { DocumentContext jsonContext = JsonPath.parse(response.getBody()); @@ -403,12 +431,12 @@ public class RemoteFetcher { } - protected Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType) { + protected Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType, String auth) { try { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - HttpEntity entity; + //RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory()); + //HttpHeaders headers = new HttpHeaders(); + //HttpEntity entity; ResponseEntity response; /* * URL url = new URL(urlString.replaceAll(" ", "%20")); @@ -416,14 +444,27 @@ public class RemoteFetcher { * HttpURLConnection con = (HttpURLConnection) url.openConnection(); * con.setRequestMethod("GET"); */ - if (contentType != null && !contentType.isEmpty()) { + /* if (contentType != null && !contentType.isEmpty()) { headers.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); headers.setContentType(MediaType.valueOf(contentType)); } + if (auth != null) { + headers.set("Authorization", auth); + }*/ JsonNode jsonBody = new ObjectMapper().readTree(requestBody); - entity = new HttpEntity<>(jsonBody, headers); +// entity = new HttpEntity<>(jsonBody, headers); - response = restTemplate.exchange(urlString, HttpMethod.resolve(requestType), entity, String.class); + + response = this.client.method(HttpMethod.valueOf(requestType)).uri(urlString).headers(httpHeaders -> { + if (contentType != null && !contentType.isEmpty()) { + httpHeaders.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); + httpHeaders.setContentType(MediaType.valueOf(contentType)); + } + if (auth != null) { + httpHeaders.set("Authorization", auth); + } + }).bodyValue(jsonBody).retrieve().toEntity(String.class).block(); + //response = restTemplate.exchange(urlString, HttpMethod.resolve(requestType), entity, String.class); if (response.getStatusCode() == HttpStatus.OK) { // success //do here all the parsing Results results = new Results(); @@ -431,7 +472,7 @@ public class RemoteFetcher { DocumentContext jsonContext = JsonPath.parse(response.getBody()); if (jsonDataPath.getFieldsUrlConfiguration().getPath() != null) { - results = RemoteFetcherUtils.getFromJsonWithRecursiveFetching(jsonContext, jsonDataPath, this, requestBody, requestType); + results = RemoteFetcherUtils.getFromJsonWithRecursiveFetching(jsonContext, jsonDataPath, this, requestBody, requestType, auth); } else if (jsonDataPath.getFieldsUrlConfiguration().getFirstName() != null) { results = RemoteFetcherUtils.getFromJsonWithFirstAndLastName(jsonContext, jsonDataPath); } else { @@ -553,8 +594,18 @@ public class RemoteFetcher { return null; } - - - + private String parseBodyString(String bodyString) { + String finalBodyString = bodyString; + if (bodyString.contains("{env:")) { + int index = bodyString.indexOf("{env: "); + while (index >= 0) { + int endIndex = bodyString.indexOf("}", index + 6); + String envName = bodyString.substring(index + 6, endIndex); + finalBodyString = finalBodyString.replace("{env: " + envName + "}", System.getenv(envName)); + index = bodyString.indexOf("{env: ", index + 6); + } + } + return finalBodyString; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java index 6b703ed15..00bcadfa1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java @@ -28,7 +28,7 @@ public class RemoteFetcherUtils { new HashMap<>(1, 1)); } - public static Results getFromJsonWithRecursiveFetching(DocumentContext jsonContext, DataUrlConfiguration jsonDataPath, RemoteFetcher remoteFetcher, String requestBody, String requestType) { + public static Results getFromJsonWithRecursiveFetching(DocumentContext jsonContext, DataUrlConfiguration jsonDataPath, RemoteFetcher remoteFetcher, String requestBody, String requestType, String auth) { Results results = new Results(parseData(jsonContext, jsonDataPath), new HashMap<>(1, 1)); @@ -37,7 +37,7 @@ public class RemoteFetcherUtils { externalUrlCriteria.setPath(result.get("path")); externalUrlCriteria.setHost(result.get("host")); String replacedPath = remoteFetcher.replaceCriteriaOnUrl(jsonDataPath.getUrlConfiguration().getUrl(), externalUrlCriteria, jsonDataPath.getUrlConfiguration().getFirstpage(), jsonDataPath.getUrlConfiguration().getQueries()); - return remoteFetcher.getResultsFromUrl(replacedPath, jsonDataPath.getUrlConfiguration().getData(), jsonDataPath.getUrlConfiguration().getData().getPath(), jsonDataPath.getUrlConfiguration().getContentType(), requestBody, requestType); + return remoteFetcher.getResultsFromUrl(replacedPath, jsonDataPath.getUrlConfiguration().getData(), jsonDataPath.getUrlConfiguration().getData().getPath(), jsonDataPath.getUrlConfiguration().getContentType(), requestBody, requestType, auth); }).filter(Objects::nonNull).map(results1 -> results1.getResults().get(0)).collect(Collectors.toList()); return new Results(multiResults, new HashMap<>(1, 1)); } @@ -98,8 +98,22 @@ public class RemoteFetcherUtils { } } else { value = value.replace("'", ""); - if (stringObjectMap.containsKey(value)) { - parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + if (value.contains(".")) { + String[] parts = value.split("\\."); + Map tempMap = stringObjectMap; + for (int i = 0; i < parts.length; i++) { + if (tempMap.containsKey(parts[i])) { + if (i + 1 < parts.length) { + tempMap = (Map) tempMap.get(parts[i]); + } else { + parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(tempMap.get(parts[i]), (field.getName().equals("types") || field.getName().equals("uri")))); + } + } + } + } else { + if (stringObjectMap.containsKey(value)) { + parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + } } } } @@ -135,7 +149,8 @@ public class RemoteFetcherUtils { } } } else if (value instanceof Map) { - return ((Map)value).get("content"); + String key = ((Map)value).containsKey("$") ? "$" : "content"; + return ((Map)value).get(key); } return value != null ? value.toString() : null; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java index 977110dfc..98ce37926 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java @@ -10,11 +10,62 @@ import java.util.List; import java.util.Map; public class AutoCompleteData extends ComboBoxData { + + public static class AuthAutoCompleteData { + private String url; + private String method; + private String body; + private String path; + private String type; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } public static class AutoCompleteSingleData { private int autocompleteType; private String url; private ComboBoxData.Option autoCompleteOptions; private String optionsRoot; + private Boolean hasAuth; + private AuthAutoCompleteData auth; + private String method; public int getAutocompleteType() { return autocompleteType; @@ -38,12 +89,36 @@ public class AutoCompleteData extends ComboBoxData { this.url = url; } + public Boolean getHasAuth() { + return hasAuth; + } + + public void setHasAuth(Boolean hasAuth) { + this.hasAuth = hasAuth; + } + + public AuthAutoCompleteData getAuth() { + return auth; + } + + public void setAuth(AuthAutoCompleteData auth) { + this.auth = auth; + } + public ComboBoxData.Option getAutoCompleteOptions() { return autoCompleteOptions; } public void setAutoCompleteOptions(ComboBoxData.Option autoCompleteOptions) { this.autoCompleteOptions = autoCompleteOptions; } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } } private Boolean multiAutoComplete; @@ -70,11 +145,22 @@ public class AutoCompleteData extends ComboBoxData { parent.setAttribute("url", singleData.url); parent.setAttribute("optionsRoot", singleData.optionsRoot); parent.setAttribute("autoCompleteType", Integer.toString(singleData.autocompleteType)); + parent.setAttribute("hasAuth", Boolean.toString(singleData.hasAuth)); + parent.setAttribute("method", singleData.method); Element element = doc.createElement("option"); element.setAttribute("label", singleData.autoCompleteOptions.getLabel()); element.setAttribute("value", singleData.autoCompleteOptions.getValue()); element.setAttribute("source", singleData.autoCompleteOptions.getSource()); parent.appendChild(element); + if (singleData.hasAuth) { + Element authElement = doc.createElement("auth"); + authElement.setAttribute("url", singleData.auth.url); + authElement.setAttribute("method", singleData.auth.method); + authElement.setAttribute("body", singleData.auth.body); + authElement.setAttribute("path", singleData.auth.path); + authElement.setAttribute("type", singleData.auth.type); + parent.appendChild(authElement); + } root.appendChild(parent); } return root; @@ -108,6 +194,8 @@ public class AutoCompleteData extends ComboBoxData { } else { singleData.autocompleteType = AutocompleteType.fromValue(Integer.parseInt(item.getAttribute("autoCompleteType"))).getValue(); } + singleData.hasAuth = Boolean.parseBoolean(item.getAttribute("hasAuth")); + singleData.method = item.hasAttribute("method") ? item.getAttribute("method") : "GET"; Element optionElement = (Element) item.getElementsByTagName("option").item(0); if (optionElement != null) { singleData.autoCompleteOptions = new Option(); @@ -116,6 +204,17 @@ public class AutoCompleteData extends ComboBoxData { singleData.autoCompleteOptions.setSource(optionElement.getAttribute("source")); singleData.autoCompleteOptions.setUri(optionElement.getAttribute("uri")); } + if (singleData.hasAuth) { + Element authElement = (Element) item.getElementsByTagName("auth").item(0); + if (authElement != null) { + singleData.auth = new AuthAutoCompleteData(); + singleData.auth.setUrl(authElement.getAttribute("url")); + singleData.auth.setMethod(authElement.getAttribute("method")); + singleData.auth.setBody(authElement.getAttribute("body")); + singleData.auth.setPath(authElement.getAttribute("path")); + singleData.auth.setType(authElement.getAttribute("type")); + } + } } @Override @@ -141,6 +240,8 @@ public class AutoCompleteData extends ComboBoxData { this.autoCompleteSingleDataList.get(i).autoCompleteOptions = new Option(); this.autoCompleteSingleDataList.get(i).url = (String) singleData.get("url"); this.autoCompleteSingleDataList.get(i).optionsRoot = (String) singleData.get("optionsRoot"); + this.autoCompleteSingleDataList.get(i).hasAuth = (Boolean) singleData.get("hasAuth"); + this.autoCompleteSingleDataList.get(i).method = singleData.containsKey("method") ? (String) singleData.get("method") : "GET"; if (singleData.get("autoCompleteType") == null) { this.autoCompleteSingleDataList.get(i).autocompleteType = AutocompleteType.UNCACHED.getValue(); @@ -154,6 +255,17 @@ public class AutoCompleteData extends ComboBoxData { this.autoCompleteSingleDataList.get(i).autoCompleteOptions.setSource(options.get("source")); this.autoCompleteSingleDataList.get(i).autoCompleteOptions.setUri(options.get("uri")); } + if (this.autoCompleteSingleDataList.get(i).hasAuth) { + Map auth = (Map) singleData.get("auth"); + if (auth != null) { + this.autoCompleteSingleDataList.get(i).auth = new AuthAutoCompleteData(); + this.autoCompleteSingleDataList.get(i).auth.setUrl(auth.get("url")); + this.autoCompleteSingleDataList.get(i).auth.setType(auth.get("type")); + this.autoCompleteSingleDataList.get(i).auth.setPath(auth.get("path")); + this.autoCompleteSingleDataList.get(i).auth.setBody(auth.get("body")); + this.autoCompleteSingleDataList.get(i).auth.setMethod(auth.get("method")); + } + } i++; } } @@ -190,6 +302,8 @@ public class AutoCompleteData extends ComboBoxData { node.appendChild(autoCompleteSingles.item(i)); node.setAttribute("url", item.getAttribute("url")); node.setAttribute("optionsRoot", item.getAttribute("optionsRoot")); + node.setAttribute("hasAuth", item.getAttribute("hasAuth")); + node.setAttribute("method", item.hasAttribute("method") ? item.getAttribute("method") : "GET"); autoCompletes.add(singleToMap(node)); } } @@ -214,6 +328,16 @@ public class AutoCompleteData extends ComboBoxData { return dataMap; } + private Map authToMap(Element item){ + HashMap dataMap = new HashMap(); + dataMap.put("url", item != null ? item.getAttribute("url") : ""); + dataMap.put("method", item != null ? item.getAttribute("method") : ""); + dataMap.put("body", item != null ? item.getAttribute("body") : ""); + dataMap.put("path", item != null ? item.getAttribute("path") : ""); + dataMap.put("type", item != null ? item.getAttribute("type") : ""); + return dataMap; + } + private Map singleToMap(Element item) { Map dataMap = new HashMap<>(); if (!item.getAttribute("autoCompleteType").isEmpty()) { @@ -221,8 +345,12 @@ public class AutoCompleteData extends ComboBoxData { } dataMap.put("optionsRoot", item != null ? item.getAttribute("optionsRoot") : ""); dataMap.put("url", item != null ? item.getAttribute("url") : ""); + dataMap.put("hasAuth", item != null ? item.getAttribute("hasAuth") : "false"); Element optionElement = (Element) item.getElementsByTagName("option").item(0); dataMap.put("autoCompleteOptions", item != null ? optionToMap(optionElement) : null); + Element authElement = (Element) item.getElementsByTagName("auth").item(0); + dataMap.put("auth", item != null ? authToMap(authElement) : null); + dataMap.put("method", item != null && item.hasAttribute("method") ? item.getAttribute("method") : "GET"); return dataMap; } diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts index 526c17f37..c66d04173 100644 --- a/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts @@ -12,11 +12,22 @@ export interface AutoCompleteFieldData extends FieldData { multiAutoComplete: boolean; } +export interface AuthAutoCompleteData extends FieldData { + url: string; + method: string; + body: string; + path: string; + type: string; +} + export interface AutoCompleteSingleData extends FieldData { url: string; optionsRoot: string; autoCompleteOptions: FieldDataOption; autocompleteType: number; + hasAuth: boolean; + method: string; + auth: AuthAutoCompleteData; } export interface CheckBoxFieldData extends FieldData { diff --git a/dmp-frontend/src/app/core/services/prefilling.service.ts b/dmp-frontend/src/app/core/services/prefilling.service.ts index fa940a1f6..600a187f9 100644 --- a/dmp-frontend/src/app/core/services/prefilling.service.ts +++ b/dmp-frontend/src/app/core/services/prefilling.service.ts @@ -20,10 +20,10 @@ export class PrefillingService { } public getPrefillingDataset(pid: string, profileId: string, configId: string): Observable { - return this.http.get(this.actionUrl + '/generate/' + encodeURIComponent(pid) + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), { headers: this.headers }); + return this.http.get(this.actionUrl + 'generate/' + encodeURIComponent(pid) + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), { headers: this.headers }); } public getPrefillingDatasetUsingData(data: any, profileId: string, configId: string): Observable { - return this.http.post(this.actionUrl + '/generateUsingData' + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), data, { headers: this.headers }); + return this.http.post(this.actionUrl + 'generateUsingData' + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), data, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts index 3bffd86d1..f53cf544c 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts @@ -3,6 +3,7 @@ import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profil import { FieldDataOptionEditorModel } from './field-data-option-editor-model'; import { FormGroup, Validators } from '@angular/forms'; import { AutoCompleteFieldData, AutoCompleteSingleData } from '@app/core/model/dataset-profile-definition/field-data/field-data'; +import { AuthFieldEditorModel } from './auto-complete-auth-field-data.model'; export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel { @@ -11,6 +12,9 @@ export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel = []): FormGroup { @@ -18,9 +22,12 @@ export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel - +
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-SOURCE-TITLE' | translate}}
- - +
- warning_amber {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-OTHER-SOURCES-REQUIRED'| translate}}
- +
- +
- + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}} + + {{method.value}} + - + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -70,6 +76,37 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-HAS-AUTH' | translate}} +
+ + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}} + + {{method.value}} + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-TYPE' | translate}} + + {{type.value}} + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-OPTIONS-ROOT' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-BODY' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts index 06224ee6f..1171059cd 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts @@ -3,6 +3,8 @@ import { FormGroup, FormArray, AbstractControl } from '@angular/forms'; import { DatasetProfileComboBoxType } from '../../../../../../../core/common/enum/dataset-profile-combo-box-type'; import { AutoCompleteFieldDataEditorModel } from '../../../../admin/field-data/auto-complete-field-data-editor-model'; import { AutoCompleteSingleDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data'; +import { HtmlMethod } from '@app/core/model/dataset-profile-definition/html-method.enum'; +import { AuthType } from '@app/core/model/dataset-profile-definition/auth-type.enum'; @Component({ selector: 'app-dataset-profile-editor-auto-complete-field-component', @@ -11,6 +13,9 @@ import { AutoCompleteSingleDataEditorModel } from '@app/ui/admin/dataset-profile }) export class DatasetProfileEditorAutoCompleteFieldComponent implements OnInit { + public htmlMethods = HtmlMethod; + public authTypes = AuthType; + @Input() form: FormGroup; private data: AutoCompleteFieldDataEditorModel = new AutoCompleteFieldDataEditorModel(); multiForm: FormArray; diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index bd029097e..9819f25b8 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Label", @@ -1755,7 +1759,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Einstellungen", diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index b57448cbf..529d4862c 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Label", @@ -1755,7 +1759,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Settings", diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index c86acbb90..a11facff3 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Fuente", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Optiones principales", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Campo de entrada para fecha", "FIELD-DATE-PICKER-PLACEHOLDER": "Marcador de entrada", "FIELD-DATE-PICKER-LABEL": "Etiqueta", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Configuración", diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index 8517af524..2c8198f54 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Πηγή", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Βάση Επιλογών", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Επιλογή Ημερομηνίας", "FIELD-DATE-PICKER-PLACEHOLDER": "Τοποθέτηση placeholder", "FIELD-DATE-PICKER-LABEL": "Ετικέτα", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ρυθμίσεις", diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index d3a724f1c..28532490f 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Izvor", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opcija", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Izbor datuma", "FIELD-DATE-PICKER-PLACEHOLDER": "Polje za unos", "FIELD-DATE-PICKER-LABEL": "Oznaka", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Postavke", diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index 288cbd39f..73a058d45 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Źródło", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "$Opcje główne$", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Wybierz datę", "FIELD-DATE-PICKER-PLACEHOLDER": "Wprowadź tekst zastępczy", "FIELD-DATE-PICKER-LABEL": "Etykieta", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ustawienia", diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 791996716..6e9045a6b 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Fonte", "FIELD-AUTOCOMPLETE-URL": "URL", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opções de Raiz", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Escolha da Data", "FIELD-DATE-PICKER-PLACEHOLDER": "Sugestão de Preenchimento", "FIELD-DATE-PICKER-LABEL": "Etiqueta", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Definições", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 3ab92051d..887380183 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder", "FIELD-DATE-PICKER-LABEL": "Label", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Nastavenia", diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index 65ffac0a4..aeeba8df9 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Izvor", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opcija", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Izbor datuma", "FIELD-DATE-PICKER-PLACEHOLDER": "Polje za unos", "FIELD-DATE-PICKER-LABEL": "Oznaka", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Podešavanja", diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index c2e6e20d9..00eea7df8 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -459,6 +459,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Kaynak", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Tarih Seçici", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Etiket", @@ -1756,7 +1760,7 @@ "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ayarlar",