package eu.eudat.service.reference.external; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import eu.eudat.commons.enums.ReferenceType; import eu.eudat.commons.exceptions.HugeResultSetException; import eu.eudat.service.reference.external.config.*; import eu.eudat.service.reference.external.config.entities.GenericUrls; import eu.eudat.service.reference.external.models.ExternalRefernceResult; import eu.eudat.service.reference.external.criteria.ExternalReferenceCriteria; import eu.eudat.service.reference.external.criteria.FetchStrategy; import eu.eudat.service.storage.StorageFileService; import gr.cite.tools.exception.MyNotFoundException; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.Unmarshaller; 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 java.io.ByteArrayInputStream; import java.io.File; import java.io.StringReader; import java.lang.reflect.Method; import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; @Service public class RemoteFetcher { private static final Logger logger = LoggerFactory.getLogger(RemoteFetcher.class); private final WebClient client; private final ExternalUrlConfigProvider externalUrlConfigProvider; @Autowired public RemoteFetcher(ExternalUrlConfigProvider externalUrlConfigProvider) { this.externalUrlConfigProvider = externalUrlConfigProvider; 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(); } public List> get(ReferenceType referenceType, ExternalReferenceCriteria externalReferenceCriteria, String key) throws MyNotFoundException, HugeResultSetException { FetchStrategy fetchStrategy = null; GenericUrls exGenericUrls = this.getExternalUrls(referenceType); List urlConfigs = key != null && !key.isEmpty() ? exGenericUrls.getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : exGenericUrls.getUrls(); List> results = getAll(urlConfigs, fetchStrategy, externalReferenceCriteria); for (Map result: results) { result.put("referenceType", referenceType.name()); } return results; } public GenericUrls getExternalUrls(ReferenceType referenceType) { switch (referenceType){ case Taxonomies: return this.externalUrlConfigProvider.getExternalUrls().getTaxonomies(); case Licenses: return this.externalUrlConfigProvider.getExternalUrls().getLicenses(); case Publications: return this.externalUrlConfigProvider.getExternalUrls().getPublications(); case Journals: return this.externalUrlConfigProvider.getExternalUrls().getJournals(); case PubRepositories: return this.externalUrlConfigProvider.getExternalUrls().getPubRepositories(); case DataRepositories: return this.externalUrlConfigProvider.getExternalUrls().getRepositories(); case Registries: return this.externalUrlConfigProvider.getExternalUrls().getRegistries(); case Services: return this.externalUrlConfigProvider.getExternalUrls().getServices(); case Grants: return this.externalUrlConfigProvider.getExternalUrls().getGrants(); case Organizations: return this.externalUrlConfigProvider.getExternalUrls().getOrganisations(); case Datasets: return this.externalUrlConfigProvider.getExternalUrls().getDatasets(); case Funder: return this.externalUrlConfigProvider.getExternalUrls().getFunders(); case Project: return this.externalUrlConfigProvider.getExternalUrls().getProjects(); case Researcher: return this.externalUrlConfigProvider.getExternalUrls().getResearchers(); default: throw new IllegalArgumentException("Type not found" + referenceType); } } public Integer findEntries(ExternalReferenceCriteria externalReferenceCriteria, String key) throws MyNotFoundException, HugeResultSetException { List urlConfigs = key != null && !key.isEmpty() ? this.externalUrlConfigProvider.getExternalUrls().getValidations().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : this.externalUrlConfigProvider.getExternalUrls().getValidations().getUrls(); FetchStrategy fetchStrategy = this.externalUrlConfigProvider.getExternalUrls().getValidations().getFetchMode(); List> data = this.getAll(urlConfigs, fetchStrategy, externalReferenceCriteria); return data.size(); } public List> getExternalGeneric(ExternalReferenceCriteria externalReferenceCriteria, GenericUrls genericUrls) { List urlConfigurations = genericUrls.getUrls(); FetchStrategy fetchStrategy = genericUrls.getFetchMode(); return getAll(urlConfigurations, fetchStrategy, externalReferenceCriteria); } public List> getExternalGenericWithData(ExternalReferenceCriteria externalReferenceCriteria, GenericUrls genericUrls) { List urlConfigurations = genericUrls.getUrls(); return getAllWithData(urlConfigurations, externalReferenceCriteria); } private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, ExternalReferenceCriteria externalReferenceCriteria) { List> results = new LinkedList<>(); if (urlConfigs == null || urlConfigs.isEmpty()) { return results; } // throw new MyNotFoundException("No Repository urls found in configuration"); urlConfigs.sort(Comparator.comparing(UrlConfiguration::getOrdinal)); urlConfigs.forEach(urlConfiguration -> { ifFunderQueryExist(urlConfiguration, externalReferenceCriteria); if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { try { String auth = null; if (urlConfiguration.getAuth() != null) { auth = this.getAuthentication(urlConfiguration.getAuth()); } results.addAll(getAllResultsFromUrl(urlConfiguration.getUrl(), fetchStrategy, urlConfiguration.getData(), urlConfiguration.getPaginationPath(), externalReferenceCriteria, 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); } } else if (urlConfiguration.getType() != null && urlConfiguration.getType().equals("Internal")) { results.addAll(getAllResultsFromMockUpJson(urlConfiguration.getUrl(), externalReferenceCriteria.getLike())); } }); /* for (UrlConfiguration urlConfig : urlConfigs) { ifFunderQueryExist(urlConfig, externalUrlCriteria); if (urlConfig.getType() == null || urlConfig.getType().equals("External")) { results.addAll(getAllResultsFromUrl(urlConfig.getUrl(), fetchStrategy, urlConfig.getData(), urlConfig.getPaginationPath(), externalUrlCriteria, urlConfig.getLabel(), urlConfig.getKey(), urlConfig.getContentType(), urlConfig.getFirstpage(), urlConfig.getRequestBody(), urlConfig.getRequestType())); } else if (urlConfig.getType() != null && urlConfig.getType().equals("Internal")) { results.addAll(getAllResultsFromMockUpJson(urlConfig.getUrl(), externalUrlCriteria.getLike())); } }*/ 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, ExternalReferenceCriteria externalReferenceCriteria) { List> results = new LinkedList<>(); if (urlConfigs == null || urlConfigs.isEmpty()) { return results; } urlConfigs.sort(Comparator.comparing(UrlConfiguration::getOrdinal)); urlConfigs.forEach(urlConfiguration -> { ifFunderQueryExist(urlConfiguration, externalReferenceCriteria); if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { try { results.addAll(getAllResultsFromUrlWithData(urlConfiguration.getUrl(), urlConfiguration.getData(), externalReferenceCriteria, urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getQueries())); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } } }); return results; } private void ifFunderQueryExist(UrlConfiguration urlConfiguration, ExternalReferenceCriteria externalReferenceCriteria) { if (urlConfiguration.getFunderQuery() != null) { if (externalReferenceCriteria.getFunderId() != null && !urlConfiguration.getFunderQuery().startsWith("dmp:")) { urlConfiguration.setUrl(urlConfiguration.getUrl().replace("{funderQuery}", urlConfiguration.getFunderQuery())); } else { urlConfiguration.setUrl(urlConfiguration.getUrl().replace("{funderQuery}", "")); } } } private String calculateQuery(ExternalReferenceCriteria externalReferenceCriteria, List queryConfigs) { String finalQuery = ""; QueryConfig queryConfig = queryConfigs.stream().filter(queryConfigl -> externalReferenceCriteria.getLike().matches(queryConfigl.getCondition())) .min((Comparator.comparing(QueryConfig::getOrdinal))).orElse(null); if (queryConfig != null) { if (queryConfig.getSeparator() != null) { String[] likes = externalReferenceCriteria.getLike().split(queryConfig.getSeparator()); finalQuery = queryConfig.getValue(); for (int i = 0; i < likes.length; i++) { finalQuery = finalQuery.replaceAll("\\{like" + (i+1) + "}", likes[i]); } } else { finalQuery = queryConfig.getValue().replaceAll("\\{like}", externalReferenceCriteria.getLike()); } } return finalQuery; } protected String replaceCriteriaOnUrl(String path, ExternalReferenceCriteria externalReferenceCriteria, String firstPage, List queries) { String completedPath = path; if (externalReferenceCriteria.getLike() != null) { if ((path.contains("openaire") || path.contains("orcid") || path.contains("ror") || path.contains("fairsharing")) && externalReferenceCriteria.getLike().equals("")) { completedPath = completedPath.replaceAll("\\{like}", "*"); completedPath = completedPath.replaceAll("\\{query}", "*"); } else { if (completedPath.contains("{query}")) { completedPath = completedPath.replaceAll("\\{query}", this.calculateQuery(externalReferenceCriteria, queries)); } else { completedPath = completedPath.replaceAll("\\{like}", externalReferenceCriteria.getLike()); } } } else { completedPath = completedPath.replace("{like}", ""); } if (externalReferenceCriteria.getFunderId() != null) { String funderPrefix = externalReferenceCriteria.getFunderId().split(":")[0]; String funderId = externalReferenceCriteria.getFunderId().replace(funderPrefix + ":", ""); if (funderId.toCharArray()[0] == ':') { funderId = externalReferenceCriteria.getFunderId(); } /* try { funderId = URLEncoder.encode(funderId, "UTF-8"); } catch (UnsupportedEncodingException e) { logger.error(e.getMessage(), e); } */ completedPath = completedPath.replace("{funderId}", funderId); } else if(completedPath.contains("{funderId}")){ logger.warn("FunderId is null."); completedPath = completedPath.replace("{funderId}", " "); } if (externalReferenceCriteria.getPage() != null) { completedPath = completedPath.replace("{page}", externalReferenceCriteria.getPage()); } else { if (firstPage != null) { completedPath = completedPath.replace("{page}", firstPage); } else { completedPath = completedPath.replace("{page}", "1"); } } if (externalReferenceCriteria.getPageSize() != null) { completedPath = completedPath.replace("{pageSize}", externalReferenceCriteria.getPageSize()); } else { completedPath = completedPath.replace("{pageSize}", "60"); } if (externalReferenceCriteria.getHost() != null) { completedPath = completedPath.replace("{host}", externalReferenceCriteria.getHost()); } else { completedPath = completedPath.replace("{host}", ""); } if (externalReferenceCriteria.getPath() != null) { completedPath = completedPath.replace("{path}", externalReferenceCriteria.getPath()); } else { completedPath = completedPath.replace("{path}", ""); } return completedPath; } private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalReferenceCriteria externalReferenceCriteria, 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, externalReferenceCriteria, firstPage, queries); String replacedBody = replaceCriteriaOnUrl(requestBody, externalReferenceCriteria, firstPage, queries); ExternalRefernceResult externalRefernceResult = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType, auth); if(externalRefernceResult != null) { if (filterType != null && filterType.equals("local") && (externalReferenceCriteria.getLike() != null && !externalReferenceCriteria.getLike().isEmpty())) { externalRefernceResult.setResults(externalRefernceResult.getResults().stream() .filter(r -> r.get("name").toLowerCase().contains(externalReferenceCriteria.getLike().toLowerCase())) .collect(Collectors.toList())); } if (fetchStrategy == FetchStrategy.FIRST) return externalRefernceResult.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); if (externalRefernceResult.getPagination() != null && externalRefernceResult.getPagination().get("pages") != null) //if has more pages, add them to the pages set for (int i = 2; i <= externalRefernceResult.getPagination().get("pages"); i++) pages.add(i); Long maxResults = this.externalUrlConfigProvider.getExternalUrls().getMaxresults(); if ((maxResults > 0) && (externalRefernceResult.getPagination().get("count") > maxResults)) throw new HugeResultSetException("The submitted search query " + externalReferenceCriteria.getLike() + " is about to return " + externalRefernceResult.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, auth)) .filter(Objects::nonNull) .reduce((result1, result2) -> { result1.getResults().addAll(result2.getResults()); return result1; }); ExternalRefernceResult remainingExternalRefernceResult = optionalResults.orElseGet(ExternalRefernceResult::new); remainingExternalRefernceResult.getResults().addAll(externalRefernceResult.getResults()); return remainingExternalRefernceResult.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); } else { return new LinkedList<>(); } } private List> getAllResultsFromUrlWithData(String path, final DataUrlConfiguration jsonDataPath, ExternalReferenceCriteria externalReferenceCriteria, String contentType, String firstPage, String requestBody, String requestType, List queries) { String replacedPath = replaceCriteriaOnUrl(path, externalReferenceCriteria, firstPage, queries); String replacedBody = replaceCriteriaOnUrl(requestBody, externalReferenceCriteria, firstPage, queries); try { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); HttpEntity entity; ResponseEntity response; if (contentType != null && !contentType.isEmpty()) { headers.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); headers.setContentType(MediaType.valueOf(contentType)); } JsonNode jsonBody = new ObjectMapper().readTree(replacedBody); entity = new HttpEntity<>(jsonBody, headers); 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()); return jsonContext.read(jsonDataPath.getPath()); } } } catch (Exception exception) { logger.error(exception.getMessage(), exception); } return new LinkedList<>(); } protected ExternalRefernceResult getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType, String auth) { try { //RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory()); //HttpHeaders headers = new HttpHeaders(); //HttpEntity entity; ResponseEntity response; /* * URL url = new URL(urlString.replaceAll(" ", "%20")); * * HttpURLConnection con = (HttpURLConnection) url.openConnection(); * con.setRequestMethod("GET"); */ /* 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); 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 ExternalRefernceResult externalRefernceResult = new ExternalRefernceResult(); if (response.getHeaders().get("Content-Type").get(0).contains("json")) { DocumentContext jsonContext = JsonPath.parse(response.getBody()); if (jsonDataPath.getFieldsUrlConfiguration().getPath() != null) { externalRefernceResult = RemoteFetcherUtils.getFromJsonWithRecursiveFetching(jsonContext, jsonDataPath, this, requestBody, requestType, auth); } else if (jsonDataPath.getFieldsUrlConfiguration().getFirstName() != null) { externalRefernceResult = RemoteFetcherUtils.getFromJsonWithFirstAndLastName(jsonContext, jsonDataPath); } else { externalRefernceResult = RemoteFetcherUtils.getFromJson(jsonContext, jsonDataPath); } externalRefernceResult.setResults(externalRefernceResult.getResults().stream().map(e -> e.entrySet().stream().collect(Collectors.toMap(x -> this.transformKey(jsonDataPath,x.getKey()), Map.Entry::getValue))) .collect(Collectors.toList())); } else if (response.getHeaders().get("Content-Type").get(0).contains("xml")) { Class aClass = Class.forName(jsonDataPath.getParseClass()); JAXBContext jaxbContext = JAXBContext.newInstance(aClass); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); StringReader stringReader = new StringReader(response.getBody()); Object data = unmarshaller.unmarshal(stringReader); Method reader = null; if (jsonDataPath.getParseField() != null && !jsonDataPath.getParseField().isEmpty()) { String camelCaseGetter = jsonDataPath.getParseField() != null && !jsonDataPath.getParseField().isEmpty() ? "get" + jsonDataPath.getParseField().substring(0, 1).toUpperCase() + jsonDataPath.getParseField().substring(1) : ""; reader = aClass.getMethod(camelCaseGetter); } ObjectMapper objectMapper = new ObjectMapper(); List> values = new ArrayList<>(); int max = 1; if (reader != null) { Object invokedField = reader.invoke(data); if (invokedField instanceof Collection) { max = ((Collection) invokedField).size(); } } for (int i = 0; i< max; i++) { Object value; if (reader != null) { Object invokedField = reader.invoke(data); if (invokedField instanceof Collection) { value = ((Collection) invokedField).toArray()[i]; } else { value = invokedField; } } else { value = data; } Map map = objectMapper.convertValue(value, Map.class); if (jsonDataPath.getMergedFields() != null && !jsonDataPath.getMergedFields().isEmpty() && jsonDataPath.getMergedFieldName() != null && !jsonDataPath.getMergedFieldName().isEmpty()) { Map finalMap = new HashMap<>(); for (Map.Entry entry : map.entrySet()) { if (jsonDataPath.getMergedFields().contains(entry.getKey())) { if (!finalMap.containsKey(jsonDataPath.getMergedFieldName())) { finalMap.put(jsonDataPath.getMergedFieldName(), entry.getValue()); } else { finalMap.put(jsonDataPath.getMergedFieldName(), finalMap.get(jsonDataPath.getMergedFieldName()) + " " + entry.getValue()); } } else { finalMap.put(entry.getKey(), entry.getValue()); } } values.add(finalMap); } else { values.add(map); } } externalRefernceResult = new ExternalRefernceResult(values, new HashMap<>(1, 1)); } if (externalRefernceResult.getPagination().isEmpty()) { externalRefernceResult.getPagination().put("pages", 1); externalRefernceResult.getPagination().put("count", externalRefernceResult.getResults().size()); } return externalRefernceResult; } } catch (Exception exception) { logger.error(exception.getMessage(), exception); } //maybe print smth... return null; } private List> getAllResultsFromMockUpJson(String path, String query) { List> internalResults; try { String filePath = Paths.get(path).toUri().toURL().toString(); ObjectMapper mapper = new ObjectMapper(); internalResults = mapper.readValue(new File(filePath), new TypeReference>>(){}); return searchListMap(internalResults, query); } catch (Exception e) { logger.error(e.getMessage(), e); return new LinkedList<>(); } } private List> searchListMap(List> internalResults, String query) { List> list = new LinkedList<>(); for (Map map : internalResults) { if (map.get("name") != null && map.get("name").toUpperCase().contains(query.toUpperCase())) { list.add(map); } if (map.get("label") != null && map.get("label").toUpperCase().contains(query.toUpperCase())) { list.add(map); } } return list; } private String transformKey(DataUrlConfiguration dataUrlConfiguration, String key) { if (dataUrlConfiguration.getFieldsUrlConfiguration().getId() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getId().replace("'",""))) { if(dataUrlConfiguration.getFieldsUrlConfiguration().getPid() == null) return "pid"; else return "originalId"; } if (dataUrlConfiguration.getFieldsUrlConfiguration().getPid() != null && key.equals("pid")) return "pid"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getPidTypeField() != null && key.equals("pidTypeField")) return "pidTypeField"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getDescription() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getDescription().replace("'",""))) return "description"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getUri() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getUri().replace("'",""))) return "uri"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getName() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getName().replace("'",""))) return "name"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getSource() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getSource().replace("'",""))) return "source"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getCount() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getCount().replace("'",""))) return "count"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getPath() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getPath().replace("'",""))) return "path"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getHost() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getHost().replace("'",""))) return "host"; 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; } }