558cbadc71d1b0a0a3403c1b4eff501bb44e9d8e
[policy/apex-pdp.git] / client / client-editor / src / main / java / org / onap / policy / apex / client / editor / rest / ApexEditorMain.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.client.editor.rest;
23
24 import java.io.PrintStream;
25
26 import org.slf4j.ext.XLogger;
27 import org.slf4j.ext.XLoggerFactory;
28
29 /**
30  * This class is the main class that is used to launch the Apex editor from the command line.
31  *
32  */
33 public class ApexEditorMain {
34     // Logger for this class
35     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorMain.class);
36
37     // Recurring string constants
38     private static final String REST_ENDPOINT_PREFIX = "Apex Editor REST endpoint (";
39
40     /**
41      * The Enum EditorState holds the current state of the editor.
42      */
43     // Editor state
44     public enum EditorState {
45         /** The editor is stopped. */
46         STOPPED,
47         /** The editor is ready to run. */
48         READY,
49         /** The editor is getting ready to run. */
50         INITIALIZING,
51         /** The editor is running. */
52         RUNNING
53     }
54
55     private static final int EDITOR_RNNING_CHECK_TIMEOUT = 1000;
56
57     private EditorState state = EditorState.STOPPED;
58
59     // The Apex editor this class is running
60     private ApexEditor apexEditor = null;
61
62     // The parameters for the editor
63     private ApexEditorParameters parameters = null;
64
65     // Output and error streams for messages
66     private final PrintStream outStream;
67
68     /**
69      * Constructor, kicks off the editor.
70      *
71      * @param args The command line arguments for the editor
72      * @param outStream The stream for output messages
73      */
74     public ApexEditorMain(final String[] args, final PrintStream outStream) {
75         // Save the streams for output and error
76         this.outStream = outStream;
77
78         // Editor parameter parsing
79         final ApexEditorParameterParser parser = new ApexEditorParameterParser();
80
81         try {
82             // Get and check the parameters
83             parameters = parser.parse(args);
84         } catch (final ApexEditorParameterException e) {
85             throw new ApexEditorParameterException(REST_ENDPOINT_PREFIX + this.toString() + ") parameter error, "
86                             + e.getMessage() + '\n' + parser.getHelp(ApexEditorMain.class.getName()), e);
87         }
88
89         if (parameters.isHelpSet()) {
90             throw new ApexEditorParameterException(parser.getHelp(ApexEditorMain.class.getName()));
91         }
92
93         // Validate the parameters
94         final String validationMessage = parameters.validate();
95         if (validationMessage.length() > 0) {
96             throw new ApexEditorParameterException(REST_ENDPOINT_PREFIX + this.toString() + ") parameters invalid, "
97                             + validationMessage + '\n' + parser.getHelp(ApexEditorMain.class.getName()));
98         }
99
100         state = EditorState.READY;
101     }
102
103     /**
104      * Initialize the Apex editor.
105      */
106     public void init() {
107         outStream.println(REST_ENDPOINT_PREFIX + this.toString() + ") starting at " + parameters.getBaseUri().toString()
108                         + " . . .");
109
110         try {
111             state = EditorState.INITIALIZING;
112
113             // Start the editor
114             apexEditor = new ApexEditor(parameters);
115
116             // Add a shutdown hook to shut down the editor when the process is exiting
117             Runtime.getRuntime().addShutdownHook(new Thread(new ApexEditorShutdownHook()));
118
119             state = EditorState.RUNNING;
120
121             if (parameters.getTimeToLive() == ApexEditorParameters.INFINITY_TIME_TO_LIVE) {
122                 outStream.println(REST_ENDPOINT_PREFIX + this.toString() + ") started at "
123                                 + parameters.getBaseUri().toString());
124             } else {
125                 outStream.println(REST_ENDPOINT_PREFIX + this.toString() + ") started");
126             }
127
128             // Find out how long is left to wait
129             long timeRemaining = parameters.getTimeToLive();
130             while (timeRemaining == ApexEditorParameters.INFINITY_TIME_TO_LIVE || timeRemaining > 0) {
131                 // decrement the time to live in the non-infinity case
132                 if (timeRemaining > 0) {
133                     timeRemaining--;
134                 }
135
136                 // Wait for a second
137                 Thread.sleep(EDITOR_RNNING_CHECK_TIMEOUT);
138             }
139         } catch (final Exception e) {
140             String message = REST_ENDPOINT_PREFIX + this.toString() + ") failed at with error: " + e.getMessage();
141             outStream.println(message);
142             LOGGER.warn(message, e);
143         }
144         finally {
145             if (apexEditor != null) {
146                 apexEditor.shutdown();
147                 apexEditor = null;
148             }
149             state = EditorState.STOPPED;
150         }
151     }
152
153     /**
154      * Get the editor state.
155      *
156      * @return the state
157      */
158     public EditorState getState() {
159         return state;
160     }
161
162     /**
163      * {@inheritDoc}.
164      */
165     @Override
166     public String toString() {
167         final StringBuilder ret = new StringBuilder();
168         ret.append(this.getClass().getSimpleName()).append(": Config=[").append(parameters).append("], State=")
169                         .append(this.getState());
170         return ret.toString();
171     }
172
173     /**
174      * Explicitly shut down the editor.
175      */
176     public void shutdown() {
177         if (apexEditor != null) {
178             outStream.println(REST_ENDPOINT_PREFIX + this.toString() + ") shutting down");
179             apexEditor.shutdown();
180         }
181         state = EditorState.STOPPED;
182         outStream.println(REST_ENDPOINT_PREFIX + this.toString() + ") shut down");
183     }
184
185     /**
186      * This class is a shutdown hook for the Apex editor command.
187      */
188     private class ApexEditorShutdownHook implements Runnable {
189         /**
190          * {@inheritDoc}.
191          */
192         @Override
193         public void run() {
194             if (apexEditor != null) {
195                 apexEditor.shutdown();
196             }
197         }
198     }
199
200     /**
201      * Main method, main entry point for command.
202      *
203      * @param args The command line arguments for the editor
204      */
205     public static void main(final String[] args) {
206         try {
207             final ApexEditorMain editorMain = new ApexEditorMain(args, System.out);
208             editorMain.init();
209         } catch (final Exception e) {
210             LOGGER.error("start failed", e);
211         }
212     }
213 }