/
LeshanBootstrapServerDemo.java
executable file
·237 lines (205 loc) · 10.2 KB
/
LeshanBootstrapServerDemo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*******************************************************************************
* Copyright (c) 2013-2015 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
* Achim Kraus (Bosch Software Innovations GmbH) - add parameter for
* configuration filename
*******************************************************************************/
package org.eclipse.leshan.server.bootstrap.demo;
import java.io.File;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.leshan.core.LwM2m;
import org.eclipse.leshan.core.model.ObjectLoader;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.StaticModel;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.bootstrap.demo.servlet.BootstrapServlet;
import org.eclipse.leshan.server.bootstrap.demo.servlet.ServerServlet;
import org.eclipse.leshan.server.californium.LeshanServerBuilder;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LeshanBootstrapServerDemo {
static {
// Define a default logback.configurationFile
String property = System.getProperty("logback.configurationFile");
if (property == null) {
System.setProperty("logback.configurationFile", "logback-config.xml");
}
}
private static final Logger LOG = LoggerFactory.getLogger(LeshanBootstrapServerDemo.class);
private final static String USAGE = "java -jar leshan-bsserver-demo.jar [OPTION]";
public static void main(String[] args) {
// Define options for command line tools
Options options = new Options();
options.addOption("h", "help", false, "Display help information.");
options.addOption("lh", "coaphost", true, "Set the local CoAP address.\n Default: any local address.");
options.addOption("lp", "coapport", true,
String.format("Set the local CoAP port.\n Default: %d.", LwM2m.DEFAULT_COAP_PORT));
options.addOption("slh", "coapshost", true, "Set the secure local CoAP address.\nDefault: any local address.");
options.addOption("slp", "coapsport", true,
String.format("Set the secure local CoAP port.\nDefault: %d.", LwM2m.DEFAULT_COAP_SECURE_PORT));
options.addOption("wh", "webhost", true, "Set the HTTP address for web server.\nDefault: any local address.");
options.addOption("wp", "webport", true, "Set the HTTP port for web server.\nDefault: 8080.");
options.addOption("m", "modelsfolder", true, "A folder which contains object models in OMA DDF(.xml) format.");
options.addOption("cfg", "configfile", true,
"Set the filename for the configuration.\nDefault: " + JSONFileBootstrapStore.DEFAULT_FILE + ".");
options.addOption("oc", "activate support of old/deprecated cipher suites.");
HelpFormatter formatter = new HelpFormatter();
formatter.setOptionComparator(null);
// Parse arguments
CommandLine cl;
try {
cl = new DefaultParser().parse(options, args);
} catch (ParseException e) {
System.err.println("Parsing failed. Reason: " + e.getMessage());
formatter.printHelp(USAGE, options);
return;
}
// Print help
if (cl.hasOption("help")) {
formatter.printHelp(USAGE, options);
return;
}
// Abort if unexpected options
if (cl.getArgs().length > 0) {
System.err.println("Unexpected option or arguments : " + cl.getArgList());
formatter.printHelp(USAGE, options);
return;
}
// Get local address
String localAddress = cl.getOptionValue("lh");
if (localAddress == null)
localAddress = "0.0.0.0";
String localPortOption = cl.getOptionValue("lp");
int localPort = LwM2m.DEFAULT_COAP_PORT;
if (localPortOption != null) {
localPort = Integer.parseInt(localPortOption);
}
// Get secure local address
String secureLocalAddress = cl.getOptionValue("slh");
if (secureLocalAddress == null)
secureLocalAddress = "0.0.0.0";
String secureLocalPortOption = cl.getOptionValue("slp");
int secureLocalPort = LwM2m.DEFAULT_COAP_SECURE_PORT;
if (secureLocalPortOption != null) {
secureLocalPort = Integer.parseInt(secureLocalPortOption);
}
// get http address
String webAddress = cl.getOptionValue("wh");
String webPortOption = cl.getOptionValue("wp");
int webPort = 8080;
if (webPortOption != null) {
webPort = Integer.parseInt(webPortOption);
}
// Get models folder
String modelsFolderPath = cl.getOptionValue("m");
// Get config file
String configFilename = cl.getOptionValue("cfg");
if (configFilename == null) {
configFilename = JSONFileBootstrapStore.DEFAULT_FILE;
}
try {
createAndStartServer(webAddress, webPort, localAddress, localPort, secureLocalAddress, secureLocalPort,
modelsFolderPath, configFilename, cl.hasOption("oc"));
} catch (BindException e) {
System.err.println(String
.format("Web port %s is already in use, you can change it using the 'webport' option.", webPort));
formatter.printHelp(USAGE, options);
} catch (Exception e) {
LOG.error("Jetty stopped with unexpected error ...", e);
}
}
public static void createAndStartServer(String webAddress, int webPort, String localAddress, int localPort,
String secureLocalAddress, int secureLocalPort, String modelsFolderPath, String configFilename,
boolean supportDeprecatedCiphers) throws Exception {
// Create Models
List<ObjectModel> models = ObjectLoader.loadDefault();
if (modelsFolderPath != null) {
models.addAll(ObjectLoader.loadObjectsFromDir(new File(modelsFolderPath)));
}
// Prepare and start bootstrap server
LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder();
JSONFileBootstrapStore bsStore = new JSONFileBootstrapStore(configFilename);
builder.setConfigStore(bsStore);
builder.setSecurityStore(new BootstrapConfigSecurityStore(bsStore));
builder.setLocalAddress(localAddress, localPort);
builder.setLocalSecureAddress(secureLocalAddress, secureLocalPort);
builder.setModel(new StaticModel(models));
// Create DTLS Config
DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
dtlsConfig.setRecommendedCipherSuitesOnly(!supportDeprecatedCiphers);
// Create X509 credentials;
X509Certificate serverCertificate = null;
try {
PrivateKey privateKey = SecurityUtil.privateKey.readFromResource("credentials/bsserver_privkey.der");
serverCertificate = SecurityUtil.certificate.readFromResource("credentials/bsserver_cert.der");
builder.setPrivateKey(privateKey);
builder.setCertificateChain(new X509Certificate[] { serverCertificate });
// Use a certificate verifier which trust all certificates by default.
builder.setTrustedCertificates(new X509Certificate[0]);
} catch (Exception e) {
LOG.error("Unable to load embedded X.509 certificate.", e);
System.exit(-1);
}
// Set DTLS Config
builder.setDtlsConfig(dtlsConfig);
// Create CoAP Config
NetworkConfig coapConfig;
File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME);
if (configFile.isFile()) {
coapConfig = new NetworkConfig();
coapConfig.load(configFile);
} else {
coapConfig = LeshanServerBuilder.createDefaultNetworkConfig();
coapConfig.store(configFile);
}
builder.setCoapConfig(coapConfig);
LeshanBootstrapServer bsServer = builder.build();
bsServer.start();
// Now prepare and start jetty
InetSocketAddress jettyAddr;
if (webAddress == null) {
jettyAddr = new InetSocketAddress(webPort);
} else {
jettyAddr = new InetSocketAddress(webAddress, webPort);
}
Server server = new Server(jettyAddr);
WebAppContext root = new WebAppContext();
root.setContextPath("/");
root.setResourceBase(LeshanBootstrapServerDemo.class.getClassLoader().getResource("webapp").toExternalForm());
root.setParentLoaderPriority(true);
ServletHolder bsServletHolder = new ServletHolder(new BootstrapServlet(bsStore));
root.addServlet(bsServletHolder, "/api/bootstrap/*");
ServletHolder serverServletHolder = new ServletHolder(new ServerServlet(bsServer, serverCertificate));
root.addServlet(serverServletHolder, "/api/server/*");
server.setHandler(root);
server.start();
LOG.info("Web server started at {}.", server.getURI());
}
}