CVC: Add support for execution, schema, product
[cli.git] / grpc / grpc-server / src / main / java / org / open / infc / grpc / server / OpenInterfaceGrpcServer.java
1 /*
2  * Copyright 2018 Huawei Technologies Co., Ltd.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.open.infc.grpc.server;
18
19 import java.io.IOException;
20 import java.net.InetAddress;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
26
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.output.OnapCommandResultType;
33 import org.onap.cli.fw.registrar.OnapCommandRegistrar;
34 import org.onap.cli.fw.store.OnapCommandExecutionStore;
35 import org.onap.cli.fw.store.OnapCommandExecutionStore.ExecutionStoreContext;
36 import org.onap.cli.main.OnapCli;
37 import org.open.infc.grpc.Args;
38 import org.open.infc.grpc.Input;
39 import org.open.infc.grpc.OpenInterfaceGrpc;
40 import org.open.infc.grpc.Output;
41 import org.open.infc.grpc.Output.Builder;
42 import org.open.infc.grpc.Result;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 import com.fasterxml.jackson.databind.ObjectMapper;
47
48 import io.grpc.Server;
49 import io.grpc.ServerBuilder;
50 import io.grpc.stub.StreamObserver;
51
52 public class OpenInterfaceGrpcServer {
53
54       private static final Logger logger = LoggerFactory.getLogger(OpenInterfaceGrpcServer.class.getName());
55
56       private static final String CONF_FILE = "oclip-grpc-server.properties";
57       private static final String CONF_SERVER_PORT = "oclip.grpc_server_port";
58
59       static {
60           OnapCommandConfig.addProperties(CONF_FILE);
61       }
62       private Server server;
63
64       private void start(String portArg) throws IOException {
65         /* The port on which the server should run */
66         int port = Integer.parseInt(portArg == null ? OnapCommandConfig.getPropertyValue(CONF_SERVER_PORT) : portArg);
67         server = ServerBuilder.forPort(port)
68             .addService(new OpenInterfaceGrpcImpl())
69             .build()
70             .start();
71         logger.info("Server started, listening on " + port);
72
73         try {
74             OnapCommandRegistrar.getRegistrar().setHost(InetAddress.getLocalHost().getHostAddress().trim());
75             OnapCommandRegistrar.getRegistrar().setPort(port);
76         } catch (OnapCommandException e) {
77             //Never Occurs
78         }
79
80         Runtime.getRuntime().addShutdownHook(new Thread() {
81           @Override
82           public void run() {
83             // Use stderr here since the logger may have been reset by its JVM shutdown hook.
84             System.err.println("*** shutting down gRPC server since JVM is shutting down");
85             OpenInterfaceGrpcServer.this.stop();
86             System.err.println("*** server shut down");
87           }
88         });
89       }
90
91       private void stop() {
92         if (server != null) {
93           server.shutdown();
94         }
95       }
96
97       /**
98        * Await termination on the main thread since the grpc library uses daemon threads.
99        */
100       private void blockUntilShutdown() throws InterruptedException {
101         if (server != null) {
102           server.awaitTermination();
103         }
104       }
105
106       /**
107        * Main launches the server from the command line.
108        */
109       public static void main(String[] args) throws IOException, InterruptedException {
110         final OpenInterfaceGrpcServer server = new OpenInterfaceGrpcServer();
111         server.start(args.length ==1 ? args[0] : null);
112         server.blockUntilShutdown();
113       }
114
115       static class OpenRemoteCli extends OnapCli {
116           public OpenRemoteCli(String[] args) {
117             super(args);
118         }
119
120         private String outputs = "";
121
122           public void print(String msg) {
123               outputs += msg + "\n";
124           }
125
126           public String getResult() {
127               return outputs;
128           }
129       }
130
131       static class OpenInterfaceGrpcImpl extends OpenInterfaceGrpc.OpenInterfaceImplBase {
132
133         @Override
134         public void invoke(Input req, StreamObserver<Output> responseObserver) {
135             Output output = null;
136             logger.info(req.toString());
137
138             String product = req.getOptionsMap().get(OnapCommandConstants.RPC_PRODUCT);
139             String format =  req.getOptionsMap().getOrDefault(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT, OnapCommandResultType.JSON.name().toLowerCase());
140             String commandName = req.getAction();
141             String profile = req.getOptionsMap().get(OnapCommandConstants.RPC_PROFILE);
142             OnapCommand cmd = null;
143
144             ExecutionStoreContext executionStoreContext = null;
145             try {
146                 cmd = OnapCommandRegistrar.getRegistrar().get(commandName, product);
147                 cmd.getParametersMap().get(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT).setValue(format);
148
149                 if (!cmd.isRpc()) {
150                     if (profile != null) {
151                         //Set the profile to current one
152                         OnapCommandRegistrar.getRegistrar().setProfile(
153                                 profile,
154                                 new ArrayList<String>(),
155                                 new ArrayList<String>());
156
157                         //fill from profile
158                         for (OnapCommandParameter param: cmd.getParameters()) {
159                             Map<String, String> cache= OnapCommandRegistrar.getRegistrar().getParamCache(product);
160                             if (cache.containsKey(
161                                     cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption())) {
162                                 param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
163                                         cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption()));
164                             } else if (cache.containsKey(
165                                     cmd.getInfo().getService() + ":" + param.getLongOption())) {
166                                 param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
167                                         cmd.getInfo().getService() + ":" + param.getLongOption()));
168                             } else if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(param.getLongOption())) {
169                                 param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(param.getLongOption()));
170                             }
171                         }
172                     }
173
174                     Set <String> params = cmd.getParametersMap().keySet();
175                     for (Entry<String, String> arg: req.getParamsMap().entrySet()) {
176                         if (params.contains(arg.getKey()))
177                             cmd.getParametersMap().get(arg.getKey()).setValue(arg.getValue());
178                     }
179                 } else {
180                     cmd.getParametersMap().get(OnapCommandConstants.INFO_PRODUCT).setValue(product);
181
182                     if (profile != null)
183                         cmd.getParametersMap().get(OnapCommandConstants.RPC_PROFILE).setValue(profile);
184
185                     cmd.getParametersMap().get(OnapCommandConstants.RPC_CMD).setValue(commandName);
186                     cmd.getParametersMap().get(OnapCommandConstants.RPC_ARGS).setValue(req.getParamsMap());
187                     cmd.getParametersMap().get(OnapCommandConstants.RPC_MODE).setValue(OnapCommandConstants.RPC_MODE_RUN_RPC);
188                 }
189
190                 if (!cmd.isRpc()) {
191                     //Start the execution
192                     if (req.getRequestId() != null) {
193                         String input = cmd.getArgsJson(true);
194                         executionStoreContext = OnapCommandExecutionStore.getStore().storeExectutionStart(
195                                 req.getRequestId(),
196                                 cmd.getInfo().getProduct(),
197                                 cmd.getInfo().getService(),
198                                 cmd.getName(),
199                                 profile,
200                                 input);
201                     }
202                 }
203
204                 cmd.execute();
205
206                 if (!cmd.isRpc()) {
207                     String printOut = cmd.getResult().print();
208                     Builder reply = Output.newBuilder();
209                     reply.setSuccess(true);
210                     reply.putAttrs(OnapCommandConstants.ERROR, "{}");
211                     reply.putAddons("execution-id", executionStoreContext.getExecutionId());
212                     try {
213                         reply.putAttrs(OnapCommandConstants.RESULTS, new ObjectMapper().readTree(printOut).toString());
214                     } catch (IOException e) {
215                         reply.putAttrs(OnapCommandConstants.RESULTS, printOut);
216                     }
217
218                     output = reply.build();
219
220                     if (req.getRequestId() != null) {
221                         //complete the execution recording
222                          OnapCommandExecutionStore.getStore().storeExectutionEnd(
223                                  executionStoreContext,
224                                  printOut,
225                                  null,
226                                  cmd.getResult().isPassed());
227                     }
228                     logger.info(output.toString());
229                 } else {
230                     //Rpc command will set the output.
231                     output = (Output) cmd.getResult().getOutput();
232                 }
233
234             } catch (OnapCommandException e) {
235                 logger.info(e.getMessage());
236
237
238                 Builder reply = Output.newBuilder();
239                 reply.putAttrs(OnapCommandConstants.RESULTS, "{}");
240                 reply.setSuccess(false);
241                 reply.putAttrs(OnapCommandConstants.ERROR, e.toJsonString());
242                 if (executionStoreContext != null) {
243                        OnapCommandExecutionStore.getStore().storeExectutionEnd(
244                                 executionStoreContext,
245                                 null,
246                                 e.getMessage(),
247                                 false);
248                       reply.putAddons("execution-id", executionStoreContext.getExecutionId());
249                 }
250
251                 output = reply.build();
252             }
253
254             responseObserver.onNext(output);
255             responseObserver.onCompleted();
256         }
257
258         @Override
259         public void remoteCli(Args req, StreamObserver<Result> responseObserver) {
260             logger.info(req.toString());
261
262             List<String> args = new ArrayList<>();
263             if (req.getRequestId() != null) {
264                 args.add(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_REQID));
265                 args.add(req.getRequestId());
266             }
267
268             args.addAll(req.getArgsList());
269             OpenRemoteCli cli = new OpenRemoteCli(args.toArray(new String [] {}));
270             cli.handle();
271             logger.info(cli.getResult());
272             Result reply = Result.newBuilder().setExitCode(cli.getExitCode()).setOutput(cli.getResult()).build();
273             responseObserver.onNext(reply);
274             responseObserver.onCompleted();
275         }
276       }
277 }