-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClientLocalService.java
More file actions
160 lines (127 loc) · 5.32 KB
/
ClientLocalService.java
File metadata and controls
160 lines (127 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package com.switcherapi.client.service.local;
import com.switcherapi.client.exception.SwitcherException;
import com.switcherapi.client.exception.SwitcherKeyNotFoundException;
import com.switcherapi.client.model.Entry;
import com.switcherapi.client.model.SwitcherRequest;
import com.switcherapi.client.model.SwitcherResult;
import com.switcherapi.client.model.criteria.Config;
import com.switcherapi.client.model.criteria.Domain;
import com.switcherapi.client.model.criteria.Group;
import com.switcherapi.client.model.criteria.StrategyConfig;
import com.switcherapi.client.service.SwitcherFactory;
import com.switcherapi.client.service.SwitcherValidator;
import com.switcherapi.client.utils.SwitcherUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Local Switcher Service retain the same main functionalities as the Remote,
* but instead, runs Switcher criteria evaluation against the snapshot files.
*
* @author Roger Floriano (petruki)
* @since 2019-12-24
*/
public class ClientLocalService implements ClientLocal {
private static final Logger logger = LoggerFactory.getLogger(ClientLocalService.class);
public static final String DISABLED_DOMAIN = "Domain disabled";
public static final String DISABLED_GROUP = "Group disabled";
public static final String DISABLED_CONFIG = "Config disabled";
public static final String HAS_RELAY = "Config has Relay enabled";
private static final String STRATEGY_FAIL_PATTERN = "Strategy %s does not agree";
private static final String STRATEGY_FAIL_NO_INPUT_PATTERN = "Strategy %s did not receive any input";
private static final String LOG_PROCESS_OP_TEMPLATE = "processOperation: configStrategies: {}";
private final SwitcherValidator validatorService;
public ClientLocalService(SwitcherValidator validatorService) {
this.validatorService = validatorService;
}
@Override
public List<String> checkSwitchers(final Set<String> switchers, final Domain domain) {
List<String> notFound = new ArrayList<>();
for (final String switcher : switchers) {
if (Arrays.stream(domain.getGroup()).noneMatch(group ->
Arrays.stream(group.getConfig()).anyMatch(config -> config.getKey().equals(switcher)))) {
notFound.add(switcher);
}
}
return notFound;
}
@Override
public SwitcherResult executeCriteria(final SwitcherRequest switcher, final Domain domain) {
if (!domain.isActivated()) {
return SwitcherFactory.buildResultDisabled(DISABLED_DOMAIN, switcher);
}
Config config;
for (final Group group : domain.getGroup()) {
config = findConfigInGroup(group, switcher.getSwitcherKey());
if (Objects.nonNull(config)) {
return getSwitcherResult(switcher, group, config);
}
}
throw new SwitcherKeyNotFoundException(switcher.getSwitcherKey());
}
private SwitcherResult getSwitcherResult(SwitcherRequest switcher, Group group, Config config) {
if (!group.isActivated()) {
return SwitcherFactory.buildResultDisabled(DISABLED_GROUP, switcher);
}
if (!config.isActivated()) {
return SwitcherFactory.buildResultDisabled(DISABLED_CONFIG, switcher);
}
if (config.hasRelayEnabled() && switcher.isRelayRestricted()) {
return SwitcherFactory.buildResultDisabled(HAS_RELAY, switcher);
}
if (ArrayUtils.isNotEmpty(config.getStrategies())) {
return this.processOperation(config.getStrategies(), switcher.getEntry(), switcher);
}
return SwitcherFactory.buildResultEnabled(switcher);
}
private Config findConfigInGroup(final Group group, final String switcherKey) {
for (Config config : group.getConfig()) {
if (config.getKey().equals(switcherKey)) {
return config;
}
}
return null;
}
/**
* Process Strategy operations based on the strategy settings
*
* @param configStrategies to be processed
* @param input sent by the client
* @return SwitcherResult containing the result of the execution
* @throws SwitcherException If encountered either invalid input or misconfiguration
*/
private SwitcherResult processOperation(final StrategyConfig[] configStrategies, final List<Entry> input,
final SwitcherRequest switcher) {
SwitcherUtils.debug(logger, LOG_PROCESS_OP_TEMPLATE, Arrays.toString(configStrategies));
for (final StrategyConfig strategyConfig : configStrategies) {
if (!strategyConfig.isActivated()) {
continue;
}
final Entry switcherInput = tryGetSwitcherInput(input, strategyConfig);
if (Objects.isNull(switcherInput)) {
return strategyFailed(switcher, strategyConfig, STRATEGY_FAIL_NO_INPUT_PATTERN);
}
if (!validatorService.execute(strategyConfig, switcherInput)) {
return strategyFailed(switcher, strategyConfig, STRATEGY_FAIL_PATTERN);
}
}
return SwitcherFactory.buildResultEnabled(switcher);
}
private SwitcherResult strategyFailed(SwitcherRequest switcher, StrategyConfig strategyConfig, String pattern) {
return SwitcherFactory.buildResultDisabled(String.format(pattern, strategyConfig.getStrategy()), switcher);
}
private Entry tryGetSwitcherInput(final List<Entry> input, StrategyConfig strategyConfig) {
if (Objects.isNull(input)) {
return null;
}
return input.stream()
.filter(i -> i.getStrategy().equals(strategyConfig.getStrategy()))
.findFirst()
.orElse(null);
}
}