Skip to content

Commit

Permalink
code review
Browse files Browse the repository at this point in the history
  • Loading branch information
gjeanmart committed Jun 9, 2019
1 parent a8d14be commit b8b0c8d
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import net.consensys.mahuta.core.exception.TimeoutException;
import net.consensys.mahuta.core.utils.BytesUtils;
import net.consensys.mahuta.core.utils.ValidatorUtils;
import net.consensys.mahuta.core.utils.lamba.Throwing;
import net.consensys.mahuta.springdata.MahutaCustomRepository;
import net.consensys.mahuta.springdata.annotation.Fulltext;
import net.consensys.mahuta.springdata.annotation.Hash;
Expand All @@ -64,8 +65,7 @@ public abstract class MahutaCustomRepositoryImpl<E> implements MahutaCustomRepos

protected static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
protected static final String DEFAULT_CONTENT_TYPE = "application/json";
protected static final String DEFAULT_ATTRIBUTE_ID = "id";
protected static final String DEFAULT_ATTRIBUTE_HASH = "hash";
protected static final boolean DEFAULT_INDEX_CONTENT = false;
protected static final Class<?> ID_CLASS = String.class;
protected static final Class<?> HASH_CLASS = String.class;

Expand All @@ -88,25 +88,29 @@ public abstract class MahutaCustomRepositoryImpl<E> implements MahutaCustomRepos

@SuppressWarnings("unchecked")
public MahutaCustomRepositoryImpl(Mahuta mahuta) {

this.mahuta = mahuta;

// Configure Jackson
this.mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);


// Get Entity class
this.entityClazz = (Class<E>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];


// Check if annotation @IPFSDocument
String indexConfigurationPath = null;
InputStream indexConfiguration = null;

try {
this.mahuta = mahuta;

// Configure Jackson
this.mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);


