1111
1212package  org .opensearch .security .tools .democonfig ;
1313
14+ // CS-SUPPRESS-SINGLE: RegexpSingleline Extension is used to refer to file extensions, keeping this rule disable for the whole file 
1415import  java .io .BufferedReader ;
1516import  java .io .File ;
1617import  java .io .FileReader ;
@@ -40,7 +41,6 @@ public class Installer {
4041    private  static  Installer  instance ;
4142
4243    private  static  SecuritySettingsConfigurer  securitySettingsConfigurer ;
43- 
4444    private  static  CertificateGenerator  certificateGenerator ;
4545
4646    boolean  assumeyes  = false ;
@@ -71,19 +71,37 @@ public class Installer {
7171    // To print help information for this script 
7272    private  final  HelpFormatter  formatter  = new  HelpFormatter ();
7373
74+     private  ExitHandler  exitHandler ;
75+ 
7476    /** 
7577     * We do not want this class to be instantiated more than once, 
76-      * as we are following Singleton Factory  pattern 
78+      * as we are following the  Singleton pattern.  
7779     */ 
7880    private  Installer () {
7981        this .OS  = System .getProperty ("os.name" ) + " "  + System .getProperty ("os.version" ) + " "  + System .getProperty ("os.arch" );
8082        FILE_EXTENSION  = OS .toLowerCase ().contains ("win" ) ? ".bat"  : ".sh" ;
8183        options  = new  Options ();
84+         // Use the default exit handler (simply calls System.exit) 
85+         this .exitHandler  = new  DefaultExitHandler ();
86+     }
87+ 
88+     /** 
89+      * Allows dependency injection of an ExitHandler. 
90+      */ 
91+     public  void  setExitHandler (ExitHandler  exitHandler ) {
92+         this .exitHandler  = exitHandler ;
8293    }
8394
8495    /** 
85-      * Returns a singleton instance of this class 
86-      * @return an existing instance OR a new instance if there was no existing instance 
96+      * Returns current exit handler 
97+      */ 
98+     public  ExitHandler  getExitHandler () {
99+         return  this .exitHandler ;
100+     }
101+ 
102+     /** 
103+      * Returns a singleton instance of this class. 
104+      * @return an existing instance OR a new instance if there was no existing instance. 
87105     */ 
88106    public  static  Installer  getInstance () {
89107        if  (instance  == null ) {
@@ -95,8 +113,8 @@ public static Installer getInstance() {
95113    }
96114
97115    /** 
98-      * Installs the demo security configuration 
99-      * @param options the options passed to the script 
116+      * Installs the demo security configuration.  
117+      * @param options the options passed to the script.  
100118     */ 
101119    public  void  installDemoConfiguration (String [] options ) throws  IOException  {
102120        readOptions (options );
@@ -116,7 +134,7 @@ public static void main(String[] options) throws IOException {
116134    }
117135
118136    /** 
119-      * Builds options supported by this tool 
137+      * Builds options supported by this tool.  
120138     */ 
121139    void  buildOptions () {
122140        options .addOption ("h" , "show-help" , false , "Shows help for this tool." );
@@ -148,16 +166,16 @@ void buildOptions() {
148166    }
149167
150168    /** 
151-      * Prints headers that indicate the start of script execution 
169+      * Prints headers that indicate the start of script execution.  
152170     */ 
153171    static  void  printScriptHeaders () {
154172        System .out .println ("### OpenSearch Security Demo Installer" );
155173        System .out .println ("### ** Warning: Do not use on production or public reachable systems **" );
156174    }
157175
158176    /** 
159-      * Reads the options passed to the script 
160-      * @param args an array of strings containing options passed to the script 
177+      * Reads the options passed to the script.  
178+      * @param args an array of strings containing options passed to the script.  
161179     */ 
162180    void  readOptions (String [] args ) {
163181        // set script execution dir 
@@ -179,28 +197,28 @@ void readOptions(String[] args) {
179197
180198        } catch  (ParseException  exp ) {
181199            System .out .println ("ERR: Parsing failed.  Reason: "  + exp .getMessage ());
182-             System .exit (-1 );
200+             exitHandler .exit (-1 );
183201        }
184202    }
185203
186204    /** 
187-      * Prints the help menu when -h option is passed 
205+      * Prints the help menu when -h option is passed.  
188206     */ 
189207    void  showHelp () {
190208        formatter .printHelp ("install_demo_configuration"  + FILE_EXTENSION , options , true );
191-         System .exit (0 );
209+         exitHandler .exit (0 );
192210    }
193211
194212    /** 
195-      * Prompt the user and collect user inputs 
196-      * Input collection will be skipped if -y option was passed 
213+      * Prompt the user and collect user inputs.  
214+      * Input collection will be skipped if -y option was passed.  
197215     */ 
198216    void  gatherUserInputs () {
199217        if  (!assumeyes ) {
200218            try  (Scanner  scanner  = new  Scanner (System .in , StandardCharsets .UTF_8 )) {
201219
202220                if  (!confirmAction (scanner , "Install demo certificates?" )) {
203-                     System .exit (0 );
221+                     exitHandler .exit (0 );
204222                }
205223
206224                if  (!initsecurity ) {
@@ -218,9 +236,9 @@ void gatherUserInputs() {
218236
219237    /** 
220238     * Helper method to scan user inputs. 
221-      * @param scanner object to be used for scanning user input 
222-      * @param message prompt question 
223-      * @return true or false based on user input 
239+      * @param scanner object to be used for scanning user input.  
240+      * @param message prompt question.  
241+      * @return true or false based on user input.  
224242     */ 
225243    boolean  confirmAction (Scanner  scanner , String  message ) {
226244        System .out .print (message  + " [y/N] " );
@@ -229,7 +247,7 @@ boolean confirmAction(Scanner scanner, String message) {
229247    }
230248
231249    /** 
232-      * Initialize all class level variables required 
250+      * Initialize all class level variables required.  
233251     */ 
234252    void  initializeVariables () {
235253        setBaseDir ();
@@ -238,22 +256,22 @@ void initializeVariables() {
238256    }
239257
240258    /** 
241-      * Sets the base directory to be used by the script 
259+      * Sets the base directory to be used by the script.  
242260     */ 
243261    void  setBaseDir () {
244262        File  baseDirFile  = new  File (SCRIPT_DIR ).getParentFile ().getParentFile ().getParentFile ();
245263        BASE_DIR  = baseDirFile  != null  ? baseDirFile .getAbsolutePath () : null ;
246264
247265        if  (BASE_DIR  == null  || !new  File (BASE_DIR ).isDirectory ()) {
248266            System .out .println ("DEBUG: basedir does not exist" );
249-             System .exit (-1 );
267+             exitHandler .exit (-1 );
250268        }
251269
252270        BASE_DIR  += File .separator ;
253271    }
254272
255273    /** 
256-      * Sets the variables for items at OpenSearch level 
274+      * Sets the variables for items at OpenSearch level.  
257275     */ 
258276    void  setOpenSearchVariables () {
259277        OPENSEARCH_CONF_FILE  = BASE_DIR  + "config"  + File .separator  + "opensearch.yml" ;
@@ -266,17 +284,17 @@ void setOpenSearchVariables() {
266284
267285        if  (!errorMessages .isEmpty ()) {
268286            errorMessages .forEach (System .out ::println );
269-             System .exit (-1 );
287+             exitHandler .exit (-1 );
270288        }
271289
272290        OPENSEARCH_CONF_DIR  = new  File (OPENSEARCH_CONF_FILE ).getParent ();
273291        OPENSEARCH_CONF_DIR  = new  File (OPENSEARCH_CONF_DIR ).getAbsolutePath () + File .separator ;
274292    }
275293
276294    /** 
277-      * Helper method 
278-      * Returns a set of error messages for the paths that didn't contain files/directories 
279-      * @return a set containing error messages if any, empty otherwise 
295+      * Helper method.  
296+      * Returns a set of error messages for the paths that didn't contain files/directories.  
297+      * @return a set containing error messages if any, empty otherwise.  
280298     */ 
281299    private  Set <String > validatePaths () {
282300        Set <String > errorMessages  = new  HashSet <>();
@@ -299,8 +317,8 @@ private Set<String> validatePaths() {
299317    }
300318
301319    /** 
302-      * Returns the installation type based on the underlying operating system 
303-      * @return will be one of `.zip`, `.tar.gz` or `rpm/deb` 
320+      * Returns the installation type based on the underlying operating system.  
321+      * @return will be one of `.zip`, `.tar.gz` or `rpm/deb`.  
304322     */ 
305323    String  determineInstallType () {
306324        // windows (.bat execution) 
@@ -320,12 +338,12 @@ String determineInstallType() {
320338    }
321339
322340    /** 
323-      * Sets the path variables for items at OpenSearch security plugin level 
341+      * Sets the path variables for items at OpenSearch security plugin level.  
324342     */ 
325343    void  setSecurityVariables () {
326344        if  (!(new  File (OPENSEARCH_PLUGINS_DIR  + "opensearch-security" ).exists ())) {
327345            System .out .println ("OpenSearch Security plugin not installed. Quit." );
328-             System .exit (-1 );
346+             exitHandler .exit (-1 );
329347        }
330348
331349        // Extract OpenSearch version and Security version 
@@ -349,7 +367,7 @@ void setSecurityVariables() {
349367    }
350368
351369    /** 
352-      * Prints the initialized variables 
370+      * Prints the initialized variables.  
353371     */ 
354372    void  printVariables () {
355373        System .out .println ("OpenSearch install type: "  + OPENSEARCH_INSTALL_TYPE  + " on "  + OS );
@@ -439,9 +457,11 @@ void finishScriptExecution() {
439457
440458    /** 
441459     * FOR TESTS ONLY 
442-      * resets  the installer state to allow testing with fresh instance for the next test. 
460+      * Resets  the installer state to allow testing with a  fresh instance for the next test. 
443461     */ 
444462    static  void  resetInstance () {
445463        instance  = null ;
446464    }
465+ 
447466}
467+ // CS-ENFORCE-SINGLE 
0 commit comments