import static java.util.Objects.requireNonNull;
import java.util.Map;
+import org.opendaylight.restconf.api.query.PrettyPrintParam;
import org.opendaylight.restconf.nb.rfc8040.streams.DefaultPingExecutor;
import org.opendaylight.restconf.nb.rfc8040.streams.DefaultRestconfStreamServletFactory;
import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
-import org.opendaylight.restconf.server.mdsal.MdsalRestconfStreamRegistry;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.component.ComponentFactory;
import org.osgi.service.component.ComponentInstance;
public @interface Configuration {
@AttributeDefinition(min = "0", max = "" + StreamsConfiguration.MAXIMUM_FRAGMENT_LENGTH_LIMIT)
int maximum$_$fragment$_$length() default 0;
+
@AttributeDefinition(min = "0")
int heartbeat$_$interval() default 10000;
+
@AttributeDefinition(min = "1")
int idle$_$timeout() default 30000;
+
@AttributeDefinition(min = "1")
String ping$_$executor$_$name$_$prefix() default DefaultPingExecutor.DEFAULT_NAME_PREFIX;
+
// FIXME: this is a misnomer: it specifies the core pool size, i.e. minimum thread count, the maximum is set to
// Integer.MAX_VALUE, which is not what we want
@AttributeDefinition(min = "0")
int max$_$thread$_$count() default DefaultPingExecutor.DEFAULT_CORE_POOL_SIZE;
- @Deprecated(since = "7.0.0", forRemoval = true)
- @AttributeDefinition
- boolean use$_$sse() default true;
+
@AttributeDefinition(name = "{+restconf}", description = """
- The value of RFC8040 {+restconf} URI template, poiting to the root resource. Must not end with '/'.""")
+ The value of RFC8040 {+restconf} URI template, pointing to the root resource. Must not end with '/'.""")
String restconf() default "rests";
+
+ @AttributeDefinition(
+ name = "default pretty-print",
+ description = "Control the default value of the '" + PrettyPrintParam.uriName + "' query parameter.")
+ boolean pretty$_$print() default false;
+
+ @AttributeDefinition(
+ name = "Report 404 on data-missing",
+ description = """
+ Control the HTTP status code reporting of conditions corresponding to "data-missing". When this is set
+ to true, the server will violate RFC8040 and report "404" instead of "409".
+
+ For details and reasoning see https://www.rfc-editor.org/errata/eid5565 and
+ https://mailarchive.ietf.org/arch/browse/netconf/?gbt=1&index=XcF9r3ek3LvZ4DjF-7_B8kxuiwA""")
+ boolean data$_$missing$_$is$_$404() default false;
}
private static final Logger LOG = LoggerFactory.getLogger(OSGiNorthbound.class);
- private final ComponentFactory<MdsalRestconfStreamRegistry> registryFactory;
private final ComponentFactory<DefaultRestconfStreamServletFactory> servletFactoryFactory;
- private ComponentInstance<MdsalRestconfStreamRegistry> registry;
- @Deprecated(since = "7.0.0", forRemoval = true)
- private boolean useSSE;
-
private ComponentInstance<DefaultRestconfStreamServletFactory> servletFactory;
private Map<String, ?> servletProps;
public OSGiNorthbound(
@Reference(target = "(component.factory=" + DefaultRestconfStreamServletFactory.FACTORY_NAME + ")")
final ComponentFactory<DefaultRestconfStreamServletFactory> servletFactoryFactory,
- @Reference(target = "(component.factory=" + MdsalRestconfStreamRegistry.FACTORY_NAME + ")")
- final ComponentFactory<MdsalRestconfStreamRegistry> registryFactory, final Configuration configuration) {
- this.registryFactory = requireNonNull(registryFactory);
+ final Configuration configuration) {
this.servletFactoryFactory = requireNonNull(servletFactoryFactory);
- useSSE = configuration.use$_$sse();
- registry = registryFactory.newInstance(FrameworkUtil.asDictionary(MdsalRestconfStreamRegistry.props(useSSE)));
-
- servletProps = DefaultRestconfStreamServletFactory.props(configuration.restconf(), registry.getInstance(),
- useSSE,
+ servletProps = DefaultRestconfStreamServletFactory.props(configuration.restconf(),
+ configuration.data$_$missing$_$is$_$404() ? ErrorTagMapping.ERRATA_5565 : ErrorTagMapping.RFC8040,
+ PrettyPrintParam.of(configuration.pretty$_$print()),
new StreamsConfiguration(configuration.maximum$_$fragment$_$length(),
configuration.idle$_$timeout(), configuration.heartbeat$_$interval()),
configuration.ping$_$executor$_$name$_$prefix(), configuration.max$_$thread$_$count());
@Modified
void modified(final Configuration configuration) {
- final var newUseSSE = configuration.use$_$sse();
- if (newUseSSE != useSSE) {
- useSSE = newUseSSE;
- registry.dispose();
- registry = registryFactory.newInstance(FrameworkUtil.asDictionary(
- MdsalRestconfStreamRegistry.props(useSSE)));
- LOG.debug("ListenersBroker restarted with {}", newUseSSE ? "SSE" : "Websockets");
- }
-
final var newServletProps = DefaultRestconfStreamServletFactory.props(configuration.restconf(),
- registry.getInstance(), useSSE,
+ configuration.data$_$missing$_$is$_$404() ? ErrorTagMapping.ERRATA_5565 : ErrorTagMapping.RFC8040,
+ PrettyPrintParam.of(configuration.pretty$_$print()),
new StreamsConfiguration(configuration.maximum$_$fragment$_$length(),
configuration.idle$_$timeout(), configuration.heartbeat$_$interval()),
configuration.ping$_$executor$_$name$_$prefix(), configuration.max$_$thread$_$count());
void deactivate() {
servletFactory.dispose();
servletFactory = null;
- registry.dispose();
- registry = null;
LOG.info("Global RESTCONF northbound pools stopped");
}
}