// Get Entity class
this.entityClazz = (Class<E>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

// Check if annotation @IPFSDocument
if (!entityClazz.isAnnotationPresent(IPFSDocument.class)) {
throw new MahutaSpringDataRuntimeException("The class " + entityClazz.getSimpleName() + " is not annotated with IPFSDocument");
}
if (!entityClazz.isAnnotationPresent(IPFSDocument.class)) {
this.indexName = entityClazz.getSimpleName();
this.indexContent = DEFAULT_INDEX_CONTENT;

} else {
IPFSDocument ipfsDocumentAnnotation = entityClazz.getAnnotation(IPFSDocument.class);

// Extract indexName, if null, take class name
Expand All @@ -116,48 +120,42 @@ public MahutaCustomRepositoryImpl(Mahuta mahuta) {
// Extract indexContent flag
this.indexContent = ipfsDocumentAnnotation.indexContent();

// Extract indexConfiguration path and read file if presend
indexConfiguration = !StringUtils.isEmpty(ipfsDocumentAnnotation.indexConfiguration())
? BytesUtils.readFileInputStream(ipfsDocumentAnnotation.indexConfiguration()) : null;

// Find @Id annotation
attributeId = EntityFieldUtils.extractOptionalSingleAnnotatedField(entityClazz, Id.class, ID_CLASS);

// Find @Hash annotation
attributeHash = EntityFieldUtils.extractOptionalSingleAnnotatedField(entityClazz, Hash.class, HASH_CLASS);

// Find @Fulltext annotation
List<EntityField> fulltextdAnnotation = EntityFieldUtils.extractMultipleAnnotatedFields(entityClazz, Fulltext.class);
this.fullTextFields = Sets.newHashSet(fulltextdAnnotation);

// Find @Indexfield annotation
List<EntityField> indexfieldAnnotation = EntityFieldUtils.extractMultipleAnnotatedFields(entityClazz, Indexfield.class);
this.indexFields = Sets.newHashSet(indexfieldAnnotation);
this.indexFields.addAll(fullTextFields);

// Create index
mahuta.prepareCreateIndex(indexName).configuration(indexConfiguration).execute();

log.info("MahutaRepository configured for class {}", entityClazz.getSimpleName());
log.trace("indexName: {}", indexName);
log.trace("indexContent: {}", indexContent);
log.trace("indexConfiguration: {}", ipfsDocumentAnnotation.indexConfiguration());
log.trace("attributeId: {}", attributeId);
log.trace("attributeHash: {}", attributeHash);
log.trace("indexfieldAnnotation: {}", indexfieldAnnotation);
log.trace("fullTextFields: {}", fullTextFields);

} catch(Exception ex) {
if(indexConfiguration != null)
try {
indexConfiguration.close();
} catch (IOException ioex) {
log.error("Error while closing indexConfiguration", ioex);
}

log.error("Error while instantiating the Mahuta repository", ex);
throw ex;
// Extract indexConfiguration path and read file if present
indexConfigurationPath = ipfsDocumentAnnotation.indexConfiguration();
indexConfiguration = !StringUtils.isEmpty(indexConfigurationPath)
? BytesUtils.readFileInputStream(indexConfigurationPath) : null;
}


// Find @Id annotation
attributeId = EntityFieldUtils.extractOptionalSingleAnnotatedField(entityClazz, Id.class, ID_CLASS);


// Find @Hash annotation
attributeHash = EntityFieldUtils.extractOptionalSingleAnnotatedField(entityClazz, Hash.class, HASH_CLASS);


// Find @Fulltext annotation
this.fullTextFields = Sets.newHashSet(EntityFieldUtils.extractMultipleAnnotatedFields(entityClazz, Fulltext.class));


// Find @Indexfield annotation
this.indexFields = Sets.newHashSet(EntityFieldUtils.extractMultipleAnnotatedFields(entityClazz, Indexfield.class));
this.indexFields.addAll(fullTextFields);


// Create index
mahuta.prepareCreateIndex(indexName).configuration(indexConfiguration).execute();


log.info("MahutaRepository configured for class {}", entityClazz.getSimpleName());
log.trace("indexName: {}", indexName);
log.trace("indexContent: {}", indexContent);
log.trace("indexConfiguration: {}", indexConfigurationPath);
log.trace("attributeId: {}", attributeId);
log.trace("attributeHash: {}", attributeHash);
log.trace("indexfieldAnnotation: {}", indexFields);
log.trace("fullTextFields: {}", fullTextFields);
}

@Override
Expand All @@ -182,10 +180,10 @@ public Page<E> findByfullTextSearch(String fullTextCriteria, Pageable pagination

@Override
public Optional<E> findByHash(String hash) {

log.debug("Find By Hash [hash: {}]", hash);

try {
log.debug("Find By Hash [hash: {}]", hash);

GetResponse response = mahuta.prepareGet().indexName(indexName).contentId(hash).loadFile(true).execute();

E entity = deserialize(response.getPayload(), hash);
Expand All @@ -194,9 +192,13 @@ public Optional<E> findByHash(String hash) {

return Optional.of(entity);

} catch (NotFoundException | TimeoutException e) {
log.warn("File [hash: {}] not found", hash, e);
} catch (NotFoundException | TimeoutException ex) {
log.warn("File [hash: {}] not found", hash, ex);
return Optional.empty();

} catch (IllegalAccessException | InvocationTargetException|IOException ex) {
log.warn("Error while deserialising entity", ex);
throw new MahutaSpringDataRuntimeException("Error while deserialising entity", ex);
}
}

Expand All @@ -205,11 +207,17 @@ public String saveNoIndexation(E entity) {

log.debug("Saving entity (no indexation) [entity: {}]", entity);

IndexingResponse response = mahuta.prepareStorage(serialize(entity)).execute();
try {
IndexingResponse response = mahuta.prepareStorage(serialize(entity)).execute();

log.debug("Entity {} saved. {}", entity, response.getContentId());

log.debug("Entity {} saved. {}", entity, response.getContentId());
return response.getContentId();

return response.getContentId();
} catch (IOException ex) {
log.error("Error while serializing object {}", entity, ex);
throw new MahutaSpringDataRuntimeException("Error while deserialising object " + entity, ex);
}
}

protected Page<E> search(Query query, Pageable pageable) {
Expand All @@ -220,51 +228,34 @@ protected Page<E> search(Query query, Pageable pageable) {
.pageRequest(MahutaSpringDataUtils.convertPageable(pageable)).loadFile(true).execute();

List<E> result = response.getPage().getElements().stream()
.map(mp -> deserialize(mp.getPayload(), mp.getMetadata().getContentId()))
.map(Throwing.rethrowFunc(mp -> deserialize(mp.getPayload(), mp.getMetadata().getContentId())))
.collect(Collectors.toList());

return new PageImpl<>(result, pageable, response.getPage().getTotalElements());
}

protected E deserialize(OutputStream content, String hash) {
protected E deserialize(OutputStream content, String hash) throws IOException, IllegalAccessException, InvocationTargetException {

ValidatorUtils.rejectIfNull("content", content);

E entity;
try {
entity = this.mapper.readValue(((ByteArrayOutputStream) content).toByteArray(), entityClazz);
} catch (IOException ex) {
log.error("Error while parsing json", ex);
throw new MahutaSpringDataRuntimeException("Error while parsing json", ex);
}

try {
if(attributeHash.isPresent()) {
attributeHash.get().invokeSetter(entity, hash);
}
E entity = this.mapper.readValue(((ByteArrayOutputStream) content).toByteArray(), entityClazz);

return entity;

} catch (IllegalAccessException | InvocationTargetException ex) {
log.error("Error while invoking set{}", attributeHash, ex);
throw new MahutaSpringDataRuntimeException("Error while invoking set" + attributeHash, ex);
if(attributeHash.isPresent()) {
attributeHash.get().invokeSetter(entity, hash);
}

return entity;
}

protected InputStream serialize(E e) {
protected InputStream serialize(E e) throws JsonProcessingException {

try {
// Programmatically JSONIgnore @Hash annotated field
JsonView<E> view = JsonView.with(e);
if(attributeHash.isPresent()) {
view.onClass(entityClazz, match().exclude(attributeHash.get().getName()));
}

return new ByteArrayInputStream(this.mapper.writeValueAsString(view).getBytes(DEFAULT_ENCODING));
} catch (JsonProcessingException ex) {
log.error("Error while serialising the entity [entity={}]", e, ex);
throw new MahutaSpringDataRuntimeException("Error while serialising the entity [entity="+e+"]", ex);
// Programmatically JSONIgnore @Hash annotated field
JsonView<E> view = JsonView.with(e);
if(attributeHash.isPresent()) {
view.onClass(entityClazz, match().exclude(attributeHash.get().getName()));
}

return new ByteArrayInputStream(this.mapper.writeValueAsString(view).getBytes(DEFAULT_ENCODING));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.consensys.mahuta.springdata.impl;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
Expand All @@ -11,12 +12,15 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import com.fasterxml.jackson.core.JsonProcessingException;

import lombok.extern.slf4j.Slf4j;
import net.consensys.mahuta.core.Mahuta;
import net.consensys.mahuta.core.domain.get.GetResponse;
import net.consensys.mahuta.core.domain.indexing.IndexingResponse;
import net.consensys.mahuta.core.exception.NotFoundException;
import net.consensys.mahuta.springdata.MahutaRepository;
import net.consensys.mahuta.springdata.exception.MahutaSpringDataRuntimeException;

@Slf4j
public class MahutaRepositoryImpl<E, I extends Serializable> extends MahutaCustomRepositoryImpl<E>
Expand Down Expand Up @@ -64,7 +68,7 @@ public <S extends E> S save(S entity, Map<String, Object> externalIndexFields) {

return entity;

} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
} catch (JsonProcessingException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
log.error("Error while saving the entity [entity: {}, external_index_fields: {}]", entity,
externalIndexFields, e);
return null;
Expand All @@ -91,6 +95,9 @@ public Optional<E> findById(I id) {
} catch (NotFoundException e) {
log.error("Entity not found [id={}]", id);
return Optional.empty();
} catch (IllegalAccessException | InvocationTargetException | IOException e) {
log.error("Error while deserialising object", e);
throw new MahutaSpringDataRuntimeException("Error while deserialising object", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import net.consensys.mahuta.springdata.exception.MahutaSpringDataRuntimeException;

public class EntityField {

private String name;
Expand Down Expand Up @@ -39,7 +41,7 @@ public Method getSetter() {

public void invokeSetter(Object entity, Object value) throws IllegalAccessException, InvocationTargetException {
if(!type.isInstance(value)) {
throw new RuntimeException("invokeSetter - Expected value to set of type " + type.getSimpleName() + " but was " +value.getClass().getSimpleName());
throw new MahutaSpringDataRuntimeException("invokeSetter - Expected value to set of type " + type.getSimpleName() + " but was " +value.getClass().getSimpleName());
}

setter.invoke(entity, value);
Expand All @@ -53,7 +55,7 @@ public <T> T invokeGetter(Object entity, Class<T> type) throws IllegalAccessExce
}

if(!type.isInstance(value)) {
throw new RuntimeException("invokeGetter - Expected value retrieved of type " + type.getSimpleName() + " but was " + value.getClass().getSimpleName());
throw new MahutaSpringDataRuntimeException("invokeGetter - Expected value retrieved of type " + type.getSimpleName() + " but was " + value.getClass().getSimpleName());
}
return type.cast(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.stream.Collectors;

import net.consensys.mahuta.core.utils.lamba.Throwing;
import net.consensys.mahuta.springdata.exception.MahutaSpringDataRuntimeException;
import net.consensys.mahuta.springdata.model.EntityField;

public class EntityFieldUtils {
Expand All @@ -19,19 +20,17 @@ public static <E, A extends Annotation, T> Optional<EntityField> extractOptional
Optional<EntityField> entityField = extractOptionalSingleAnnotatedField(entityClass, annotationClass);

if(entityField.isPresent() && !entityField.get().getType().equals(expectedType)) {
throw new RuntimeException(String.format("Expected to find one annotation %s in the class %s typed %s (found type %s)", annotationClass.getSimpleName(), entityClass.getSimpleName(), expectedType.getSimpleName(), entityField.get().getType()));
throw new MahutaSpringDataRuntimeException(String.format("Expected to find one annotation %s in the class %s typed %s (found type %s)", annotationClass.getSimpleName(), entityClass.getSimpleName(), expectedType.getSimpleName(), entityField.get().getType()));
}

return entityField;
}



public static <E, A extends Annotation> Optional<EntityField> extractOptionalSingleAnnotatedField(Class<E> entityClass, Class<A> annotationClass) {
List<EntityField> entityFields = extractMultipleAnnotatedFields(entityClass, annotationClass);

if(entityFields.size() > 1) {
throw new RuntimeException(String.format("Expected to find only ONE annotation %s in the class %s (found %s)", annotationClass.getSimpleName(), entityClass.getSimpleName(), entityFields.size()));
throw new MahutaSpringDataRuntimeException(String.format("Expected to find only ONE annotation %s in the class %s (found %s)", annotationClass.getSimpleName(), entityClass.getSimpleName(), entityFields.size()));
}

if(entityFields.isEmpty()) {
Expand All @@ -46,7 +45,7 @@ public static <E, A extends Annotation> EntityField extractUniqueSingleAnnotated
Optional<EntityField> entityField = extractOptionalSingleAnnotatedField(entityClass, annotationClass);

if(!entityField.isPresent()) {
throw new RuntimeException(String.format("Expected to find annotation %s in the class %s", annotationClass.getSimpleName(), entityClass.getSimpleName()));
throw new MahutaSpringDataRuntimeException(String.format("Expected to find annotation %s in the class %s", annotationClass.getSimpleName(), entityClass.getSimpleName()));
}

return entityField.get();
Expand Down
2 changes: 1 addition & 1 deletion mahuta-springdata/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</encoder>
</appender>

<logger name="net.consensys.mahuta" level="trace" additivity="false">
<logger name="net.consensys.mahuta" level="info" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>

Expand Down

0 comments on commit b8b0c8d

Please sign in to comment.