This repository has been archived by the owner on Dec 22, 2022. It is now read-only.
generated from NASA-PDS/template-repo-java
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
thomas loubrieu
committed
Jun 4, 2021
1 parent
22e7957
commit 5e47e95
Showing
1 changed file
with
277 additions
and
0 deletions.
There are no files selected for viewing
277 changes: 277 additions & 0 deletions
277
src/main/java/gov/nasa/pds/api/engineering/elasticsearch/business/ProductBusinessObject.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
package gov.nasa.pds.api.engineering.elasticsearch.business; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.elasticsearch.action.get.GetRequest; | ||
import org.elasticsearch.action.get.GetResponse; | ||
import org.elasticsearch.action.search.SearchRequest; | ||
import org.elasticsearch.action.search.SearchResponse; | ||
import org.elasticsearch.client.RequestOptions; | ||
import org.elasticsearch.client.RestHighLevelClient; | ||
import org.elasticsearch.search.SearchHit; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.lang.Nullable; | ||
|
||
import com.fasterxml.jackson.databind.DeserializationFeature; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import gov.nasa.pds.api.engineering.controllers.MyProductsApiBareController; | ||
import gov.nasa.pds.api.engineering.elasticsearch.ElasticSearchRegistryConnection; | ||
import gov.nasa.pds.api.engineering.elasticsearch.ElasticSearchRegistrySearchRequestBuilder; | ||
import gov.nasa.pds.api.engineering.elasticsearch.ElasticSearchUtil; | ||
import gov.nasa.pds.api.engineering.elasticsearch.entities.EntityProduct; | ||
import gov.nasa.pds.api.engineering.elasticsearch.entities.EntitytProductWithBlob; | ||
import gov.nasa.pds.api.engineering.exceptions.UnsupportedElasticSearchProperty; | ||
import gov.nasa.pds.api.model.ProductWithXmlLabel; | ||
import gov.nasa.pds.model.Product; | ||
import gov.nasa.pds.model.PropertyValues; | ||
|
||
|
||
public class ProductBusinessObject { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(ProductBusinessObject.class); | ||
|
||
private static final String DEFAULT_NULL_VALUE = null; | ||
|
||
private ElasticSearchRegistryConnection elasticSearchConnection; | ||
private ElasticSearchRegistrySearchRequestBuilder searchRequestBuilder; | ||
private ObjectMapper objectMapper; | ||
|
||
static final String LIDVID_SEPARATOR = "::"; | ||
|
||
public ProductBusinessObject(ElasticSearchRegistryConnection esRegistryConnection) { | ||
this.elasticSearchConnection = esRegistryConnection; | ||
|
||
this.searchRequestBuilder = new ElasticSearchRegistrySearchRequestBuilder( | ||
this.elasticSearchConnection.getRegistryIndex(), | ||
this.elasticSearchConnection.getRegistryRefIndex(), | ||
this.elasticSearchConnection.getTimeOutSeconds()); | ||
|
||
this.objectMapper = new ObjectMapper(); | ||
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||
|
||
} | ||
|
||
|
||
public String getLatestLidVidFromLid(String lid) throws IOException { | ||
/* | ||
* if lid is a lidvid then it return the same lidvid if available in the elasticsearch database | ||
*/ | ||
|
||
|
||
lid = !(lid.contains(LIDVID_SEPARATOR))?lid+LIDVID_SEPARATOR:lid; | ||
SearchRequest searchRequest = this.searchRequestBuilder.getSearchProductRequestHasLidVidPrefix(lid); | ||
|
||
SearchResponse searchResponse = this.elasticSearchConnection.getRestHighLevelClient().search(searchRequest, | ||
RequestOptions.DEFAULT); | ||
|
||
if (searchResponse != null) { | ||
|
||
ArrayList<String> lidvids = new ArrayList<String>(); | ||
String lidvid; | ||
for (SearchHit searchHit : searchResponse.getHits()) { | ||
lidvid = (String)searchHit.getSourceAsMap().get("lidvid");; | ||
lidvids.add(lidvid); | ||
} | ||
|
||
Collections.sort(lidvids); | ||
|
||
if (lidvids.size() == 0) return lid; | ||
else return lidvids.get(lidvids.size() - 1); | ||
|
||
} | ||
else { | ||
return null; | ||
} | ||
|
||
} | ||
|
||
|
||
private static PropertyValues object2PropertyValue(Object o) { | ||
PropertyValues pv = new PropertyValues(); | ||
|
||
if (o instanceof List<?>) { | ||
for (Object p : (List<?>) o) { | ||
pv.addValuesItem(String.valueOf(p)); | ||
} | ||
|
||
} | ||
else { | ||
// TODO find a type which make String castable in PropertyValue, | ||
// currently I am desperate so I transform String in a List<String> | ||
pv.addValuesItem(String.valueOf(o)); | ||
} | ||
|
||
return pv; | ||
|
||
} | ||
|
||
|
||
/** | ||
* @param sourceAsMap source map coming from elasticSearch | ||
* @param included_fields | ||
* @param excluded_fields is ignored is included_fields is not null and not empty | ||
* @return | ||
*/ | ||
public static Map<String, PropertyValues> getFilteredProperties( | ||
Map<String, Object> sourceAsMap, | ||
List<String> included_fields, | ||
List<String> excluded_fields){ | ||
|
||
Map<String, PropertyValues> filteredMapJsonProperties = new HashMap<String, PropertyValues>(); | ||
|
||
if ((included_fields == null) || (included_fields.size() ==0)) { | ||
|
||
String apiProperty; | ||
for (Map.Entry<String, Object> entry : sourceAsMap.entrySet()) { | ||
try { | ||
apiProperty = ElasticSearchUtil.elasticPropertyToJsonProperty(entry.getKey()); | ||
if ((excluded_fields == null) | ||
|| (! excluded_fields.contains(apiProperty))) | ||
filteredMapJsonProperties.put( | ||
apiProperty, | ||
ProductBusinessObject.object2PropertyValue(entry.getValue()) | ||
); | ||
} catch (UnsupportedElasticSearchProperty e) { | ||
log.warn("ElasticSearch property " + entry.getKey() + " is not supported, ignored"); | ||
} | ||
} | ||
|
||
} | ||
else { | ||
|
||
for (String field : included_fields) { | ||
|
||
|
||
if (sourceAsMap.containsKey(ElasticSearchUtil.jsonPropertyToElasticProperty(field))) { | ||
filteredMapJsonProperties.put( | ||
field, | ||
ProductBusinessObject.object2PropertyValue(sourceAsMap.get(field)) | ||
); | ||
} | ||
else { | ||
filteredMapJsonProperties.put( | ||
field, | ||
ProductBusinessObject.object2PropertyValue(ProductBusinessObject.DEFAULT_NULL_VALUE) | ||
); | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
|
||
return filteredMapJsonProperties; | ||
|
||
|
||
} | ||
|
||
|
||
public Product getProduct(String lidvid) throws IOException { | ||
return this.getProduct(lidvid, null); | ||
} | ||
|
||
|
||
public Product getProduct(String lidvid, @Nullable List<String> fields) throws IOException { | ||
GetRequest getProductRequest = this.searchRequestBuilder.getGetProductRequest(lidvid, false); | ||
|
||
GetResponse getResponse = null; | ||
|
||
|
||
RestHighLevelClient restHighLevelClient = this.elasticSearchConnection.getRestHighLevelClient(); | ||
|
||
getResponse = restHighLevelClient.get( | ||
getProductRequest, | ||
RequestOptions.DEFAULT | ||
); | ||
|
||
if (getResponse.isExists()) { | ||
log.info("get response " + getResponse.toString()); | ||
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap(); | ||
Map<String, PropertyValues> filteredMapJsonProperties = | ||
ProductBusinessObject.getFilteredProperties(sourceAsMap, fields, null); | ||
|
||
EntityProduct entityProduct; | ||
|
||
entityProduct = this.objectMapper.convertValue(sourceAsMap, EntityProduct.class); | ||
|
||
Product product = ElasticSearchUtil.ESentityProductToAPIProduct(entityProduct); | ||
|
||
product.setProperties(filteredMapJsonProperties); | ||
|
||
return product; | ||
|
||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
|
||
|
||
public ProductWithXmlLabel getProductWithXml(String lidvid) throws IOException { | ||
return this.getProductWithXml(lidvid, null); | ||
} | ||
|
||
// TODO make the method more generic by having the name of the class we want to cast the object into instead of a boolean, the code will be more neat also | ||
public ProductWithXmlLabel getProductWithXml(String lidvid, @Nullable List<String> field) throws IOException { | ||
|
||
GetRequest getProductRequest = this.searchRequestBuilder.getGetProductRequest(lidvid, true); | ||
|
||
GetResponse getResponse = null; | ||
|
||
|
||
RestHighLevelClient restHighLevelClient = this.elasticSearchConnection.getRestHighLevelClient(); | ||
|
||
getResponse = restHighLevelClient.get( | ||
getProductRequest, | ||
RequestOptions.DEFAULT | ||
); | ||
|
||
if (getResponse.isExists()) { | ||
log.info("get response " + getResponse.toString()); | ||
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap(); | ||
|
||
try { | ||
|
||
Map<String, PropertyValues> filteredMapJsonProperties = | ||
ProductBusinessObject.getFilteredProperties( | ||
sourceAsMap, | ||
null, | ||
new ArrayList<String>(Arrays.asList(ElasticSearchUtil.elasticPropertyToJsonProperty(EntitytProductWithBlob.BLOB_PROPERTY))) | ||
); | ||
|
||
EntitytProductWithBlob entityProduct; | ||
|
||
entityProduct = this.objectMapper.convertValue(sourceAsMap, EntitytProductWithBlob.class); | ||
|
||
ProductWithXmlLabel product = ElasticSearchUtil.ESentityProductToAPIProduct(entityProduct); | ||
product.setProperties(filteredMapJsonProperties); | ||
|
||
return product; | ||
|
||
} | ||
catch (UnsupportedElasticSearchProperty e) { | ||
log.error("This should never happen " + e.getMessage()); | ||
return null; | ||
} | ||
|
||
|
||
|
||
} | ||
else { | ||
return null; | ||
} | ||
|
||
|
||
|
||
} | ||
} |