fa25b6ddb8337c999d5d773f1a4b5490dbfd6087
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.runtime.main.startstop;
22
23 import java.io.File;
24 import java.io.PrintWriter;
25 import java.io.StringWriter;
26 import java.net.URL;
27 import java.util.Arrays;
28 import javax.ws.rs.core.Response;
29 import org.apache.commons.cli.CommandLine;
30 import org.apache.commons.cli.DefaultParser;
31 import org.apache.commons.cli.HelpFormatter;
32 import org.apache.commons.cli.Option;
33 import org.apache.commons.cli.Options;
34 import org.apache.commons.cli.ParseException;
35 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
36 import org.onap.policy.common.utils.resources.ResourceUtils;
37
38
39 /**
40  * This class reads and handles command line parameters for the control loop runtime service.
41  *
42  */
43 public class ClRuntimeCommandLineArguments {
44     private static final String FILE_MESSAGE_PREAMBLE = " file \"";
45     private static final int HELP_LINE_LENGTH = 120;
46
47     private final Options options;
48     private String configurationFilePath = null;
49
50     /**
51      * Construct the options for the control loop runtime component.
52      */
53     public ClRuntimeCommandLineArguments() {
54         //@formatter:off
55         options = new Options();
56         options.addOption(Option.builder("h")
57                 .longOpt("help")
58                 .desc("outputs the usage of this command")
59                 .required(false)
60                 .type(Boolean.class)
61                 .build());
62         options.addOption(Option.builder("v")
63                 .longOpt("version")
64                 .desc("outputs the version of control loop runtime")
65                 .required(false)
66                 .type(Boolean.class)
67                 .build());
68         options.addOption(Option.builder("c")
69                 .longOpt("config-file")
70                 .desc("the full path to the configuration file to use, "
71                         + "the configuration file must be a Json file containing the control loop runtime parameters")
72                 .hasArg()
73                 .argName("CONFIG_FILE")
74                 .required(false)
75                 .type(String.class)
76                 .build());
77         //@formatter:on
78     }
79
80     /**
81      * Parse the command line options.
82      *
83      * @param args The command line arguments
84      * @return a string with a message for help and version, or null if there is no message
85      * @throws ControlLoopException on command argument errors
86      */
87     public String parse(final String[] args) throws ControlLoopException {
88         // Clear all our arguments
89         setConfigurationFilePath(null);
90
91         CommandLine commandLine = null;
92         try {
93             commandLine = new DefaultParser().parse(options, args);
94         } catch (final ParseException e) {
95             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
96                     "invalid command line arguments specified", e);
97         }
98
99         // Arguments left over after Commons CLI does its stuff
100         final String[] remainingArgs = commandLine.getArgs();
101
102         if (remainingArgs.length > 0) {
103             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
104                     "too many command line arguments specified : " + Arrays.toString(args));
105         }
106
107         if (remainingArgs.length == 1) {
108             configurationFilePath = remainingArgs[0];
109         }
110
111         if (commandLine.hasOption('h')) {
112             return help(Main.class.getName());
113         }
114
115         if (commandLine.hasOption('v')) {
116             return version();
117         }
118
119         if (commandLine.hasOption('c')) {
120             setConfigurationFilePath(commandLine.getOptionValue('c'));
121         }
122
123         return null;
124     }
125
126     /**
127      * Validate the command line options.
128      *
129      * @throws ControlLoopException on command argument validation errors
130      */
131     public void validate() throws ControlLoopException {
132         validateReadableFile("control loop runtime configuration", configurationFilePath);
133     }
134
135     /**
136      * Print version information for control loop runtime.
137      *
138      * @return the version string
139      */
140     public String version() {
141         return ResourceUtils.getResourceAsString("version.txt");
142     }
143
144     /**
145      * Print help information for control loop runtime.
146      *
147      * @param mainClassName the main class name
148      * @return the help string
149      */
150     public String help(final String mainClassName) {
151         final HelpFormatter helpFormatter = new HelpFormatter();
152         final StringWriter stringWriter = new StringWriter();
153         final PrintWriter printWriter = new PrintWriter(stringWriter);
154
155         helpFormatter.printHelp(printWriter, HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, 0,
156                 0, "");
157
158         return stringWriter.toString();
159     }
160
161     /**
162      * Gets the configuration file path.
163      *
164      * @return the configuration file path
165      */
166     public String getConfigurationFilePath() {
167         return configurationFilePath;
168     }
169
170     /**
171      * Gets the full expanded configuration file path.
172      *
173      * @return the configuration file path
174      */
175     public String getFullConfigurationFilePath() {
176         return ResourceUtils.getFilePath4Resource(getConfigurationFilePath());
177     }
178
179     /**
180      * Sets the configuration file path.
181      *
182      * @param configurationFilePath the configuration file path
183      */
184     public void setConfigurationFilePath(final String configurationFilePath) {
185         this.configurationFilePath = configurationFilePath;
186
187     }
188
189     /**
190      * Validate readable file.
191      *
192      * @param fileTag the file tag
193      * @param fileName the file name
194      * @throws ControlLoopException on the file name passed as a parameter
195      */
196     private void validateReadableFile(final String fileTag, final String fileName) throws ControlLoopException {
197         if (fileName == null || fileName.length() == 0) {
198             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
199                     fileTag + " file was not specified as an argument");
200         }
201
202         // The file name refers to a resource on the local file system
203         final URL fileUrl = ResourceUtils.getUrl4Resource(fileName);
204         if (fileUrl == null) {
205             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
206                     fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist");
207         }
208
209         final File theFile = new File(fileUrl.getPath());
210         if (!theFile.exists()) {
211             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
212                     fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist");
213         }
214         if (!theFile.isFile()) {
215             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
216                     fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file");
217         }
218         if (!theFile.canRead()) {
219             throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE,
220                     fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is ureadable");
221         }
222     }
223 }