All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.runtime.rest.RestServerEndpointConfiguration Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.flink.runtime.rest;

import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.RestOptions;
import org.apache.flink.configuration.SecurityOptions;
import org.apache.flink.configuration.WebOptions;
import org.apache.flink.runtime.net.SSLEngineFactory;
import org.apache.flink.runtime.net.SSLUtils;
import org.apache.flink.util.ConfigurationException;
import org.apache.flink.util.Preconditions;

import org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders;

import javax.annotation.Nullable;
import javax.net.ssl.SSLEngine;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;

import static java.util.Objects.requireNonNull;

/**
 * A configuration object for {@link RestServerEndpoint}s.
 */
public final class RestServerEndpointConfiguration {

	private final String restAddress;

	@Nullable
	private final String restBindAddress;

	private final int restBindPort;

	@Nullable
	private final SSLEngineFactory sslEngineFactory;

	private final Path uploadDir;

	private final int maxContentLength;

	private final Map responseHeaders;

	private RestServerEndpointConfiguration(
			final String restAddress,
			@Nullable String restBindAddress,
			int restBindPort,
			@Nullable SSLEngineFactory sslEngineFactory,
			final Path uploadDir,
			final int maxContentLength,
			final Map responseHeaders) {

		Preconditions.checkArgument(0 <= restBindPort && restBindPort < 65536, "The bing rest port " + restBindPort + " is out of range (0, 65536[");
		Preconditions.checkArgument(maxContentLength > 0, "maxContentLength must be positive, was: %d", maxContentLength);

		this.restAddress = requireNonNull(restAddress);
		this.restBindAddress = restBindAddress;
		this.restBindPort = restBindPort;
		this.sslEngineFactory = sslEngineFactory;
		this.uploadDir = requireNonNull(uploadDir);
		this.maxContentLength = maxContentLength;
		this.responseHeaders = Collections.unmodifiableMap(requireNonNull(responseHeaders));
	}

	/**
	 * @see RestOptions#ADDRESS
	 */
	public String getRestAddress() {
		return restAddress;
	}

	/**
	 * Returns the address that the REST server endpoint should bind itself to.
	 *
	 * @return address that the REST server endpoint should bind itself to
	 */
	public String getRestBindAddress() {
		return restBindAddress;
	}

	/**
	 * Returns the port that the REST server endpoint should listen on.
	 *
	 * @return port that the REST server endpoint should listen on
	 */
	public int getRestBindPort() {
		return restBindPort;
	}

	/**
	 * Returns the {@link SSLEngine} that the REST server endpoint should use.
	 *
	 * @return SSLEngine that the REST server endpoint should use, or null if SSL was disabled
	 */
	@Nullable
	public SSLEngineFactory getSslEngineFactory() {
		return sslEngineFactory;
	}

	/**
	 * Returns the directory used to temporarily store multipart/form-data uploads.
	 */
	public Path getUploadDir() {
		return uploadDir;
	}

	/**
	 * Returns the max content length that the REST server endpoint could handle.
	 *
	 * @return max content length that the REST server endpoint could handle
	 */
	public int getMaxContentLength() {
		return maxContentLength;
	}

	/**
	 * Response headers that should be added to every HTTP response.
	 */
	public Map getResponseHeaders() {
		return responseHeaders;
	}

	/**
	 * Creates and returns a new {@link RestServerEndpointConfiguration} from the given {@link Configuration}.
	 *
	 * @param config configuration from which the REST server endpoint configuration should be created from
	 * @return REST server endpoint configuration
	 * @throws ConfigurationException if SSL was configured incorrectly
	 */
	public static RestServerEndpointConfiguration fromConfiguration(Configuration config) throws ConfigurationException {
		Preconditions.checkNotNull(config);

		final String restAddress = Preconditions.checkNotNull(config.getString(RestOptions.ADDRESS),
			"%s must be set",
			RestOptions.ADDRESS.key());

		final String restBindAddress = config.getString(RestOptions.BIND_ADDRESS);
		final int port = config.getInteger(RestOptions.PORT);

		final SSLEngineFactory sslEngineFactory;
		final boolean enableSSL = config.getBoolean(SecurityOptions.SSL_ENABLED) && config.getBoolean(WebOptions.SSL_ENABLED);
		if (enableSSL) {
			try {
				sslEngineFactory = SSLUtils.createServerSSLEngineFactory(config);
			} catch (Exception e) {
				throw new ConfigurationException("Failed to initialize SSLEngineFactory for REST server endpoint.", e);
			}
		} else {
			sslEngineFactory = null;
		}

		final Path uploadDir = Paths.get(
			config.getString(WebOptions.UPLOAD_DIR,	config.getString(WebOptions.TMP_DIR)),
			"flink-web-upload");

		final int maxContentLength = config.getInteger(RestOptions.SERVER_MAX_CONTENT_LENGTH);

		final Map responseHeaders = Collections.singletonMap(
			HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN,
			config.getString(WebOptions.ACCESS_CONTROL_ALLOW_ORIGIN));

		return new RestServerEndpointConfiguration(
			restAddress,
			restBindAddress,
			port,
			sslEngineFactory,
			uploadDir,
			maxContentLength,
			responseHeaders);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy