1
1
package io .visual_regression_tracker .sdk_java ;
2
2
3
- import lombok .AllArgsConstructor ;
4
- import lombok .Builder ;
5
- import lombok .Data ;
6
- import lombok .NonNull ;
7
- import lombok .RequiredArgsConstructor ;
8
-
9
- @ Data
10
- @ Builder
3
+ import com .google .gson .Gson ;
4
+ import com .google .gson .reflect .TypeToken ;
5
+ import lombok .*;
6
+ import lombok .experimental .Accessors ;
7
+ import lombok .extern .slf4j .Slf4j ;
8
+
9
+ import java .io .File ;
10
+ import java .io .IOException ;
11
+ import java .lang .reflect .Field ;
12
+ import java .lang .reflect .Type ;
13
+ import java .nio .charset .StandardCharsets ;
14
+ import java .nio .file .Files ;
15
+ import java .util .Collections ;
16
+ import java .util .Map ;
17
+ import java .util .function .Function ;
18
+
19
+ @ Data ()
11
20
@ RequiredArgsConstructor
12
21
@ AllArgsConstructor
22
+ @ Accessors (chain = true )
23
+ @ Slf4j
13
24
public class VisualRegressionTrackerConfig {
14
25
15
26
@ NonNull
@@ -18,12 +29,145 @@ public class VisualRegressionTrackerConfig {
18
29
private final String apiKey ;
19
30
@ NonNull
20
31
private final String project ;
21
- @ Builder .Default
22
- private String branchName = null ;
23
- @ Builder .Default
24
- private String ciBuildId = null ;
25
- @ Builder .Default
26
- private Boolean enableSoftAssert = false ;
27
- @ Builder .Default
28
- private int httpTimeoutInSeconds = 10 ;
32
+
33
+ private String branchName ;
34
+ private String ciBuildId ;
35
+ private Boolean enableSoftAssert ;
36
+ private int httpTimeoutInSeconds ;
37
+
38
+ public static VisualRegressionTrackerConfigBuilder builder () {
39
+ return new VisualRegressionTrackerConfigBuilder ();
40
+ }
41
+
42
+ public static class VisualRegressionTrackerConfigBuilder {
43
+ private String apiUrl ;
44
+ private String apiKey ;
45
+ private String project ;
46
+
47
+ private String branchName ;
48
+ private String ciBuildId ;
49
+ private Boolean enableSoftAssert ;
50
+ private Integer httpTimeoutInSeconds ;
51
+
52
+ private File configFile ;
53
+
54
+ private static final String VRT_ENV_VARIABLE_PREFIX = "VRT_" ;
55
+ private static final boolean DEFAULT_SOFT_ASSERTION_STATE = false ;
56
+ private static final int DEFAULT_HTTP_TIMEOUT_SECONDS = 10 ;
57
+
58
+ public VisualRegressionTrackerConfigBuilder apiUrl (String apiUrl ) {
59
+ this .apiUrl = apiUrl ;
60
+ return this ;
61
+ }
62
+
63
+ public VisualRegressionTrackerConfigBuilder apiKey (String apiKey ) {
64
+ this .apiKey = apiKey ;
65
+ return this ;
66
+ }
67
+
68
+ public VisualRegressionTrackerConfigBuilder project (String project ) {
69
+ this .project = project ;
70
+ return this ;
71
+ }
72
+
73
+ public VisualRegressionTrackerConfigBuilder branchName (String branchName ) {
74
+ this .branchName = branchName ;
75
+ return this ;
76
+ }
77
+
78
+ public VisualRegressionTrackerConfigBuilder ciBuildId (String ciBuildId ) {
79
+ this .ciBuildId = ciBuildId ;
80
+ return this ;
81
+ }
82
+
83
+ public VisualRegressionTrackerConfigBuilder enableSoftAssert (Boolean enableSoftAssert ) {
84
+ this .enableSoftAssert = enableSoftAssert ;
85
+ return this ;
86
+ }
87
+
88
+ public VisualRegressionTrackerConfigBuilder httpTimeoutInSeconds (int httpTimeoutInSeconds ) {
89
+ this .httpTimeoutInSeconds = httpTimeoutInSeconds ;
90
+ return this ;
91
+ }
92
+
93
+ public VisualRegressionTrackerConfigBuilder configFile (File configFile ) {
94
+ this .configFile = configFile ;
95
+ return this ;
96
+ }
97
+
98
+ public VisualRegressionTrackerConfig build () {
99
+ Map <String , Object > configFromFile = Collections .emptyMap ();
100
+ if (configFile != null ) {
101
+ configFromFile = readConfigFromFile (configFile );
102
+ }
103
+
104
+ String actualApiUrl = resolve ("apiUrl" , configFromFile );
105
+ String actualApiKey = resolve ("apiKey" , configFromFile );
106
+ String actualProject = resolve ("project" , configFromFile );
107
+
108
+ VisualRegressionTrackerConfig config = new VisualRegressionTrackerConfig (actualApiUrl , actualApiKey , actualProject );
109
+ config .setCiBuildId (resolve ("ciBuildId" , configFromFile ));
110
+ config .setBranchName (resolve ("branchName" , configFromFile ));
111
+
112
+ Boolean actualEnableSoftAssert = resolve ("enableSoftAssert" , configFromFile );
113
+ config .setEnableSoftAssert (actualEnableSoftAssert == null ? DEFAULT_SOFT_ASSERTION_STATE : actualEnableSoftAssert );
114
+
115
+ Integer actualHttpTimeoutInSeconds = resolve ("httpTimeoutInSeconds" , configFromFile );
116
+ config .setHttpTimeoutInSeconds (actualHttpTimeoutInSeconds == null ? DEFAULT_HTTP_TIMEOUT_SECONDS : actualHttpTimeoutInSeconds );
117
+
118
+ return config ;
119
+ }
120
+
121
+ private Map <String , Object > readConfigFromFile (File configFile ) {
122
+ if (!configFile .exists ()) {
123
+ throw new IllegalArgumentException ("File " + configFile + " doesn't exist" );
124
+ }
125
+
126
+ String fileContent ;
127
+ try {
128
+ fileContent = Files .readString (configFile .toPath (), StandardCharsets .UTF_8 );
129
+ } catch (IOException e ) {
130
+ throw new IllegalArgumentException ("Can't read content of provided config file" , e );
131
+ }
132
+ Type mapType = new TypeToken <Map <String , Object >>() {}.getType ();
133
+ return new Gson ().fromJson (fileContent , mapType );
134
+ }
135
+
136
+ @ SneakyThrows
137
+ private <T > T resolve (String propertyName , Map <String , Object > configurationFromFile ) {
138
+ // 1. check if it was initialized explicitly in builder
139
+ // 2. check if env variable exists
140
+ // 3. try to read from file as last resort
141
+ Field field = this .getClass ().getDeclaredField (propertyName );
142
+ Object propertyValue = field .get (this );
143
+ if (propertyValue != null ) {
144
+ return (T ) propertyValue ;
145
+ }
146
+
147
+ String environmentVariableName = VRT_ENV_VARIABLE_PREFIX + propertyName .toUpperCase ();
148
+ propertyValue = System .getenv (environmentVariableName );
149
+ if (propertyValue != null ) {
150
+ log .debug ("Value of '{}' resolved from environment variable {}" , propertyName , environmentVariableName );
151
+ Function <String , ?> parser = findParser (field .getType ());
152
+ return (T ) parser .apply ((String )propertyValue );
153
+ }
154
+
155
+ propertyValue = configurationFromFile .get (propertyName );
156
+ if (propertyValue != null ) {
157
+ log .debug ("Value of '{}' resolved from config file" , propertyName );
158
+ }
159
+ return propertyValue == null ? null : (T ) propertyValue ;
160
+ }
161
+
162
+ private Function <String , ?> findParser (Class <?> cls ) {
163
+ if (cls .equals (Boolean .class )) {
164
+ return Boolean ::parseBoolean ;
165
+ }
166
+ if (cls .equals (Integer .class )) {
167
+ return Integer ::parseInt ;
168
+ }
169
+ return String ::valueOf ;
170
+ }
171
+ }
172
+
29
173
}
0 commit comments