11package io .visual_regression_tracker .sdk_java ;
22
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 ()
1120@ RequiredArgsConstructor
1221@ AllArgsConstructor
22+ @ Accessors (chain = true )
23+ @ Slf4j
1324public class VisualRegressionTrackerConfig {
1425
1526 @ NonNull
@@ -18,12 +29,145 @@ public class VisualRegressionTrackerConfig {
1829 private final String apiKey ;
1930 @ NonNull
2031 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+
29173}
0 commit comments