2 * Copyright 2018 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.open.infc.grpc.server;
19 import java.io.IOException;
20 import java.net.InetAddress;
21 import java.util.ArrayList;
22 import java.util.List;
24 import java.util.Map.Entry;
27 import org.onap.cli.fw.cmd.OnapCommand;
28 import org.onap.cli.fw.conf.OnapCommandConfig;
29 import org.onap.cli.fw.conf.OnapCommandConstants;
30 import org.onap.cli.fw.error.OnapCommandException;
31 import org.onap.cli.fw.input.OnapCommandParameter;
32 import org.onap.cli.fw.input.OnapCommandParameterType;
33 import org.onap.cli.fw.output.OnapCommandResultType;
34 import org.onap.cli.fw.registrar.OnapCommandRegistrar;
35 import org.onap.cli.fw.store.OnapCommandExecutionStore;
36 import org.onap.cli.fw.store.OnapCommandExecutionStore.ExecutionStoreContext;
37 import org.onap.cli.main.OnapCli;
38 import org.onap.cli.main.utils.OnapCliArgsParser;
39 import org.open.infc.grpc.Args;
40 import org.open.infc.grpc.Input;
41 import org.open.infc.grpc.OpenInterfaceGrpc;
42 import org.open.infc.grpc.Output;
43 import org.open.infc.grpc.Output.Builder;
44 import org.open.infc.grpc.Result;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 import com.google.gson.JsonParser;
50 import io.grpc.Server;
51 import io.grpc.ServerBuilder;
52 import io.grpc.stub.StreamObserver;
54 public class OpenInterfaceGrpcServer {
56 private static final Logger logger = LoggerFactory.getLogger(OpenInterfaceGrpcServer.class.getName());
58 private static final String CONF_FILE = "oclip-grpc-server.properties";
59 private static final String CONF_SERVER_PORT = "oclip.grpc_server_port";
60 private static final String CONF_SERVER_HOST = "oclip.grpc_server_host";
63 OnapCommandConfig.addProperties(CONF_FILE);
65 private Server server;
67 private void start(String portArg) throws IOException {
68 /* The port on which the server should run */
69 int port = Integer.parseInt(portArg == null ? OnapCommandConfig.getPropertyValue(CONF_SERVER_PORT) : portArg);
70 String host = OnapCommandConfig.getPropertyValue(CONF_SERVER_HOST);
72 host = InetAddress.getLocalHost().getHostAddress().trim();
74 server = ServerBuilder.forPort(port)
75 .addService(new OpenInterfaceGrpcImpl())
78 logger.info("Server started, listening on {}", port);
81 OnapCommandRegistrar.getRegistrar().setHost(host);
82 OnapCommandRegistrar.getRegistrar().setPort(port);
83 } catch (OnapCommandException e) {
87 Runtime.getRuntime().addShutdownHook(new Thread() {
90 // Use stderr here since the logger may have been reset by its JVM shutdown hook.
91 System.err.println("*** shutting down gRPC server since JVM is shutting down"); //NOSONAR
92 OpenInterfaceGrpcServer.this.stop();
93 System.err.println("*** server shut down"); //NOSONAR
105 * Await termination on the main thread since the grpc library uses daemon threads.
107 private void blockUntilShutdown() throws InterruptedException {
108 if (server != null) {
109 server.awaitTermination();
114 * Main launches the server from the command line.
116 public static void main(String[] args) throws IOException, InterruptedException {
117 final OpenInterfaceGrpcServer server = new OpenInterfaceGrpcServer();
118 server.start(args.length ==1 ? args[0] : null); //NOSONAR
119 server.blockUntilShutdown();
122 static class OpenRemoteCli extends OnapCli {
123 public OpenRemoteCli(String[] args) {
127 private String outputs = "";
130 public void print(String msg) {
131 outputs += msg + "\n";
134 public String getResult() {
139 static class OpenInterfaceGrpcImpl extends OpenInterfaceGrpc.OpenInterfaceImplBase {
142 public void invoke(Input req, StreamObserver<Output> responseObserver) {
143 Output output = null;
144 logger.info("{}", req);
146 String product = req.getOptionsMap().get(OnapCommandConstants.RPC_PRODUCT);
147 String format = req.getOptionsMap().getOrDefault(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT, OnapCommandResultType.JSON.name().toLowerCase());
148 String commandName = req.getAction();
149 String profile = req.getOptionsMap().get(OnapCommandConstants.RPC_PROFILE);
150 OnapCommand cmd = null;
152 ExecutionStoreContext executionStoreContext = null;
154 cmd = OnapCommandRegistrar.getRegistrar().get(commandName, product);
155 cmd.getParametersMap().get(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT).setValue(format);
158 if (profile != null) {
159 //Set the profile to current one
160 OnapCommandRegistrar.getRegistrar().setProfile(
166 Map<String, String> cache= OnapCommandRegistrar.getRegistrar().getParamCache(product);
167 for (OnapCommandParameter param: cmd.getParameters()) {
168 if (cache.containsKey(
169 cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption())) {
170 param.setValue(cache.get(
171 cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption()));
172 } else if (cache.containsKey(
173 cmd.getInfo().getService() + ":" + param.getLongOption())) {
174 param.setValue(cache.get(
175 cmd.getInfo().getService() + ":" + param.getLongOption()));
176 } else if (cache.containsKey(param.getLongOption())) {
177 param.setValue(cache.get(param.getLongOption()));
182 Set <String> params = cmd.getParametersMap().keySet();
183 for (Entry<String, String> arg: req.getParamsMap().entrySet()) {
184 if (params.contains(arg.getKey()))
185 cmd.getParametersMap().get(arg.getKey()).setValue(arg.getValue());
188 //fill values from the file, if needed
189 for (OnapCommandParameter param: cmd.getParameters()) {
190 if (param.getParameterType().equals(OnapCommandParameterType.JSON)) {
191 param.setValue(OnapCliArgsParser.readJsonStringFromUrl(param.getValue().toString(), param.getName()));
193 } else if (param.getParameterType().equals(OnapCommandParameterType.TEXT)) {
194 param.setValue(OnapCliArgsParser.readTextStringFromUrl(param.getValue().toString(), param.getName()));
196 } else if (param.getParameterType().equals(OnapCommandParameterType.BYTE)) {
197 param.setValue(OnapCliArgsParser.readBytesFromUrl(param.getValue().toString(), param.getName()));
199 } else if (param.getParameterType().equals(OnapCommandParameterType.YAML)) {
200 param.setValue(OnapCliArgsParser.readYamlStringFromUrl(param.getValue().toString(), param.getName()));
206 cmd.getParametersMap().get(OnapCommandConstants.INFO_PRODUCT).setValue(product);
209 cmd.getParametersMap().get(OnapCommandConstants.RPC_PROFILE).setValue(profile);
211 cmd.getParametersMap().get(OnapCommandConstants.RPC_CMD).setValue(commandName);
212 cmd.getParametersMap().get(OnapCommandConstants.RPC_ARGS).setValue(req.getParamsMap());
213 cmd.getParametersMap().get(OnapCommandConstants.RPC_MODE).setValue(OnapCommandConstants.RPC_MODE_RUN_RPC);
216 //Start the execution
217 if (!cmd.isRpc()&&req.getRequestId() != null && !req.getRequestId().isEmpty() && !(cmd.getInfo().getProduct().equalsIgnoreCase("open-cli") &&
218 cmd.getName().equalsIgnoreCase("execution-list"))) {
219 String input = cmd.getArgsJson(true);
220 executionStoreContext = OnapCommandExecutionStore.getStore().storeExectutionStart(
222 cmd.getInfo().getProduct(),
223 cmd.getInfo().getService(),
228 cmd.setExecutionContext(executionStoreContext);
232 //Track and/or persist the execution context
233 new OnapCli().handleTracking(cmd);
235 String printOut = cmd.getResult().print();
236 Builder reply = Output.newBuilder();
237 reply.putAttrs(OnapCommandConstants.ERROR, "{}");
239 if (executionStoreContext != null)
240 reply.putAddons("execution-id", executionStoreContext.getExecutionId());
242 // use the status from the plugin.
243 reply.setSuccess(cmd.getResult().isPassed());
245 setOutputAttr(reply, printOut);
247 output = reply.build();
248 logger.info("{}", output);
250 //Rpc command will set the output.
251 output = (Output) cmd.getResult().getOutput();
254 } catch (OnapCommandException e) {
255 logger.info(e.getMessage());
257 Builder reply = Output.newBuilder();
258 reply.putAttrs(OnapCommandConstants.RESULTS, "{}");
259 reply.setSuccess(false);
260 reply.putAttrs(OnapCommandConstants.ERROR, e.toJsonString());
261 if (executionStoreContext != null) {
262 OnapCommandExecutionStore.getStore().storeExectutionEnd(
263 executionStoreContext,
266 cmd.getResult().getDebugInfo(),
268 reply.putAddons("execution-id", executionStoreContext.getExecutionId());
271 output = reply.build();
274 responseObserver.onNext(output);
275 responseObserver.onCompleted();
278 public static void setOutputAttr(Builder reply, String printOut){
280 reply.putAttrs(OnapCommandConstants.RESULTS, new JsonParser().parse(printOut).toString());
281 } catch (Exception e) { // NOSONAR
282 reply.putAttrs(OnapCommandConstants.RESULTS, printOut);
287 public void remoteCli(Args req, StreamObserver<Result> responseObserver) {
288 logger.info("{}", req);
290 List<String> args = new ArrayList<>();
291 if (req.getRequestId() != null) {
292 args.add(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_REQID));
293 args.add(req.getRequestId());
296 args.addAll(req.getArgsList());
297 OpenRemoteCli cli = new OpenRemoteCli(args.toArray(new String [] {}));
299 logger.info(cli.getResult());
300 Result reply = Result.newBuilder().setExitCode(cli.getExitCode()).setOutput(cli.getResult()).build();
301 responseObserver.onNext(reply);
302 responseObserver.onCompleted();