use of org.eclipse.milo.opcua.stack.server.services.ServiceRequest in project milo by eclipse.
the class SubscriptionManager method modifyMonitoredItems.
public void modifyMonitoredItems(ServiceRequest service) throws UaException {
ModifyMonitoredItemsRequest request = (ModifyMonitoredItemsRequest) service.getRequest();
UInteger subscriptionId = request.getSubscriptionId();
Subscription subscription = subscriptions.get(subscriptionId);
TimestampsToReturn timestamps = request.getTimestampsToReturn();
List<MonitoredItemModifyRequest> itemsToModify = l(request.getItemsToModify());
if (subscription == null) {
throw new UaException(StatusCodes.Bad_SubscriptionIdInvalid);
}
if (timestamps == null) {
throw new UaException(StatusCodes.Bad_TimestampsToReturnInvalid);
}
if (itemsToModify.isEmpty()) {
throw new UaException(StatusCodes.Bad_NothingToDo);
}
List<NodeId> distinctNodeIds = itemsToModify.stream().map(item -> {
UInteger itemId = item.getMonitoredItemId();
BaseMonitoredItem<?> monitoredItem = subscription.getMonitoredItems().get(itemId);
return monitoredItem != null ? monitoredItem.getReadValueId().getNodeId() : NodeId.NULL_VALUE;
}).filter(NodeId::isNotNull).distinct().collect(toList());
CompletableFuture<Map<NodeId, AttributeGroup>> attributesFuture = readMonitoringAttributes(distinctNodeIds);
attributesFuture.thenAccept(attributeGroups -> {
MonitoredItemModifyResult[] modifyResults = new MonitoredItemModifyResult[itemsToModify.size()];
List<BaseMonitoredItem<?>> monitoredItems = new ArrayList<>();
for (int i = 0; i < itemsToModify.size(); i++) {
MonitoredItemModifyRequest modifyRequest = itemsToModify.get(i);
try {
BaseMonitoredItem<?> monitoredItem = modifyMonitoredItem(modifyRequest, timestamps, subscription, attributeGroups);
monitoredItems.add(monitoredItem);
modifyResults[i] = new MonitoredItemModifyResult(StatusCode.GOOD, monitoredItem.getSamplingInterval(), uint(monitoredItem.getQueueSize()), monitoredItem.getFilterResult());
} catch (UaException e) {
modifyResults[i] = new MonitoredItemModifyResult(e.getStatusCode(), 0.0, UInteger.MIN, null);
}
}
subscription.resetLifetimeCounter();
/*
* Notify AddressSpaces of the items we just modified.
*/
byMonitoredItemType(monitoredItems, dataItems -> server.getAddressSpaceManager().onDataItemsModified(dataItems), eventItems -> server.getAddressSpaceManager().onEventItemsModified(eventItems));
/*
* AddressSpaces have been notified; send response.
*/
ResponseHeader header = service.createResponseHeader();
ModifyMonitoredItemsResponse response = new ModifyMonitoredItemsResponse(header, modifyResults, new DiagnosticInfo[0]);
service.setResponse(response);
});
}
use of org.eclipse.milo.opcua.stack.server.services.ServiceRequest in project milo by eclipse.
the class SubscriptionManager method sessionClosed.
public void sessionClosed(boolean deleteSubscriptions) {
Iterator<Subscription> iterator = subscriptions.values().iterator();
while (iterator.hasNext()) {
Subscription s = iterator.next();
s.setStateListener(null);
if (deleteSubscriptions) {
server.getSubscriptions().remove(s.getId());
server.getEventBus().post(new SubscriptionDeletedEvent(s));
List<BaseMonitoredItem<?>> deletedItems = s.deleteSubscription();
/*
* Notify AddressSpaces the items for this subscription are deleted.
*/
byMonitoredItemType(deletedItems, dataItems -> server.getAddressSpaceManager().onDataItemsDeleted(dataItems), eventItems -> server.getAddressSpaceManager().onEventItemsDeleted(eventItems));
}
iterator.remove();
}
if (deleteSubscriptions) {
while (publishQueue.isNotEmpty()) {
ServiceRequest publishService = publishQueue.poll();
if (publishService != null) {
publishService.setServiceFault(StatusCodes.Bad_SessionClosed);
}
}
}
}
use of org.eclipse.milo.opcua.stack.server.services.ServiceRequest in project milo by eclipse.
the class DefaultSubscriptionServiceSet method onTransferSubscriptions.
@Override
public void onTransferSubscriptions(ServiceRequest service) throws UaException {
TransferSubscriptionsRequest request = (TransferSubscriptionsRequest) service.getRequest();
OpcUaServer server = service.attr(ServiceAttributes.SERVER_KEY).get();
Session session = service.attr(ServiceAttributes.SESSION_KEY).get();
List<UInteger> subscriptionIds = l(request.getSubscriptionIds());
if (subscriptionIds.isEmpty()) {
throw new UaException(StatusCodes.Bad_NothingToDo);
}
List<TransferResult> results = Lists.newArrayList();
for (UInteger subscriptionId : subscriptionIds) {
Subscription subscription = server.getSubscriptions().get(subscriptionId);
if (subscription == null) {
results.add(new TransferResult(new StatusCode(StatusCodes.Bad_SubscriptionIdInvalid), new UInteger[0]));
} else {
Session otherSession = subscription.getSession();
if (!sessionsHaveSameUser(session, otherSession)) {
results.add(new TransferResult(new StatusCode(StatusCodes.Bad_UserAccessDenied), new UInteger[0]));
} else {
UInteger[] availableSequenceNumbers;
synchronized (subscription) {
otherSession.getSubscriptionManager().sendStatusChangeNotification(subscription, new StatusCode(StatusCodes.Good_SubscriptionTransferred));
otherSession.getSubscriptionManager().removeSubscription(subscriptionId);
subscription.setSubscriptionManager(session.getSubscriptionManager());
subscriptionManager.addSubscription(subscription);
subscription.getMonitoredItems().values().forEach(item -> item.setSession(session));
availableSequenceNumbers = subscription.getAvailableSequenceNumbers();
if (request.getSendInitialValues()) {
subscription.getMonitoredItems().values().stream().filter(item -> item instanceof MonitoredDataItem).map(item -> (MonitoredDataItem) item).forEach(MonitoredDataItem::maybeSendLastValue);
}
}
subscription.getSubscriptionDiagnostics().getTransferRequestCount().increment();
ApplicationDescription toClient = session.getClientDescription();
ApplicationDescription fromClient = otherSession.getClientDescription();
if (Objects.equals(toClient, fromClient)) {
subscription.getSubscriptionDiagnostics().getTransferredToSameClientCount().increment();
} else {
subscription.getSubscriptionDiagnostics().getTransferredToAltClientCount().increment();
}
results.add(new TransferResult(StatusCode.GOOD, availableSequenceNumbers));
}
}
}
TransferSubscriptionsResponse response = new TransferSubscriptionsResponse(service.createResponseHeader(), a(results, TransferResult.class), new DiagnosticInfo[0]);
service.setResponse(response);
}
use of org.eclipse.milo.opcua.stack.server.services.ServiceRequest in project milo by eclipse.
the class PublishQueue method poll.
@Nullable
public synchronized ServiceRequest poll() {
long nowNanos = System.nanoTime();
while (true) {
ServiceRequest serviceRequest = serviceQueue.poll();
if (serviceRequest == null) {
return null;
} else {
RequestHeader requestHeader = serviceRequest.getRequest().getRequestHeader();
long millisSinceReceived = TimeUnit.MILLISECONDS.convert(nowNanos - serviceRequest.getReceivedAtNanos(), TimeUnit.NANOSECONDS);
long timeoutHint = requestHeader.getTimeoutHint().longValue();
if (timeoutHint == 0 || millisSinceReceived < timeoutHint) {
return serviceRequest;
} else {
logger.debug("Discarding expired PublishRequest requestHandle={} timestamp={} timeoutHint={}", serviceRequest.getRequest().getRequestHeader().getRequestHandle(), requestHeader.getTimestamp().getJavaDate(), timeoutHint);
serviceRequest.setServiceFault(StatusCodes.Bad_Timeout);
}
}
}
}
use of org.eclipse.milo.opcua.stack.server.services.ServiceRequest in project milo by eclipse.
the class DefaultAttributeHistoryServiceSet method onHistoryUpdate.
@Override
public void onHistoryUpdate(ServiceRequest service) {
historyUpdateMetric.record(service);
HistoryUpdateRequest request = (HistoryUpdateRequest) service.getRequest();
OpcUaServer server = service.attr(ServiceAttributes.SERVER_KEY).get();
Session session = service.attr(ServiceAttributes.SESSION_KEY).get();
List<HistoryUpdateDetails> historyUpdateDetailsList = l(request.getHistoryUpdateDetails()).stream().map(e -> (HistoryUpdateDetails) e.decode(server.getSerializationContext())).collect(Collectors.toList());
if (historyUpdateDetailsList.isEmpty()) {
service.setServiceFault(StatusCodes.Bad_NothingToDo);
return;
}
if (historyUpdateDetailsList.size() > server.getConfig().getLimits().getMaxNodesPerWrite().intValue()) {
service.setServiceFault(StatusCodes.Bad_TooManyOperations);
return;
}
DiagnosticsContext<HistoryUpdateDetails> diagnosticsContext = new DiagnosticsContext<>();
HistoryUpdateContext context = new HistoryUpdateContext(server, session, diagnosticsContext);
server.getAddressSpaceManager().historyUpdate(context, historyUpdateDetailsList);
context.getFuture().thenAccept(values -> {
ResponseHeader header = service.createResponseHeader();
DiagnosticInfo[] diagnosticInfos = diagnosticsContext.getDiagnosticInfos(historyUpdateDetailsList);
HistoryUpdateResponse response = new HistoryUpdateResponse(header, a(values, HistoryUpdateResult.class), diagnosticInfos);
service.setResponse(response);
});
}
Aggregations