Improve lighty format message
[transportpce.git] / lighty / src / main / java / io / lighty / controllers / tpce / Main.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies s.r.o. All Rights Reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at https://www.eclipse.org/legal/epl-v10.html
7  */
8 package io.lighty.controllers.tpce;
9
10 import io.lighty.controllers.tpce.exception.TechnicalException;
11 import io.lighty.controllers.tpce.module.TransportPCE;
12 import io.lighty.controllers.tpce.module.TransportPCEImpl;
13 import io.lighty.controllers.tpce.utils.TPCEUtils;
14 import io.lighty.controllers.tpce.utils.TpceBanner;
15 import io.lighty.core.controller.api.LightyController;
16 import io.lighty.core.controller.api.LightyModule;
17 import io.lighty.core.controller.impl.LightyControllerBuilder;
18 import io.lighty.core.controller.impl.config.ConfigurationException;
19 import io.lighty.core.controller.impl.config.ControllerConfiguration;
20 import io.lighty.core.controller.impl.util.ControllerConfigUtils;
21 import io.lighty.modules.northbound.restconf.community.impl.CommunityRestConf;
22 import io.lighty.modules.northbound.restconf.community.impl.CommunityRestConfBuilder;
23 import io.lighty.modules.northbound.restconf.community.impl.config.JsonRestConfServiceType;
24 import io.lighty.modules.northbound.restconf.community.impl.config.RestConfConfiguration;
25 import io.lighty.modules.northbound.restconf.community.impl.util.RestConfConfigUtils;
26 import io.lighty.modules.southbound.netconf.impl.NetconfSBPlugin;
27 import io.lighty.modules.southbound.netconf.impl.NetconfTopologyPluginBuilder;
28 import io.lighty.modules.southbound.netconf.impl.config.NetconfConfiguration;
29 import io.lighty.modules.southbound.netconf.impl.util.NetconfConfigUtils;
30 import io.lighty.server.LightyServerBuilder;
31 import java.io.IOException;
32 import java.net.InetSocketAddress;
33 import java.nio.file.Files;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.util.concurrent.ExecutionException;
37
38 import org.apache.commons.cli.CommandLine;
39 import org.apache.commons.cli.DefaultParser;
40 import org.apache.commons.cli.HelpFormatter;
41 import org.apache.commons.cli.Option;
42 import org.apache.commons.cli.Options;
43 import org.apache.commons.cli.ParseException;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class Main {
48
49     private static final String RESTCONF_OPTION_NAME = "restconf";
50
51     private static final String NBINOTIFICATION_OPTION_NAME = "nbinotification";
52
53     private static final Logger LOG = LoggerFactory.getLogger(Main.class);
54
55     private ShutdownHook shutdownHook;
56
57     public void start() {
58         start(null, false, false);
59     }
60
61     @SuppressWarnings("checkstyle:Illegalcatch")
62     public void start(String restConfConfigurationFile, boolean activateNbiNotification, boolean registerShutdownHook) {
63         long startTime = System.nanoTime();
64         TpceBanner.print();
65         RestConfConfiguration restConfConfig = null;
66         try {
67             // 1. get controller configuration
68             ControllerConfiguration singleNodeConfiguration = ControllerConfigUtils
69                     .getDefaultSingleNodeConfiguration(TPCEUtils.getYangModels());
70             // 2. get RESTCONF NBP configuration
71             if (restConfConfigurationFile != null) {
72                 Path configPath = Paths.get(restConfConfigurationFile);
73                 LOG.info("Using restconf configuration from file {} ...", configPath);
74                 restConfConfig = RestConfConfigUtils.getRestConfConfiguration(Files.newInputStream(configPath));
75
76             } else {
77                 LOG.info("Using default restconf configuration with http port 8181 ...");
78
79                 restConfConfig = RestConfConfigUtils.getDefaultRestConfConfiguration();
80                 restConfConfig.setHttpPort(8181);
81
82             }
83             restConfConfig.setJsonRestconfServiceType(JsonRestConfServiceType.DRAFT_02);
84             // 3. NETCONF SBP configuration
85             NetconfConfiguration netconfSBPConfig = NetconfConfigUtils.createDefaultNetconfConfiguration();
86             startLighty(singleNodeConfiguration, restConfConfig, netconfSBPConfig, registerShutdownHook, activateNbiNotification);
87             float duration = (System.nanoTime() - startTime) / 1_000_000f;
88             LOG.info("lighty.io and RESTCONF-NETCONF started in {}ms", duration);
89         } catch (ConfigurationException | ExecutionException | IOException e) {
90             LOG.error("An error occured while starting application: ", e);
91             throw new TechnicalException("An error occured while starting application", e);
92         } catch (InterruptedException e) {
93             LOG.error("Application start interrupted : ", e);
94             Thread.currentThread().interrupt();
95             throw new TechnicalException("Application start interrupted", e);
96           //CHECKSTYLE:OFF
97         } catch (Exception e) {
98           //CHECKSTYLE:ON
99             LOG.error("Application start unmanaged exception : ", e);
100             throw new TechnicalException("Application start unmanaged exception", e);
101
102         }
103     }
104
105     /**
106      * Build options for command line arguments
107      * @return
108      */
109     private static Options buildOptions() {
110         Option restconfFileOption = Option.builder(RESTCONF_OPTION_NAME)
111                 .desc("Restconf configuration file")
112                 .argName(RESTCONF_OPTION_NAME)
113                 .hasArg(true)
114                 .required(false)
115                 .build();
116         Option useNbiNotificationsOption = Option.builder(NBINOTIFICATION_OPTION_NAME)
117                 .desc("Activate NBI notifications feature")
118                 .argName(NBINOTIFICATION_OPTION_NAME)
119                 .hasArg(false)
120                 .required(false)
121                 .build();
122         Options options = new Options();
123         options.addOption(restconfFileOption);
124         options.addOption(useNbiNotificationsOption);
125         return options;
126     }
127
128     private void startLighty(ControllerConfiguration controllerConfiguration,
129             RestConfConfiguration restConfConfiguration, NetconfConfiguration netconfSBPConfiguration,
130             boolean registerShutdownHook, boolean activateNbiNotification)
131                     throws ConfigurationException, ExecutionException, InterruptedException {
132
133         // 1. initialize and start Lighty controller (MD-SAL, Controller, YangTools,
134         // Akka)
135         LightyControllerBuilder lightyControllerBuilder = new LightyControllerBuilder();
136         LightyController lightyController = lightyControllerBuilder.from(controllerConfiguration).build();
137         lightyController.start().get();
138
139         // 2. start RestConf server
140         LightyServerBuilder jettyServerBuilder = new LightyServerBuilder(
141                 new InetSocketAddress(restConfConfiguration.getInetAddress(), restConfConfiguration.getHttpPort()));
142         CommunityRestConfBuilder communityRestConfBuilder = CommunityRestConfBuilder.from(
143                 RestConfConfigUtils.getRestConfConfiguration(restConfConfiguration, lightyController.getServices()));
144         CommunityRestConf communityRestConf = communityRestConfBuilder.withLightyServer(jettyServerBuilder).build();
145         communityRestConf.start().get();
146         communityRestConf.startServer();
147
148         // 3. start NetConf SBP
149         NetconfSBPlugin netconfSouthboundPlugin;
150         netconfSBPConfiguration = NetconfConfigUtils.injectServicesToTopologyConfig(netconfSBPConfiguration,
151                 lightyController.getServices());
152         NetconfTopologyPluginBuilder netconfSBPBuilder = new NetconfTopologyPluginBuilder(
153                 lightyController.getServices(), netconfSBPConfiguration);
154         netconfSouthboundPlugin = netconfSBPBuilder.from(netconfSBPConfiguration, lightyController.getServices())
155                 .build();
156         netconfSouthboundPlugin.start().get();
157
158         // 4. start TransportPCE beans
159         TransportPCE transportPCE = new TransportPCEImpl(lightyController.getServices(), activateNbiNotification);
160         transportPCE.start().get();
161
162         // 5. Register shutdown hook for graceful shutdown.
163         shutdownHook = new ShutdownHook(lightyController, communityRestConf, netconfSouthboundPlugin, transportPCE);
164         if (registerShutdownHook) {
165             Runtime.getRuntime().addShutdownHook(shutdownHook);
166         }
167     }
168
169     public void shutdown() {
170         shutdownHook.run();
171     }
172
173     public static void main(String[] args) {
174         Options options = buildOptions();
175         try {
176             CommandLine commandLine = new DefaultParser().parse(options, args);
177             String restConfConfigurationFile = commandLine.getOptionValue(RESTCONF_OPTION_NAME, null);
178             boolean useNbiNotifications = commandLine.hasOption(NBINOTIFICATION_OPTION_NAME);
179             Main app = new Main();
180             app.start(restConfConfigurationFile, useNbiNotifications, true);
181         } catch (ParseException e) {
182             HelpFormatter formatter = new HelpFormatter();
183             formatter.printHelp(
184                     "java -ms<size> -mx<size> -XX:MaxMetaspaceSize=<size> -jar tpce.jar "
185                     + "[-restconf <restconfConfigurationFile>] [-nbinotification]"
186                     +" e.g. java -ms128m -mx512m -XX:MaxMetaspaceSize=128m -jar tpce.jar"
187                     + "-restconf ../src/test/resources/config.json -nbinotification",
188                     options);
189             System.exit(1);
190         }
191     }
192
193     private static class ShutdownHook extends Thread {
194
195         private static final Logger LOG = LoggerFactory.getLogger(ShutdownHook.class);
196         private final LightyController lightyController;
197         private final CommunityRestConf communityRestConf;
198         private final LightyModule netconfSouthboundPlugin;
199         private final TransportPCE transportPCE;
200
201         ShutdownHook(LightyController lightyController, CommunityRestConf communityRestConf,
202                 LightyModule netconfSouthboundPlugin, TransportPCE transportPCE) {
203             this.lightyController = lightyController;
204             this.communityRestConf = communityRestConf;
205             this.netconfSouthboundPlugin = netconfSouthboundPlugin;
206             this.transportPCE = transportPCE;
207         }
208
209         @Override
210         @SuppressWarnings({"checkstyle:Illegalcatch", "checkstyle:VariableDeclarationUsageDistance"})
211         public void run() {
212             LOG.info("lighty.io and RESTCONF-NETCONF shutting down ...");
213             long startTime = System.nanoTime();
214             try {
215                 transportPCE.shutdown().get();
216             } catch (Exception e) {
217                 LOG.error("Exception while shutting down TransportPCE: ", e);
218             }
219             try {
220                 communityRestConf.shutdown().get();
221             } catch (Exception e) {
222                 LOG.error("Exception while shutting down RESTCONF: ", e);
223             }
224             try {
225                 netconfSouthboundPlugin.shutdown().get();
226             } catch (Exception e) {
227                 LOG.error("Exception while shutting down NETCONF: ", e);
228             }
229             try {
230                 lightyController.shutdown().get();
231             } catch (Exception e) {
232                 LOG.error("Exception while shutting down lighty.io controller:", e);
233             }
234             float duration = (System.nanoTime() - startTime) / 1_000_000f;
235             LOG.info("lighty.io and RESTCONF-NETCONF stopped in {}ms", duration);
236         }
237
238     }
239
240 }