Skip to content

Commit

Permalink
Update Result Models and Add List fetching functionality to ElasticRe…
Browse files Browse the repository at this point in the history
…stClient
  • Loading branch information
rimonmostafiz committed Aug 26, 2020
1 parent e135f90 commit 38f70bf
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 9 deletions.
@@ -1,13 +1,19 @@
package com.rimonmostafiz.elasticlight.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rimonmostafiz.elasticlight.core.Command;
import com.rimonmostafiz.elasticlight.model.result.SearchResult;
import com.rimonmostafiz.elasticlight.util.RestUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
* @author Rimon Mostafiz
*/
Expand All @@ -16,8 +22,10 @@
@RequiredArgsConstructor
public class ElasticRestClient {
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;

String request(Command c) {
public <T> Optional<SearchResult<T>> searchRequest(Command c, Class<T> klass) throws Exception {
log.debug("Command: {}", c);
String uri = c.getPath();
HttpMethod method = c.getVerb().resolve();

Expand All @@ -27,9 +35,19 @@ String request(Command c) {

ResponseEntity<String> response = restTemplate.exchange(uri, method, entity, String.class);
if (RestUtils.isOkAndHasBody(response)) {
return response.getBody();
String body = response.getBody();
log.debug("Response Body: {}", body);
SearchResult<T> searchResult = RestUtils.extractSearchResult(body, klass, objectMapper);
return Optional.ofNullable(searchResult);
} else {
return "";
return Optional.empty();
}
}

public <T> List<T> requestForList(Command c, Class<T> klass) throws Exception {
Optional<SearchResult<T>> searchResult = searchRequest(c, klass);
return searchResult
.map(RestUtils::extractObjectList)
.orElseGet(Collections::emptyList);
}
}
@@ -0,0 +1,32 @@
package com.rimonmostafiz.elasticlight.component;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
* @author Rimon Mostafiz
*/
public class EsParameterizedType implements ParameterizedType {
private final ParameterizedType parameterizedType;
private final Type[] actualTypes;

public EsParameterizedType(ParameterizedType parameterizedType, Type[] actualTypes) {
this.parameterizedType = parameterizedType;
this.actualTypes = actualTypes;
}

@Override
public Type[] getActualTypeArguments() {
return actualTypes;
}

@Override
public Type getRawType() {
return parameterizedType.getRawType();
}

@Override
public Type getOwnerType() {
return parameterizedType.getOwnerType();
}
}
Expand Up @@ -12,27 +12,27 @@ public CommandBuilder() {
this.command = new Command();
}

public CommandBuilder verb(Verb verb) {
public CommandBuilder withVerb(Verb verb) {
this.command.setVerb(verb);
return this;
}

public CommandBuilder path(String path) {
public CommandBuilder withPath(String path) {
this.command.setPath(path);
return this;
}

public CommandBuilder query(String query) {
public CommandBuilder withQuery(String query) {
this.command.setBody(query);
return this;
}

private CommandBuilder query(Query query) {
public CommandBuilder withQuery(Query query) {
this.command.setBody(query.toString());
return this;
}

public CommandBuilder head(Head head) {
public CommandBuilder withHead(Head head) {
this.command.setHead(head);
return this;
}
Expand Down
@@ -0,0 +1,24 @@
package com.rimonmostafiz.elasticlight.model.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author Rimon Mostafiz
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EsHit<T> {

@JsonProperty("_index")
private String index;

@JsonProperty("_type")
private String type;

@JsonProperty("_source")
private T source;
}
@@ -0,0 +1,19 @@
package com.rimonmostafiz.elasticlight.model.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.List;

/**
* @author Rimon Mostafiz
*/
@Data
@ToString
@NoArgsConstructor
public class Hits<T> {
@JsonProperty("hits")
private List<EsHit<T>> esHits;
}
@@ -0,0 +1,21 @@
package com.rimonmostafiz.elasticlight.model.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author Rimon Mostafiz
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SearchResult<T> {
@JsonProperty("_shards")
private Shards shards;
private Hits<T> hits;
private Integer took;
@JsonProperty("timed_out")
private boolean timedOut;
}
@@ -0,0 +1,18 @@
package com.rimonmostafiz.elasticlight.model.result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author Rimon Mostafiz
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Shards {
private Integer total;
private Integer failed;
private Integer successful;
private Integer skipped;
}
@@ -0,0 +1,17 @@
package com.rimonmostafiz.elasticlight.model.result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
* @author Rimon Mostafiz
*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Source<T> {
T obj;
}
30 changes: 30 additions & 0 deletions src/main/java/com/rimonmostafiz/elasticlight/util/RestUtils.java
@@ -1,15 +1,27 @@
package com.rimonmostafiz.elasticlight.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.rimonmostafiz.elasticlight.component.EsParameterizedType;
import com.rimonmostafiz.elasticlight.model.result.SearchResult;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;

/**
* @author Rimon Mostafiz
*/
@RequiredArgsConstructor
public class RestUtils {

private static final ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();

public static String beanToPrettyJSON(Object o) {
Expand All @@ -23,4 +35,22 @@ public static String beanToPrettyJSON(Object o) {
public static boolean isOkAndHasBody(ResponseEntity<String> responseEntity) {
return responseEntity.getStatusCode().is2xxSuccessful() && StringUtils.isNotEmpty(responseEntity.getBody());
}

public static <T> SearchResult<T> extractSearchResult(String result, Class<T> klass, ObjectMapper objectMapper)
throws Exception {
TypeReference<SearchResult<T>> typeReference = new TypeReference<SearchResult<T>>() {
@Override
public Type getType() {
return new EsParameterizedType((ParameterizedType) super.getType(), new Type[]{klass});
}
};
JsonNode hits = objectMapper.readTree(result);
return objectMapper.convertValue(hits, typeReference);
}

public static <T> List<T> extractObjectList(SearchResult<T> searchResult) {
List<T> list = new java.util.ArrayList<>(Collections.emptyList());
searchResult.getHits().getEsHits().forEach(e -> list.add(e.getSource()));
return list;
}
}
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
@@ -1,4 +1,4 @@
elastic-light.elasticsearch.rest.uris=localhost:9200
elastic-light.elasticsearch.rest.uris=http://192.168.5.212:9200
elastic-light.rest-template.read.timeout=30
elastic-light.rest-template.connect.timeout=30
logging.level.root=INFO
Expand Down

0 comments on commit 38f70bf

Please sign in to comment.