Skip to content

Commit

Permalink
WIP transport refactor server
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinherron committed Sep 29, 2022
1 parent 182fea4 commit 2a1f3a7
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 7 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 the Eclipse Milo Authors
* Copyright (c) 2022 the Eclipse Milo Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -60,6 +60,7 @@
import static org.eclipse.milo.opcua.sdk.server.util.UaEnumUtil.browseResultMasks;
import static org.eclipse.milo.opcua.sdk.server.util.UaEnumUtil.nodeClasses;
import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l;
import static org.eclipse.milo.opcua.stack.core.util.FutureUtils.failedUaFuture;

public class BrowseHelper {

Expand Down Expand Up @@ -119,6 +120,15 @@ public CompletableFuture<BrowseResult> browse(
}
}

public CompletableFuture<BrowseResult[]> browseNext(
OpcUaServer server,
Session session,
BrowseNextRequest request
) {

return new BrowseNext2(server, session, request).browseNext();
}

public void browseNext(ServiceRequest service) {
OpcUaServer server = service.attr(ServiceAttributes.SERVER_KEY).get();

Expand Down Expand Up @@ -428,6 +438,85 @@ private CompletableFuture<ExpandedNodeId> getTypeDefinition(NodeId nodeId) {

}

private static class BrowseNext2 {

private final OpcUaServer server;
private final Session session;
private final BrowseNextRequest request;


private BrowseNext2(OpcUaServer server, Session session, BrowseNextRequest request) {
this.server = server;
this.session = session;
this.request = request;
}

public CompletableFuture<BrowseResult[]> browseNext() {
List<ByteString> continuationPoints = List.of(request.getContinuationPoints());

if (continuationPoints.isEmpty()) {
return failedUaFuture(StatusCodes.Bad_NothingToDo);
}
if (continuationPoints.size() >
server.getConfig().getLimits().getMaxBrowseContinuationPoints().intValue()) {

return failedUaFuture(StatusCodes.Bad_TooManyOperations);
}

var results = new ArrayList<BrowseResult>();

for (ByteString bs : continuationPoints) {
if (request.getReleaseContinuationPoints()) {
results.add(release(bs));
} else {
results.add(references(bs));
}
}

return CompletableFuture.completedFuture(results.toArray(BrowseResult[]::new));
}

private BrowseResult release(ByteString bs) {
BrowseContinuationPoint c = session.getBrowseContinuationPoints().remove(bs);

return c != null ?
new BrowseResult(StatusCode.GOOD, null, null) :
new BrowseResult(BAD_CONTINUATION_POINT_INVALID, null, null);
}

private BrowseResult references(ByteString bs) {
BrowseContinuationPoint c = session.getBrowseContinuationPoints().remove(bs);

if (c != null) {
int max = c.max;
List<ReferenceDescription> references = c.references;

if (references.size() > max) {
List<ReferenceDescription> subList = references.subList(0, max);
List<ReferenceDescription> current = List.copyOf(subList);
subList.clear();

session.getBrowseContinuationPoints().put(c.identifier, c);

return new BrowseResult(
StatusCode.GOOD,
c.identifier,
current.toArray(new ReferenceDescription[0])
);
} else {
return new BrowseResult(
StatusCode.GOOD,
null,
references.toArray(new ReferenceDescription[0])
);
}
} else {
return new BrowseResult(BAD_CONTINUATION_POINT_INVALID, null, null);
}
}

}

private static class BrowseNext implements Runnable {

private final Session session;
Expand Down Expand Up @@ -505,7 +594,8 @@ private BrowseResult references(ByteString bs) {
return new BrowseResult(
StatusCode.GOOD,
null,
references.toArray(new ReferenceDescription[0]));
references.toArray(new ReferenceDescription[0])
);
}
} else {
return new BrowseResult(BAD_CONTINUATION_POINT_INVALID, null, null);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 the Eclipse Milo Authors
* Copyright (c) 2022 the Eclipse Milo Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -46,6 +46,7 @@

import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.stream.Collectors.toList;
import static org.eclipse.milo.opcua.sdk.server.services2.AbstractServiceSet.createResponseHeader;
import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.a;
import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l;
Expand Down Expand Up @@ -100,6 +101,40 @@ public void onTranslateBrowsePaths(ServiceRequest service) {
}, server.getExecutorService());
}

public CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> translateBrowsePaths(
TranslateBrowsePathsToNodeIdsRequest request
) {

List<BrowsePath> browsePaths = List.of(request.getBrowsePaths());

if (browsePaths.isEmpty()) {
return failedUaFuture(StatusCodes.Bad_NothingToDo);
}
if (browsePaths.size() >
server.getConfig().getLimits().getMaxNodesPerTranslateBrowsePathsToNodeIds().intValue()) {

return failedUaFuture(StatusCodes.Bad_TooManyOperations);
}

var futures = new ArrayList<CompletableFuture<BrowsePathResult>>(browsePaths.size());

for (BrowsePath browsePath : browsePaths) {
futures.add(translate(browsePath));
}

return sequence(futures).thenComposeAsync(results -> {
ResponseHeader header = createResponseHeader(request);

var response = new TranslateBrowsePathsToNodeIdsResponse(
header,
results.toArray(BrowsePathResult[]::new),
new DiagnosticInfo[0]
);

return CompletableFuture.completedFuture(response);
}, server.getExecutorService());
}

private CompletableFuture<BrowsePathResult> translate(BrowsePath browsePath) {
CompletableFuture<BrowsePathResult> future = new CompletableFuture<>();

Expand Down
@@ -1,3 +1,13 @@
/*
* Copyright (c) 2022 the Eclipse Milo Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/

package org.eclipse.milo.opcua.sdk.server.services2.impl;

import java.util.List;
Expand All @@ -10,6 +20,7 @@
import org.eclipse.milo.opcua.sdk.server.api.services.ViewServices.RegisterNodesContext;
import org.eclipse.milo.opcua.sdk.server.api.services.ViewServices.UnregisterNodesContext;
import org.eclipse.milo.opcua.sdk.server.services.helpers.BrowseHelper;
import org.eclipse.milo.opcua.sdk.server.services.helpers.BrowsePathsHelper;
import org.eclipse.milo.opcua.sdk.server.services2.ViewServiceSet2;
import org.eclipse.milo.opcua.stack.core.StatusCodes;
import org.eclipse.milo.opcua.stack.core.UaException;
Expand Down Expand Up @@ -71,8 +82,26 @@ public CompletableFuture<BrowseNextResponse> onBrowseNext(
BrowseNextRequest request
) {

// TODO
return failedUaFuture(StatusCodes.Bad_NotImplemented);
Session session;
try {
session = server.getSessionManager()
.getSession(context, request.getRequestHeader());
} catch (UaException e) {
// TODO Session-less service invocation?
return CompletableFuture.failedFuture(e);
}

CompletableFuture<BrowseNextResponse> future = browseHelper.browseNext(server, session, request)
.thenApply(results -> {
ResponseHeader header = createResponseHeader(request);

return new BrowseNextResponse(header, results, new DiagnosticInfo[0]);
});

session.getSessionDiagnostics().getBrowseNextCount().record(future);
session.getSessionDiagnostics().getTotalRequestCount().record(future);

return future;
}

@Override
Expand All @@ -81,8 +110,24 @@ public CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> onTranslateBrows
TranslateBrowsePathsToNodeIdsRequest request
) {

// TODO
return failedUaFuture(StatusCodes.Bad_NotImplemented);
Session session;
try {
session = server.getSessionManager()
.getSession(context, request.getRequestHeader());
} catch (UaException e) {
// TODO Session-less service invocation?
return CompletableFuture.failedFuture(e);
}

var browsePathsHelper = new BrowsePathsHelper(() -> Optional.ofNullable(session), server);

CompletableFuture<TranslateBrowsePathsToNodeIdsResponse> future =
browsePathsHelper.translateBrowsePaths(request);

session.getSessionDiagnostics().getTranslateBrowsePathsToNodeIdsCount().record(future);
session.getSessionDiagnostics().getTotalRequestCount().record(future);

return future;
}

@Override
Expand Down

0 comments on commit 2a1f3a7

Please sign in to comment.