import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfDataStreamServiceImpl;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.restconf.nb.rfc8040.streams.WebSocketInitializer;
import org.opendaylight.yangtools.concepts.Registration;
final DatabindProvider databindProvider,
final String pingNamePrefix, final int pingMaxThreadCount, final int maximumFragmentLength,
final int heartbeatInterval, final int idleTimeout, final boolean useSSE) throws ServletException {
- final var configuration = new Configuration(maximumFragmentLength, idleTimeout, heartbeatInterval, useSSE);
+ final var streamsConfiguration = new StreamsConfiguration(maximumFragmentLength, idleTimeout, heartbeatInterval,
+ useSSE);
final var scheduledThreadPool = new ScheduledThreadPoolWrapper(pingMaxThreadCount,
new NamingThreadPoolFactory(pingNamePrefix));
.addUrlPattern("/*")
.servlet(servletSupport.createHttpServletBuilder(
new RestconfApplication(databindProvider, mountPointService, dataBroker, rpcService, actionService,
- notificationService,schemaService, configuration)).build())
+ notificationService,schemaService, streamsConfiguration)).build())
.asyncSupported(true)
.build())
.addServlet(ServletDetails.builder()
.addUrlPattern("/" + NOTIF + "/*")
.servlet(servletSupport.createHttpServletBuilder(
new DataStreamApplication(databindProvider, mountPointService,
- new RestconfDataStreamServiceImpl(scheduledThreadPool, configuration))).build())
+ new RestconfDataStreamServiceImpl(scheduledThreadPool, streamsConfiguration))).build())
.name("notificationServlet")
.asyncSupported(true)
.build())
.addServlet(ServletDetails.builder()
.addUrlPattern("/" + DATA_SUBSCRIPTION + "/*")
.addUrlPattern("/" + NOTIFICATION_STREAM + "/*")
- .servlet(new WebSocketInitializer(scheduledThreadPool, configuration))
+ .servlet(new WebSocketInitializer(scheduledThreadPool, streamsConfiguration))
.build())
// Allows user to add javax.servlet.Filter(s) in front of REST services
import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfOperationsServiceImpl;
import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfSchemaServiceImpl;
import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfStreamsSubscriptionServiceImpl;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
@Singleton
public class RestconfApplication extends AbstractRestconfApplication {
final RestconfStreamsSubscriptionService streamSubscription, final DOMDataBroker dataBroker,
final DOMRpcService rpcService, final DOMActionService actionService,
final DOMNotificationService notificationService, final DOMSchemaService domSchemaService,
- final Configuration configuration) {
+ final StreamsConfiguration configuration) {
super(databindProvider, mountPointService, List.of(
streamSubscription,
new RestconfDataServiceImpl(databindProvider, dataBroker, mountPointService, streamSubscription,
public RestconfApplication(final DatabindProvider databindProvider, final DOMMountPointService mountPointService,
final DOMDataBroker dataBroker, final DOMRpcService rpcService, final DOMActionService actionService,
final DOMNotificationService notificationService, final DOMSchemaService domSchemaService,
- final Configuration configuration) {
+ final StreamsConfiguration configuration) {
this(databindProvider, mountPointService,
new RestconfStreamsSubscriptionServiceImpl(dataBroker, notificationService, databindProvider,
configuration),
import org.opendaylight.restconf.nb.rfc8040.rests.utils.PostDataTransactionUtil;
import org.opendaylight.restconf.nb.rfc8040.rests.utils.PutDataTransactionUtil;
import org.opendaylight.restconf.nb.rfc8040.rests.utils.ReadDataTransactionUtil;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.restconf.nb.rfc8040.utils.mapping.RestconfMappingNodeUtil;
import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
public RestconfDataServiceImpl(final DatabindProvider databindProvider,
final DOMDataBroker dataBroker, final DOMMountPointService mountPointService,
final RestconfStreamsSubscriptionService delegRestconfSubscrService,
- final DOMActionService actionService, final Configuration configuration) {
+ final DOMActionService actionService, final StreamsConfiguration configuration) {
this.databindProvider = requireNonNull(databindProvider);
this.dataBroker = requireNonNull(dataBroker);
restconfStrategy = new MdsalRestconfStrategy(dataBroker);
this.mountPointService = requireNonNull(mountPointService);
this.delegRestconfSubscrService = requireNonNull(delegRestconfSubscrService);
this.actionService = requireNonNull(actionService);
- streamUtils = configuration.isUseSSE() ? SubscribeToStreamUtil.serverSentEvents()
+ streamUtils = configuration.useSSE() ? SubscribeToStreamUtil.serverSentEvents()
: SubscribeToStreamUtil.webSockets();
}
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfDataStreamService;
import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
import org.opendaylight.restconf.nb.rfc8040.streams.SSESessionHandler;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.BaseListenerInterface;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker;
import org.opendaylight.yangtools.yang.common.ErrorTag;
@Inject
public RestconfDataStreamServiceImpl(final ScheduledThreadPool scheduledThreadPool,
- final Configuration configuration) {
+ final StreamsConfiguration configuration) {
executorService = scheduledThreadPool.getExecutor();
- heartbeatInterval = configuration.getHeartbeatInterval();
- maximumFragmentLength = configuration.getMaximumFragmentLength();
+ heartbeatInterval = configuration.heartbeatInterval();
+ maximumFragmentLength = configuration.maximumFragmentLength();
}
@Override
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfInvokeOperationsService;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.device.notification.rev221106.SubscribeDeviceNotificationInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateDataChangeEventSubscriptionInput;
import org.opendaylight.yangtools.yang.common.ErrorTag;
private final SubscribeToStreamUtil streamUtils;
public RestconfInvokeOperationsServiceImpl(final DOMRpcService rpcService,
- final DOMMountPointService mountPointService, final Configuration configuration) {
+ final DOMMountPointService mountPointService, final StreamsConfiguration configuration) {
this.rpcService = requireNonNull(rpcService);
this.mountPointService = requireNonNull(mountPointService);
- streamUtils = configuration.isUseSSE() ? SubscribeToStreamUtil.serverSentEvents()
+ streamUtils = configuration.useSSE() ? SubscribeToStreamUtil.serverSentEvents()
: SubscribeToStreamUtil.webSockets();
}
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
* @param dataBroker {@link DOMDataBroker}
* @param notificationService {@link DOMNotificationService}
* @param databindProvider a {@link DatabindProvider}
- * @param configuration configuration for RESTCONF {@link Configuration}}
+ * @param configuration configuration for RESTCONF {@link StreamsConfiguration}}
*/
public RestconfStreamsSubscriptionServiceImpl(final DOMDataBroker dataBroker,
final DOMNotificationService notificationService, final DatabindProvider databindProvider,
- final Configuration configuration) {
+ final StreamsConfiguration configuration) {
handlersHolder = new HandlersHolder(dataBroker, notificationService, databindProvider);
- streamUtils = configuration.isUseSSE() ? SubscribeToStreamUtil.serverSentEvents()
+ streamUtils = configuration.useSSE() ? SubscribeToStreamUtil.serverSentEvents()
: SubscribeToStreamUtil.webSockets();
}
+++ /dev/null
-/*
- * Copyright © 2019 FRINX s.r.o. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.restconf.nb.rfc8040.streams;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Restconf configuration holder and verifier.
- */
-public class Configuration {
-
- private static final int MAX_FRAGMENT_LENGTH = 65535;
-
- private final int maximumFragmentLength;
- private final int idleTimeout;
- private final int heartbeatInterval;
- private final boolean useSSE;
-
- /**
- * Creation of the restconf configuration holder with verification of input parameters.
- *
- * @param maximumFragmentLength Maximum web-socket fragment length in number of Unicode code units (characters)
- * (exceeded message length leads to fragmentation of messages).
- * @param idleTimeout Maximum idle time of web-socket session before the session is closed (milliseconds).
- * @param heartbeatInterval Interval in milliseconds between sending of ping control frames.
- * @param useSSE when is true use SSE else use WS
- */
- public Configuration(final int maximumFragmentLength, final int idleTimeout, final int heartbeatInterval,
- final boolean useSSE) {
- checkArgument(idleTimeout > 0, "Idle timeout must be specified by positive value.");
- checkArgument(maximumFragmentLength >= 0 && maximumFragmentLength < MAX_FRAGMENT_LENGTH,
- "Maximum fragment length must be disabled (0) or specified by positive value less than 64 KB.");
- checkArgument(heartbeatInterval >= 0, "Heartbeat ping interval must be "
- + "disabled (0) or specified by positive value.");
-
- this.maximumFragmentLength = maximumFragmentLength;
- this.idleTimeout = idleTimeout;
- this.heartbeatInterval = heartbeatInterval;
- this.useSSE = useSSE;
- }
-
- public int getMaximumFragmentLength() {
- return maximumFragmentLength;
- }
-
- public int getIdleTimeout() {
- return idleTimeout;
- }
-
- public int getHeartbeatInterval() {
- return heartbeatInterval;
- }
-
- /**
- * Getter for useSSE.
- *
- * @return true in situation when we use SSE. False in situation when we use WS
- */
- public boolean isUseSSE() {
- return useSSE;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("maximumFragmentLength", maximumFragmentLength)
- .add("idleTimeout", idleTimeout)
- .add("heartbeatInterval", heartbeatInterval)
- .add("useSSE", useSSE)
- .toString();
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright © 2019 FRINX s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.nb.rfc8040.streams;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * RESTCONF configuration holder and verifier.
+ *
+ * @param maximumFragmentLength Maximum web-socket fragment length in number of Unicode code units (characters)
+ * (exceeded message length leads to fragmentation of messages).
+ * @param idleTimeout Maximum idle time of web-socket session before the session is closed (milliseconds).
+ * @param heartbeatInterval Interval in milliseconds between sending of ping control frames.
+ * @param useSSE when is {@code true} use SSE else use WS
+ */
+public record StreamsConfiguration(int maximumFragmentLength, int idleTimeout, int heartbeatInterval, boolean useSSE) {
+ public StreamsConfiguration {
+ checkArgument(maximumFragmentLength >= 0 && maximumFragmentLength < 65535,
+ "Maximum fragment length must be disabled (0) or specified by positive value less than 64KiB");
+ checkArgument(idleTimeout > 0, "Idle timeout must be specified by positive value.");
+ checkArgument(heartbeatInterval >= 0,
+ "Heartbeat ping interval must be disabled (0) or specified by positive value.");
+ }
+}
\ No newline at end of file
* @param configuration Web-socket configuration holder.
*/
@Inject
- public WebSocketInitializer(final ScheduledThreadPool scheduledThreadPool, final Configuration configuration) {
+ public WebSocketInitializer(final ScheduledThreadPool scheduledThreadPool,
+ final StreamsConfiguration configuration) {
executorService = scheduledThreadPool.getExecutor();
- maximumFragmentLength = configuration.getMaximumFragmentLength();
- heartbeatInterval = configuration.getHeartbeatInterval();
- idleTimeoutMillis = configuration.getIdleTimeout();
+ maximumFragmentLength = configuration.maximumFragmentLength();
+ heartbeatInterval = configuration.heartbeatInterval();
+ idleTimeoutMillis = configuration.idleTimeout();
}
/**
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.Uint32;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
final RestconfDataServiceImpl dataService = new RestconfDataServiceImpl(
() -> DatabindContext.ofModel(contextRef), mockDataBroker, mock(DOMMountPointService.class),
- mock(RestconfStreamsSubscriptionService.class), actionService, mock(Configuration.class));
+ mock(RestconfStreamsSubscriptionService.class), actionService, new StreamsConfiguration(0, 1, 0, false));
final var nodeAndStack = DataSchemaContextTree.from(contextRef).enterPath(ACTION_YII).orElseThrow();
final var node = nodeAndStack.node().getDataSchemaNode();
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
@Mock
private RestconfStreamsSubscriptionService delegRestconfSubscrService;
@Mock
- private Configuration configuration;
- @Mock
private MultivaluedMap<String, String> queryParamenters;
@Before
doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
dataService = new RestconfDataServiceImpl(() -> DatabindContext.ofModel(contextRef), mockDataBroker,
- mountPointService, delegRestconfSubscrService, actionService, configuration);
+ mountPointService, delegRestconfSubscrService, actionService, new StreamsConfiguration(0, 1, 0, false));
doReturn(Optional.of(mountPoint)).when(mountPointService)
.getMountPoint(any(YangInstanceIdentifier.class));
doReturn(Optional.of(FixedDOMSchemaService.of(contextRef))).when(mountPoint)
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
@Before
public void setup() {
invokeOperationsService = new RestconfInvokeOperationsServiceImpl(rpcService, mountPointService,
- mock(Configuration.class));
+ new StreamsConfiguration(0, 1, 0, false));
}
@Test
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
+import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenerAdapter;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker;
import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
@Mock
private DOMNotificationService notificationService;
- private Configuration configurationWs;
- private Configuration configurationSse;
+ private StreamsConfiguration configurationWs;
+ private StreamsConfiguration configurationSse;
private EffectiveModelContext modelContext;
private DatabindProvider databindProvider;
modelContext = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/notifications"));
databindProvider = () -> DatabindContext.ofModel(modelContext);
- configurationWs = new Configuration(0, 100, 10, false);
- configurationSse = new Configuration(0, 100, 10, true);
+ configurationWs = new StreamsConfiguration(0, 100, 10, false);
+ configurationSse = new StreamsConfiguration(0, 100, 10, true);
}
@BeforeClass