use of org.openremote.model.gateway.GatewayDisconnectEvent in project openremote by openremote.
the class GatewayClientService method onCentralManagerMessage.
protected void onCentralManagerMessage(GatewayConnection connection, String message) {
String messageId = null;
SharedEvent event = null;
if (message.startsWith(EventRequestResponseWrapper.MESSAGE_PREFIX)) {
EventRequestResponseWrapper<?> wrapper = messageFromString(message, EventRequestResponseWrapper.MESSAGE_PREFIX, EventRequestResponseWrapper.class);
messageId = wrapper.getMessageId();
event = wrapper.getEvent();
}
if (message.startsWith(SharedEvent.MESSAGE_PREFIX)) {
event = messageFromString(message, SharedEvent.MESSAGE_PREFIX, SharedEvent.class);
}
if (event != null) {
if (event instanceof GatewayDisconnectEvent) {
if (((GatewayDisconnectEvent) event).getReason() == GatewayDisconnectEvent.Reason.PERMANENT_ERROR) {
LOG.info("Central manager requested disconnect due to permanent error (likely this version of the edge gateway software is not compatible with that manager version)");
destroyGatewayClient(connection, clientRealmMap.get(connection.getLocalRealm()));
clientRealmMap.put(connection.getLocalRealm(), null);
}
} else if (event instanceof AttributeEvent) {
assetProcessingService.sendAttributeEvent((AttributeEvent) event, AttributeEvent.Source.INTERNAL);
} else if (event instanceof AssetEvent) {
AssetEvent assetEvent = (AssetEvent) event;
if (assetEvent.getCause() == AssetEvent.Cause.CREATE || assetEvent.getCause() == AssetEvent.Cause.UPDATE) {
Asset asset = assetEvent.getAsset();
asset.setRealm(connection.getLocalRealm());
LOG.finer("Request from central manager to create/update an asset: Realm=" + connection.getLocalRealm() + ", Asset<?> ID=" + asset.getId());
try {
asset = assetStorageService.merge(asset, true);
} catch (Exception e) {
LOG.log(Level.INFO, "Request from central manager to create/update an asset failed: Realm=" + connection.getLocalRealm() + ", Asset<?> ID=" + asset.getId(), e);
}
}
} else if (event instanceof DeleteAssetsRequestEvent) {
DeleteAssetsRequestEvent deleteRequest = (DeleteAssetsRequestEvent) event;
LOG.finer("Request from central manager to delete asset(s): Realm=" + connection.getLocalRealm() + ", Asset<?> IDs=" + Arrays.toString(deleteRequest.getAssetIds().toArray()));
boolean success = false;
try {
success = assetStorageService.delete(deleteRequest.getAssetIds());
} catch (Exception e) {
LOG.log(Level.INFO, "Request from central manager to create/update an asset failed: Realm=" + connection.getLocalRealm() + ", Asset<?> IDs=" + Arrays.toString(deleteRequest.getAssetIds().toArray()), e);
} finally {
sendCentralManagerMessage(connection.getLocalRealm(), messageToString(EventRequestResponseWrapper.MESSAGE_PREFIX, new EventRequestResponseWrapper<>(messageId, new DeleteAssetsResponseEvent(success, deleteRequest.getAssetIds()))));
}
} else if (event instanceof ReadAssetsEvent) {
ReadAssetsEvent readAssets = (ReadAssetsEvent) event;
AssetQuery query = readAssets.getAssetQuery();
// Force realm to be the one that this client is associated with
query.tenant(new TenantPredicate(connection.getLocalRealm()));
List<Asset<?>> assets = assetStorageService.findAll(readAssets.getAssetQuery());
sendCentralManagerMessage(connection.getLocalRealm(), messageToString(EventRequestResponseWrapper.MESSAGE_PREFIX, new EventRequestResponseWrapper<>(messageId, new AssetsEvent(assets))));
}
}
}
use of org.openremote.model.gateway.GatewayDisconnectEvent in project openremote by openremote.
the class GatewayService method processGatewayConnected.
protected void processGatewayConnected(String gatewayClientId, String sessionId) {
if (!active) {
return;
}
String gatewayId = getGatewayIdFromClientId(gatewayClientId);
GatewayConnector connector = gatewayConnectorMap.get(gatewayId.toLowerCase(Locale.ROOT));
if (connector == null) {
LOG.warning("Gateway connected but not recognised which shouldn't happen: Gateway ID=" + gatewayId);
clientEventService.sendToSession(sessionId, new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.UNRECOGNISED));
clientEventService.closeSession(sessionId);
return;
}
if (connector.isConnected()) {
LOG.warning("Gateway already connected so requesting disconnect on new connection: Gateway ID=" + gatewayId);
clientEventService.sendToSession(sessionId, new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.ALREADY_CONNECTED));
clientEventService.closeSession(sessionId);
return;
}
if (connector.isDisabled()) {
LOG.warning("Gateway is currently disabled so will be ignored: Gateway ID=" + gatewayId);
clientEventService.sendToSession(sessionId, new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.DISABLED));
clientEventService.closeSession(sessionId);
return;
}
connector.connect(createConnectorMessageConsumer(sessionId), () -> clientEventService.closeSession(sessionId));
}
use of org.openremote.model.gateway.GatewayDisconnectEvent in project openremote by openremote.
the class GatewayService method processAssetUpdate.
@Override
public boolean processAssetUpdate(EntityManager em, Asset<?> asset, Attribute<?> attribute, AttributeEvent.Source source) throws AssetProcessingException {
// If the update was generated by a gateway then we don't want to process it here
if (source == AttributeEvent.Source.GATEWAY) {
return false;
}
GatewayConnector connector = gatewayConnectorMap.get(asset.getId().toLowerCase(Locale.ROOT));
if (connector != null) {
LOG.fine("Attribute event for a locally registered gateway asset (Asset ID=" + asset.getId() + "): " + attribute);
GatewayAsset gatewayAsset = (GatewayAsset) asset;
// This is a change to a locally registered gateway
if (GatewayAsset.DISABLED.getName().equals(attribute.getName())) {
boolean disabled = attribute.getValueAs(Boolean.class).orElse(false);
boolean isAlreadyDisabled = gatewayAsset.getDisabled().orElse(false);
// Ensure we update state
gatewayAsset.setDisabled(disabled);
if (disabled != isAlreadyDisabled) {
createUpdateGatewayServiceUser(gatewayAsset);
if (disabled) {
connector.sendMessageToGateway(new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.DISABLED));
}
connector.setDisabled(disabled);
}
}
if (GatewayAsset.CLIENT_SECRET.getName().equals(attribute.getName())) {
String newSecret = attribute.getValueAs(String.class).orElse(null);
if (!TextUtil.isNullOrEmpty(newSecret)) {
LOG.fine("Gateway client secret attribute updated so updating gateway service user secret to match: (Gateway ID=" + asset.getId() + ")");
User gatewayServiceUser = identityProvider.getUserByUsername(asset.getRealm(), User.SERVICE_ACCOUNT_PREFIX + ((GatewayAsset) asset).getClientId().orElse(""));
if (gatewayServiceUser != null) {
identityProvider.resetSecret(asset.getRealm(), gatewayServiceUser.getId(), newSecret);
} else {
LOG.info("Couldn't retrieve gateway service user to update secret: (Gateway ID=" + asset.getId() + ")");
}
} else {
// Push old secret back
assetProcessingService.sendAttributeEvent(new AttributeEvent(asset.getId(), GatewayAsset.CLIENT_SECRET, gatewayAsset.getClientSecret().orElseThrow(() -> new IllegalStateException("Gateway client secret is null which was not expected"))));
}
}
} else {
String gatewayId = assetIdGatewayIdMap.get(asset.getId());
if (gatewayId != null) {
LOG.fine("Attribute event for a gateway descendant asset (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
connector = gatewayConnectorMap.get(gatewayId.toLowerCase(Locale.ROOT));
if (connector == null) {
LOG.warning("Gateway not found for descendant asset, this should not happen!!! (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + ")");
} else {
if (!connector.isConnected()) {
LOG.info("Gateway is not connected so attribute event for descendant asset will be dropped (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
throw new AssetProcessingException(AttributeWriteFailure.GATEWAY_DISCONNECTED, "Gateway is not connected: Gateway ID=" + connector.gatewayId);
}
LOG.fine("Attribute event for a gateway descendant asset being forwarded to the gateway (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
connector.sendMessageToGateway(new AttributeEvent(mapAssetId(gatewayId, asset.getId(), true), attribute.getName(), attribute.getValue().orElse(null), attribute.getTimestamp().orElse(0L)).setParentId(mapAssetId(gatewayId, asset.getParentId(), true)).setRealm(asset.getRealm()));
}
// Consume this event as it is for a gateway descendant and we've sent it to that gateway for processing
return true;
}
}
// Don't consume event for non gateway descendant assets
return false;
}
use of org.openremote.model.gateway.GatewayDisconnectEvent in project openremote by openremote.
the class GatewayConnector method syncAborted.
protected boolean syncAborted() {
if (syncErrors == MAX_SYNC_RETRIES) {
LOG.warning("Gateway sync max retries reached so disconnecting the gateway: Gateway ID=" + gatewayId);
sendMessageToGateway(new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.PERMANENT_ERROR));
disconnect();
return true;
}
return false;
}
use of org.openremote.model.gateway.GatewayDisconnectEvent in project openremote by openremote.
the class GatewayService method processGatewayChange.
protected void processGatewayChange(GatewayAsset gateway, PersistenceEvent<Asset<?>> persistenceEvent) {
switch(persistenceEvent.getCause()) {
case CREATE:
createUpdateGatewayServiceUser(gateway);
synchronized (gatewayConnectorMap) {
GatewayConnector connector = new GatewayConnector(assetStorageService, assetProcessingService, executorService, gateway);
gatewayConnectorMap.put(gateway.getId().toLowerCase(Locale.ROOT), connector);
}
break;
case UPDATE:
// Check if this gateway has a connector
GatewayConnector connector = gatewayConnectorMap.get(gateway.getId().toLowerCase(Locale.ROOT));
if (connector == null) {
break;
}
connector.gateway = gateway;
// Check if disabled
boolean isNowDisabled = gateway.getDisabled().orElse(false);
if (isNowDisabled) {
connector.sendMessageToGateway(new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.DISABLED));
}
connector.setDisabled(isNowDisabled);
int attributeIndex = persistenceEvent.getPropertyNames() != null ? IntStream.range(0, persistenceEvent.getPropertyNames().length).filter(i -> "attributes".equals(persistenceEvent.getPropertyNames()[i])).findFirst().orElse(-1) : -1;
if (attributeIndex >= 0) {
// Check if disabled attribute has changed
AttributeMap oldAttributes = persistenceEvent.getPreviousState("attributes");
boolean wasDisabled = oldAttributes.getValue(GatewayAsset.DISABLED).orElse(false);
if (wasDisabled != isNowDisabled) {
createUpdateGatewayServiceUser(gateway);
}
}
break;
case DELETE:
// Check if this gateway has a connector
connector = gatewayConnectorMap.get(gateway.getId().toLowerCase(Locale.ROOT));
if (connector == null) {
break;
}
synchronized (gatewayConnectorMap) {
connector = gatewayConnectorMap.remove(gateway.getId().toLowerCase(Locale.ROOT));
if (connector != null) {
connector.disconnect();
}
}
removeGatewayServiceUser(gateway);
break;
}
}
Aggregations