package org.yamcs.web;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.YConfiguration;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.cors.CorsConfig;
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
/**
* Data holder for webConfig section of yamcs.yamnl
*/
public class WebConfig {
private static final Logger log = LoggerFactory.getLogger(WebConfig.class);
private static WebConfig INSTANCE;
private int port;
private List<String> webRoots = new ArrayList<>(2);
private boolean zeroCopyEnabled = true;
// Refer to W3C spec for understanding these properties
// Cross-origin Resource Sharing (CORS) enables ajaxified use of the REST api by
// remote web applications.
private CorsConfig corsConfig;
private WebConfig() {
YConfiguration yconf = YConfiguration.getConfiguration("yamcs");
if (yconf.containsKey("webPort")) {
log.warn("Property 'webPort' in yamcs.yaml is deprecated. Instead nest new property 'port' under 'webConfig'.");
port = yconf.getInt("webPort");
}
if (yconf.containsKey("webRoot")) {
log.warn("Property 'webRoot' in yamcs.yaml is deprecated. Instead nest 'webRoot' under 'webConfig'.");
if (yconf.isList("webRoot")) {
@SuppressWarnings({ "unchecked", "rawtypes" })
List<String> rootConf = (List) yconf.getList("webRoot");
for (String root : rootConf) {
webRoots.add(root);
}
} else {
webRoots.add(yconf.getString("webRoot"));
}
}
if (yconf.containsKey("zeroCopyEnabled")) {
log.warn("Property 'zeroCopyEnabled' in yamcs.yaml is deprecated. Instead nest 'zeroCopyEnabled' under 'webConfig'.");
zeroCopyEnabled = yconf.getBoolean("zeroCopyEnabled");
}
CorsConfigBuilder corsb = null;
if (yconf.containsKey("webConfig")) {
Map<String, Object> webConfig = yconf.getMap("webConfig");
port = YConfiguration.getInt(webConfig, "port", 8090);
zeroCopyEnabled = YConfiguration.getBoolean(webConfig, "zeroCopyEnabled", zeroCopyEnabled);
if (webConfig.containsKey("webRoot")) {
if (YConfiguration.isList(webConfig, "webRoot")) {
List<String> rootConf = YConfiguration.getList(webConfig, "webRoot");
webRoots.addAll(rootConf);
} else {
webRoots.add(YConfiguration.getString(webConfig, "webRoot"));
}
}
if(webConfig.containsKey("cors")) {
Map<String, Object> ycors = YConfiguration.getMap(webConfig, "cors");
if (YConfiguration.getBoolean(ycors, "enabled")) {
if (YConfiguration.isList(ycors, "allowOrigin")) {
List<String> originConf = YConfiguration.getList(ycors, "allowOrigin");
corsb = CorsConfigBuilder.forOrigins(originConf.toArray(new String[originConf.size()]));
} else {
corsb = CorsConfigBuilder.forOrigin(YConfiguration.getString(ycors, "allowOrigin"));
}
if (YConfiguration.getBoolean(ycors, "allowCredentials")) {
corsb.allowCredentials();
}
}
}
} else {
// Allow CORS requests for unprotected Yamcs instances
// (Browsers would anyway strip Authorization header)
corsb = CorsConfigBuilder.forAnyOrigin();
}
if (corsb != null) {
corsb.allowedRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.PATCH, HttpMethod.PUT, HttpMethod.DELETE);
corsb.allowedRequestHeaders(HttpHeaderNames.CONTENT_TYPE, HttpHeaderNames.ACCEPT, HttpHeaderNames.AUTHORIZATION, HttpHeaderNames.ORIGIN);
corsConfig = corsb.build();
}
}
public static synchronized WebConfig getInstance() {
if (INSTANCE != null) return INSTANCE;
INSTANCE = new WebConfig();
return INSTANCE;
}
public int getPort() {
return port;
}
public boolean isZeroCopyEnabled() {
return zeroCopyEnabled;
}
public List<String> getWebRoots() {
return webRoots;
}
public CorsConfig getCorsConfig() {
return corsConfig;
}
}