Skip to content

Instantly share code, notes, and snippets.

@fabiojose
Created June 2, 2020 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabiojose/d7387ccd2fdbcd2d65dad27a79e8ff13 to your computer and use it in GitHub Desktop.
Save fabiojose/d7387ccd2fdbcd2d65dad27a79e8ff13 to your computer and use it in GitHub Desktop.
Apache Avro GenericRecords with MapStruct example
package petstore.catalog.elasticsearch;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.avro.generic.GenericRecord;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Qualifier;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
* @author fabiojose
*/
@Data
@Document(indexName = "catalogs", type = "item")
public class CatalogItemEntity {
@Id
private String id;
private String catalogId;
private String productId;
private String productName;
private String productDescription;
private Double price;
private String imageUrl;
@Mapper(
componentModel = "spring"
)
public interface EntityMapper {
@Mapping(target = "id",
expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(
source = "item",
target = "catalogId",
qualifiedBy = CatalogId.class)
@Mapping(source = "item",
target = "productId",
qualifiedBy = ProductId.class)
@Mapping(source = "item",
target = "productName",
qualifiedBy = ProductName.class)
@Mapping(source = "item",
target = "productDescription",
qualifiedBy = ProductDescription.class)
@Mapping(source = "item",
target = "price",
qualifiedBy = Price.class)
@Mapping(source = "item",
target = "imageUrl",
qualifiedBy = ImageUrl.class)
CatalogItemEntity map(Wrapper avro);
/**
* To wrapper the {@link GenericRecord}
*/
@Getter
@AllArgsConstructor
public static class Wrapper {
private GenericRecord item;
}
default Object getObject(String key, GenericRecord g) {
GenericRecord data = (GenericRecord)g.get("data");
if(null == data) {
return null;
}
return data.get(key);
}
default String getString(String key, GenericRecord g){
GenericRecord data = (GenericRecord)g.get("data");
if(null== data){
return null;
}
CharSequence cs = (CharSequence)data.get(key);
return cs.toString();
}
@CatalogId
default String catalogId(GenericRecord g){
return getString("catalogId", g);
}
@ProductId
default String productIdOf(GenericRecord g) {
return getString("productId", g);
}
@ProductName
default String productNameOf(GenericRecord g){
return getString("productName", g);
}
@ProductDescription
default String productDecriptionOf(GenericRecord g){
return getString("productDescription", g);
}
@Price
default Double price(GenericRecord g) {
Object priceObj = getObject("price", g);
if(null == priceObj) {
return null;
}
return (Double)priceObj;
}
@ImageUrl
default String imageUrlOf(GenericRecord r) {
return getString("image", r);
}
@Qualifier
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface CatalogId {}
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface ProductId {}
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface ProductName {}
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface ProductDescription {}
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public static @interface Price {}
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@interface ImageUrl {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment