Skip to content

Commit 427aedc

Browse files
jianggangjianggang
andauthored
feat: targeting version (#10)
* feat: targeting version * feat: targeting version * feat: targeting version * feat: targeting version Co-authored-by: jianggang <jianggang@didiglobal.com>
1 parent f61ae95 commit 427aedc

21 files changed

Lines changed: 316 additions & 33 deletions

src/main/java/com/featureprobe/api/controller/TargetingController.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
import com.featureprobe.api.base.doc.ToggleKeyParameter;
99
import com.featureprobe.api.dto.TargetingRequest;
1010
import com.featureprobe.api.dto.TargetingResponse;
11+
import com.featureprobe.api.dto.TargetingVersionRequest;
12+
import com.featureprobe.api.dto.TargetingVersionResponse;
1113
import com.featureprobe.api.service.TargetingService;
1214
import com.featureprobe.api.validate.ResourceExistsValidate;
1315
import io.swagger.v3.oas.annotations.Operation;
1416
import io.swagger.v3.oas.annotations.tags.Tag;
1517
import lombok.AllArgsConstructor;
1618
import lombok.extern.slf4j.Slf4j;
19+
import org.springframework.data.domain.Page;
1720
import org.springframework.validation.annotation.Validated;
1821
import org.springframework.web.bind.annotation.GetMapping;
1922
import org.springframework.web.bind.annotation.PatchMapping;
@@ -58,5 +61,13 @@ public TargetingResponse query(
5861
return targetingService.queryByKey(projectKey, environmentKey, toggleKey);
5962
}
6063

61-
64+
@GetApiResponse
65+
@GetMapping("/versions")
66+
@Operation(summary = "Get targeting versions", description = "Get targeting version history.")
67+
public Page<TargetingVersionResponse> versions(
68+
@PathVariable("projectKey") String projectKey,
69+
@PathVariable("environmentKey") String environmentKey,
70+
TargetingVersionRequest targetingVersionRequest) {
71+
return targetingService.queryVersions(projectKey, environmentKey, targetingVersionRequest);
72+
}
6273
}

src/main/java/com/featureprobe/api/dto/SegmentSearchRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
public class SegmentSearchRequest extends PaginationRequest {
77

88
private String keyword;
9+
10+
private Boolean includeDeleted = false;
911
}

src/main/java/com/featureprobe/api/dto/TargetingRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import com.featureprobe.api.model.TargetingContent;
44
import lombok.Data;
55

6+
import javax.validation.constraints.NotBlank;
7+
68
@Data
79
public class TargetingRequest {
810

911
private TargetingContent content;
1012

13+
private String comment;
14+
1115
private Boolean disabled;
1216
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.featureprobe.api.dto;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class TargetingVersionRequest extends PaginationRequest{
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.featureprobe.api.dto;
2+
3+
import com.featureprobe.api.model.TargetingContent;
4+
import lombok.Data;
5+
6+
import java.util.Date;
7+
8+
@Data
9+
public class TargetingVersionResponse {
10+
11+
private String projectKey;
12+
13+
private String environmentKey;
14+
15+
private String comment;
16+
17+
private TargetingContent content;
18+
19+
private Long version;
20+
21+
private Date createdTime;
22+
23+
private String createdBy;
24+
}

src/main/java/com/featureprobe/api/entity/Segment.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public class Segment extends AbstractAuditEntity {
3232
@Column(name = "[key]")
3333
private String key;
3434

35+
@Column(name = "unique_Key")
36+
private String uniqueKey;
37+
3538
private String description;
3639

3740
@Column(name = "project_key")
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.featureprobe.api.entity;
2+
3+
import com.featureprobe.api.base.entity.AbstractAuditEntity;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.EqualsAndHashCode;
8+
import lombok.NoArgsConstructor;
9+
import lombok.ToString;
10+
import org.hibernate.annotations.DynamicInsert;
11+
import org.hibernate.annotations.Where;
12+
13+
import javax.persistence.Column;
14+
import javax.persistence.Entity;
15+
import javax.persistence.Table;
16+
17+
@EqualsAndHashCode(callSuper = true)
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
@Data
21+
@Builder
22+
@Entity
23+
@Table(name = "targeting_version")
24+
@Where(clause = "deleted = 0")
25+
@DynamicInsert
26+
@ToString(callSuper = true)
27+
public class TargetingVersion extends AbstractAuditEntity {
28+
29+
@Column(name = "targeting_id")
30+
private Long targetingId;
31+
32+
@Column(name = "project_key")
33+
private String projectKey;
34+
35+
@Column(name = "environment_key")
36+
private String environmentKey;
37+
38+
private String comment;
39+
40+
private String content;
41+
42+
private Long version;
43+
44+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.featureprobe.api.mapper;
2+
3+
import com.featureprobe.api.dto.TargetingVersionResponse;
4+
import com.featureprobe.api.entity.TargetingVersion;
5+
import com.featureprobe.api.model.TargetingContent;
6+
import org.apache.commons.lang3.StringUtils;
7+
import org.mapstruct.Mapper;
8+
import org.mapstruct.Mapping;
9+
import org.mapstruct.factory.Mappers;
10+
11+
@Mapper
12+
public interface TargetingVersionMapper {
13+
14+
TargetingVersionMapper INSTANCE = Mappers.getMapper(TargetingVersionMapper.class);
15+
16+
@Mapping(target = "content",
17+
expression = "java(toTargetingContent(targetingVersion.getContent()))")
18+
TargetingVersionResponse entityToResponse(TargetingVersion targetingVersion);
19+
20+
default TargetingContent toTargetingContent(String content) {
21+
if (StringUtils.isNotBlank(content)) {
22+
return JsonMapper.toObject(content, TargetingContent.class);
23+
}
24+
return null;
25+
}
26+
27+
}

src/main/java/com/featureprobe/api/model/ServerSegmentBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public ServerSegmentBuilder builder() {
2222
return this;
2323
}
2424

25-
public ServerSegmentBuilder uniqueId(String projectKey, String segmentKey) {
26-
this.segment.setUniqueId(StringUtils.join(projectKey, '$', segmentKey));
25+
public ServerSegmentBuilder uniqueId(String uniqueId) {
26+
this.segment.setUniqueId(uniqueId);
2727
return this;
2828
}
2929

src/main/java/com/featureprobe/api/model/ServerToggleBuilder.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package com.featureprobe.api.model;
22

33
import com.featureprobe.api.base.exception.ServerToggleBuildException;
4+
import com.featureprobe.api.entity.Segment;
45
import com.featureprobe.api.mapper.JsonMapper;
6+
import com.featureprobe.sdk.server.model.Condition;
57
import com.featureprobe.sdk.server.model.ConditionType;
68
import com.featureprobe.sdk.server.model.Rule;
79
import com.featureprobe.sdk.server.model.Toggle;
810
import com.google.common.collect.Maps;
911
import org.apache.commons.collections4.CollectionUtils;
1012
import org.apache.commons.lang3.BooleanUtils;
11-
import org.apache.commons.lang3.StringUtils;
1213

1314
import java.math.BigDecimal;
1415
import java.util.Collections;
@@ -21,9 +22,11 @@ public class ServerToggleBuilder {
2122
private Toggle toggle;
2223
private Variation.ValueConverter variationValueConverter;
2324
private TargetingContent targetingContent;
25+
private Map<String, Segment> segments;
2426

2527
private static Map<String, Variation.ValueConverter<?>> converters = Maps.newHashMap();
2628

29+
2730
static {
2831
converters.put("string", value -> value);
2932
converters.put("boolean", value -> Boolean.valueOf(value));
@@ -62,6 +65,11 @@ public ServerToggleBuilder rules(String rules) {
6265
return this;
6366
}
6467

68+
public ServerToggleBuilder segments(Map<String, Segment> segments) {
69+
this.segments = segments;
70+
return this;
71+
}
72+
6573
public ServerToggleBuilder returnType(String returnType) {
6674
this.variationValueConverter = getReturnTypeConverter(returnType);
6775
return this;
@@ -74,12 +82,11 @@ private Variation.ValueConverter<?> getReturnTypeConverter(String type) {
7482
throw new ServerToggleBuildException("return type is unknown:" + type);
7583
}
7684

77-
public Toggle build(String projectKey) {
85+
public Toggle build() {
7886
this.setDisabledServe();
7987
this.setDefaultServe();
8088
this.setVariations();
81-
this.setRules(projectKey);
82-
89+
this.setRules();
8390
return toggle;
8491
}
8592

@@ -113,7 +120,7 @@ private void setVariations() {
113120
toggle.setVariations(variations);
114121
}
115122

116-
private void setRules(String projectKey) {
123+
private void setRules() {
117124
if (CollectionUtils.isEmpty(targetingContent.getRules())) {
118125
toggle.setRules(Collections.emptyList());
119126
return;
@@ -122,10 +129,14 @@ private void setRules(String projectKey) {
122129
rule.toRule()).collect(Collectors.toList());
123130
rules.forEach(rule -> rule.getConditions().forEach(condition -> {
124131
if (condition.getType() != ConditionType.SEGMENT) return;
125-
condition.setObjects(condition.getObjects().stream().map(segmentKey ->
126-
StringUtils.join(projectKey, '$', segmentKey)).collect(Collectors.toList()));
132+
replaceSegmentKeyToUniqueKey(condition);
127133
}));
128134
toggle.setRules(rules);
129135
}
130136

137+
private void replaceSegmentKeyToUniqueKey(Condition condition) {
138+
condition.setObjects(condition.getObjects().stream().map(segmentKey ->
139+
segments.get(segmentKey).getUniqueKey()).collect(Collectors.toList()));
140+
}
141+
131142
}

0 commit comments

Comments
 (0)