Skip to content

Commit

Permalink
add JdempotentProperty feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mehmet.ari committed Mar 7, 2022
1 parent 7424771 commit 606e16a
Show file tree
Hide file tree
Showing 23 changed files with 493 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Jdempotent-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.trendyol</groupId>
<artifactId>Jdempotent-core</artifactId>
<version>1.0.12</version>
<version>1.1.0</version>
<name>Jdempotent-core</name>
<packaging>jar</packaging>
<url>https://github.com/Trendyol/Jdempotent/tree/master/Jdempotent-core</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.trendyol.jdempotent.core.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
*
* That annotation needs to get the field name differently and generate the hash
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JdempotentProperty {
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

import com.trendyol.jdempotent.core.annotation.*;
import com.trendyol.jdempotent.core.callback.ErrorConditionalCallback;
import com.trendyol.jdempotent.core.chain.*;
import com.trendyol.jdempotent.core.constant.CryptographyAlgorithm;
import com.trendyol.jdempotent.core.datasource.IdempotentRepository;
import com.trendyol.jdempotent.core.datasource.InMemoryIdempotentRepository;
import com.trendyol.jdempotent.core.generator.DefaultKeyGenerator;
import com.trendyol.jdempotent.core.generator.KeyGenerator;
import com.trendyol.jdempotent.core.model.IdempotencyKey;
import com.trendyol.jdempotent.core.model.IdempotentIgnorableWrapper;
import com.trendyol.jdempotent.core.model.IdempotentRequestWrapper;
import com.trendyol.jdempotent.core.model.IdempotentResponseWrapper;
import com.trendyol.jdempotent.core.model.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
Expand All @@ -31,6 +30,7 @@
@Aspect
public class IdempotentAspect {
private static final Logger logger = LoggerFactory.getLogger(IdempotentAspect.class);
private AnnotationChain annotationChain;
private KeyGenerator keyGenerator;
private IdempotentRepository idempotentRepository;
private ErrorConditionalCallback errorCallback;
Expand Down Expand Up @@ -73,40 +73,47 @@ public MessageDigest get() {
public IdempotentAspect() {
this.idempotentRepository = new InMemoryIdempotentRepository();
this.keyGenerator = new DefaultKeyGenerator();
this.annotationChain = fillChains();
}

public IdempotentAspect(ErrorConditionalCallback errorCallback) {
this.errorCallback = errorCallback;
this.idempotentRepository = new InMemoryIdempotentRepository();
this.keyGenerator = new DefaultKeyGenerator();
this.annotationChain = fillChains();
}

public IdempotentAspect(IdempotentRepository idempotentRepository) {
this.idempotentRepository = idempotentRepository;
this.keyGenerator = new DefaultKeyGenerator();
this.annotationChain = fillChains();
}

public IdempotentAspect(IdempotentRepository idempotentRepository, ErrorConditionalCallback errorCallback) {
this.idempotentRepository = idempotentRepository;
this.errorCallback = errorCallback;
this.keyGenerator = new DefaultKeyGenerator();
this.annotationChain = fillChains();
}

public IdempotentAspect(ErrorConditionalCallback errorCallback, DefaultKeyGenerator keyGenerator) {
this.errorCallback = errorCallback;
this.idempotentRepository = new InMemoryIdempotentRepository();
this.keyGenerator = keyGenerator;
this.annotationChain = fillChains();
}

public IdempotentAspect(IdempotentRepository idempotentRepository, DefaultKeyGenerator keyGenerator) {
this.idempotentRepository = idempotentRepository;
this.keyGenerator = keyGenerator;
this.annotationChain = fillChains();
}

public IdempotentAspect(IdempotentRepository idempotentRepository, ErrorConditionalCallback errorCallback, DefaultKeyGenerator keyGenerator) {
this.idempotentRepository = idempotentRepository;
this.errorCallback = errorCallback;
this.keyGenerator = keyGenerator;
this.annotationChain = fillChains();
}

/**
Expand Down Expand Up @@ -253,16 +260,12 @@ public IdempotentIgnorableWrapper getIdempotentNonIgnorableWrapper(Object args)
wrapper.getNonIgnoredFields().put(args.toString(), args);
return wrapper;
}

for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
if (declaredField.getDeclaredAnnotations().length == 0) {
wrapper.getNonIgnoredFields().put(declaredField.getName(), declaredField.get(args));
} else {
for (Annotation annotation : declaredField.getDeclaredAnnotations()) {
if (!(annotation instanceof JdempotentIgnore)) {
wrapper.getNonIgnoredFields().put(declaredField.getName(), declaredField.get(args));
}
}
KeyValuePair keyValuePair = annotationChain.process(new ChainData(declaredField,args));
if (!StringUtils.isEmpty(keyValuePair.getKey())){
wrapper.getNonIgnoredFields().put(keyValuePair.getKey(), keyValuePair.getValue());
}
}
return wrapper;
Expand All @@ -283,4 +286,16 @@ public void setIdempotentRepository(IdempotentRepository idempotentRepository) {
public IdempotentRepository getIdempotentRepository() {
return idempotentRepository;
}

private AnnotationChain fillChains(){
JdempotentNoAnnotationChain jdempotentNoAnnotationChain = new JdempotentNoAnnotationChain();
JdempotentIgnoreAnnotationChain jdempotentIgnoreAnnotationChain = new JdempotentIgnoreAnnotationChain();
JdempotentDefaultChain jdempotentDefaultChain = new JdempotentDefaultChain();
JdempotentPropertyAnnotationChain jdempotentPropertyAnnotationChain = new JdempotentPropertyAnnotationChain();

jdempotentNoAnnotationChain.next(jdempotentIgnoreAnnotationChain);
jdempotentIgnoreAnnotationChain.next(jdempotentPropertyAnnotationChain);
jdempotentPropertyAnnotationChain.next(jdempotentDefaultChain);
return jdempotentIgnoreAnnotationChain;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.trendyol.jdempotent.core.chain;

import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;

public abstract class AnnotationChain {
protected AnnotationChain nextChain;

public abstract KeyValuePair process(ChainData chainData) throws IllegalAccessException;

public void next(AnnotationChain nextChain) {
this.nextChain = nextChain;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.trendyol.jdempotent.core.chain;

import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;

import java.lang.reflect.Field;

public class JdempotentDefaultChain extends AnnotationChain {

@Override
public KeyValuePair process(ChainData chainData) throws IllegalAccessException {
Field declaredField = chainData.getDeclaredField();
declaredField.setAccessible(true);
return new KeyValuePair(declaredField.getName(),declaredField.get(chainData.getArgs()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.trendyol.jdempotent.core.chain;

import com.trendyol.jdempotent.core.annotation.JdempotentIgnore;
import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;

import java.lang.reflect.Field;

public class JdempotentIgnoreAnnotationChain extends AnnotationChain {
@Override
public KeyValuePair process(ChainData chainData) throws IllegalAccessException {
Field declaredField = chainData.getDeclaredField();
declaredField.setAccessible(true);
JdempotentIgnore annotation = declaredField.getAnnotation(JdempotentIgnore.class);
if(annotation != null){
return new KeyValuePair();
}
return super.nextChain.process(chainData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.trendyol.jdempotent.core.chain;

import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;

import java.lang.reflect.Field;

public class JdempotentNoAnnotationChain extends AnnotationChain {

@Override
public KeyValuePair process(ChainData chainData) throws IllegalAccessException {
if (chainData.getDeclaredField().getDeclaredAnnotations().length == 0) {
Field declaredField = chainData.getDeclaredField();
declaredField.setAccessible(true);
return new KeyValuePair(declaredField.getName(),declaredField.get(chainData.getArgs()));
}
return super.nextChain.process(chainData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.trendyol.jdempotent.core.chain;

import com.trendyol.jdempotent.core.annotation.JdempotentProperty;
import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;

import java.lang.reflect.Field;

public class JdempotentPropertyAnnotationChain extends AnnotationChain {

@Override
public KeyValuePair process(ChainData chainData) throws IllegalAccessException {
Field declaredField = chainData.getDeclaredField();
declaredField.setAccessible(true);
JdempotentProperty annotation = declaredField.getAnnotation(JdempotentProperty.class);
if(annotation != null){
return new KeyValuePair(annotation.value(),declaredField.get(chainData.getArgs()));
}
return super.nextChain.process(chainData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.trendyol.jdempotent.core.model;

import java.lang.reflect.Field;

public class ChainData {
private Field declaredField;
private Object args;

public ChainData(){
}

public ChainData(Field declaredField, Object args) {
this.declaredField = declaredField;
this.args = args;
}

public Field getDeclaredField() {
return declaredField;
}

public void setDeclaredField(Field declaredField) {
this.declaredField = declaredField;
}

public Object getArgs() {
return args;
}

public void setArgs(Object args) {
this.args = args;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.trendyol.jdempotent.core.model;

public class KeyValuePair {
private String key;
private Object value;

public KeyValuePair(){}

public KeyValuePair(String key, Object value) {
this.key = key;
this.value = value;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public Object getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package aspect.chain;

import aspect.core.IdempotentTestPayload;
import com.trendyol.jdempotent.core.chain.JdempotentDefaultChain;
import com.trendyol.jdempotent.core.model.ChainData;
import com.trendyol.jdempotent.core.model.KeyValuePair;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)
public class JdempotentDefaultChainTest {

@InjectMocks
private JdempotentDefaultChain jdempotentDefaultChain;

@Test
public void should_process_with_no_annotation() throws IllegalAccessException, NoSuchFieldException {
//Given
IdempotentTestPayload idempotentTestPayload = new IdempotentTestPayload();
idempotentTestPayload.setName("value");
ChainData chainData = new ChainData();
chainData.setArgs(idempotentTestPayload);
chainData.setDeclaredField(idempotentTestPayload.getClass().getDeclaredField("name"));

//When
KeyValuePair process = jdempotentDefaultChain.process(chainData);

//Then
assertEquals("name", process.getKey());
assertEquals("value", process.getValue());
}

@Test
public void should_process_with_another_annotated_property() throws IllegalAccessException, NoSuchFieldException {
//Given
IdempotentTestPayload idempotentTestPayload = new IdempotentTestPayload();
idempotentTestPayload.setEventId(1l);
ChainData chainData = new ChainData();
chainData.setArgs(idempotentTestPayload);
chainData.setDeclaredField(idempotentTestPayload.getClass().getDeclaredField("eventId"));

//When
KeyValuePair process = jdempotentDefaultChain.process(chainData);

//Then
assertEquals("eventId", process.getKey());
assertEquals(1l, process.getValue());
}
}
Loading

0 comments on commit 606e16a

Please sign in to comment.