use of org.openremote.agent.protocol.Protocol in project openremote by openremote.
the class HttpClientProtocol method doLinkAttribute.
@Override
protected void doLinkAttribute(AssetAttribute attribute, AssetAttribute protocolConfiguration) {
AttributeRef protocolConfigurationRef = protocolConfiguration.getReferenceOrThrow();
Pair<ResteasyWebTarget, List<Integer>> clientAndFailureCodes;
clientAndFailureCodes = clientMap.get(protocolConfigurationRef);
WebTarget client = clientAndFailureCodes != null ? clientAndFailureCodes.key : null;
if (client == null) {
LOG.warning("Attempt to link attribute to non existent protocol configuration: " + attribute.getReferenceOrThrow());
return;
}
String method = Values.getMetaItemValueOrThrow(attribute, META_ATTRIBUTE_METHOD, StringValue.class, false, true).map(StringValue::getString).orElse(DEFAULT_HTTP_METHOD);
String path = Values.getMetaItemValueOrThrow(attribute, META_ATTRIBUTE_PATH, StringValue.class, false, true).map(StringValue::getString).orElse(null);
String contentType = Values.getMetaItemValueOrThrow(attribute, META_ATTRIBUTE_CONTENT_TYPE, StringValue.class, false, true).map(StringValue::getString).orElse(null);
Value body = attribute.getMetaItem(META_ATTRIBUTE_BODY).flatMap(AbstractValueHolder::getValue).orElse(null);
List<Integer> failureCodes = attribute.getMetaItem(META_FAILURE_CODES).flatMap(AbstractValueHolder::getValueAsArray).flatMap(arrayValue -> Values.getArrayElements(arrayValue, NumberValue.class, true, false, number -> Values.getIntegerCoerced(number).orElse(null))).map(fCodes -> {
if (clientAndFailureCodes.value != null) {
fCodes.addAll(clientAndFailureCodes.value);
}
return fCodes;
}).orElseGet(() -> {
if (clientAndFailureCodes.value != null) {
return clientAndFailureCodes.value;
}
return null;
});
MultivaluedMap<String, String> headers = Values.getMetaItemValueOrThrow(attribute, META_HEADERS, ObjectValue.class, false, true).flatMap(objectValue -> getMultivaluedMap(objectValue, true)).orElse(null);
MultivaluedMap<String, String> queryParams = Values.getMetaItemValueOrThrow(attribute, META_QUERY_PARAMETERS, ObjectValue.class, false, true).flatMap(objectValue -> getMultivaluedMap(objectValue, false)).orElse(null);
Optional<Integer> pollingSeconds = Values.getMetaItemValueOrThrow(attribute, META_ATTRIBUTE_POLLING_SECONDS, NumberValue.class, false, true).map(polling -> Values.getIntegerCoerced(polling).map(seconds -> seconds < 1 ? null : seconds).orElseThrow(() -> new IllegalArgumentException("Polling seconds meta item must be an integer >= 1")));
final AttributeRef attributeRef = attribute.getReferenceOrThrow();
boolean updateConnectionStatus = !pollingMap.containsKey(protocolConfigurationRef);
HttpClientRequest clientRequest = buildClientRequest(client, path, method, headers, queryParams, failureCodes, updateConnectionStatus, body, contentType);
LOG.fine("Creating HTTP request for linked attribute '" + clientRequest + "': " + attributeRef);
requestMap.put(attributeRef, clientRequest);
pollingSeconds.ifPresent(seconds -> pollingMap.put(attributeRef, schedulePollingRequest(attributeRef, protocolConfigurationRef, clientRequest, seconds)));
}
use of org.openremote.agent.protocol.Protocol in project openremote by openremote.
the class AgentService method linkAttributes.
protected void linkAttributes(AssetAttribute protocolConfiguration, Collection<AssetAttribute> attributes) {
withLock(getClass().getSimpleName() + "::linkAttributes", () -> {
LOG.fine("Linking all attributes that use protocol attribute: " + protocolConfiguration);
Protocol protocol = getProtocol(protocolConfiguration);
if (protocol == null) {
LOG.severe("Cannot link protocol attributes as protocol is null: " + protocolConfiguration);
return;
}
attributes.removeIf(attr -> linkedAttributes.contains(attr.getReferenceOrThrow()));
linkedAttributes.addAll(attributes.stream().map(AssetAttribute::getReferenceOrThrow).collect(Collectors.toList()));
try {
LOG.finest("Linking protocol attributes to: " + protocol.getProtocolName());
protocol.linkAttributes(attributes, protocolConfiguration);
} catch (Exception ex) {
LOG.log(Level.SEVERE, "Ignoring error on linking attributes to protocol: " + protocol.getProtocolName(), ex);
// Update the status of this protocol configuration to error
publishProtocolConnectionStatus(protocolConfiguration.getReferenceOrThrow(), ERROR);
}
});
}
use of org.openremote.agent.protocol.Protocol in project openremote by openremote.
the class AgentService method unlinkAttributes.
protected void unlinkAttributes(AssetAttribute protocolConfiguration, Collection<AssetAttribute> attributes) {
withLock(getClass().getSimpleName() + "::unlinkAttributes", () -> {
LOG.fine("Unlinking all attributes that use protocol attribute: " + protocolConfiguration);
Protocol protocol = getProtocol(protocolConfiguration);
if (protocol == null) {
LOG.severe("Cannot unlink protocol attributes as protocol is null: " + protocolConfiguration);
return;
}
attributes.removeIf(attr -> !linkedAttributes.contains(attr.getReferenceOrThrow()));
linkedAttributes.removeAll(attributes.stream().map(AssetAttribute::getReferenceOrThrow).collect(Collectors.toList()));
try {
LOG.finest("Unlinking protocol attributes from: " + protocol.getProtocolName());
protocol.unlinkAttributes(attributes, protocolConfiguration);
} catch (Exception ex) {
LOG.log(Level.SEVERE, "Ignoring error on unlinking attributes from protocol: " + protocol.getProtocolName(), ex);
// Update the status of this protocol configuration to error
publishProtocolConnectionStatus(protocolConfiguration.getReferenceOrThrow(), ERROR);
}
});
}
use of org.openremote.agent.protocol.Protocol in project openremote by openremote.
the class LocalAgentConnector method getDiscoveredLinkedAttributes.
@Override
public Asset[] getDiscoveredLinkedAttributes(AttributeRef protocolConfigurationRef, FileInfo fileInfo) throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
Optional<Pair<Protocol, AssetAttribute>> protocolAndConfigOptional = getProtocolAndConfig(protocolConfigurationRef);
if (!protocolAndConfigOptional.isPresent()) {
throw new IllegalArgumentException("Protocol not found for: " + protocolConfigurationRef);
}
Pair<Protocol, AssetAttribute> protocolAndConfig = protocolAndConfigOptional.get();
// Check protocol is of correct type
if (!(protocolAndConfigOptional.get().key instanceof ProtocolLinkedAttributeImport)) {
LOG.info("Protocol not of type '" + ProtocolLinkedAttributeImport.class.getSimpleName() + "'");
throw new UnsupportedOperationException("Protocol doesn't support linked attribute import:" + protocolAndConfigOptional.get().key.getProtocolDisplayName());
}
ProtocolLinkedAttributeImport discoveryProtocol = (ProtocolLinkedAttributeImport) protocolAndConfig.key;
return discoveryProtocol.discoverLinkedAssetAttributes(protocolAndConfig.value, fileInfo);
}
use of org.openremote.agent.protocol.Protocol in project openremote by openremote.
the class AgentService method processAssetChange.
/**
* Looks for new, modified and obsolete AGENT_LINK attributes and links / unlinks them
* with the protocol
*/
protected void processAssetChange(Asset asset, PersistenceEvent persistenceEvent) {
LOG.finest("Processing asset persistence event: " + persistenceEvent.getCause());
switch(persistenceEvent.getCause()) {
case INSERT:
// Asset insert persistence events can be fired before the agent insert persistence event
// so need to check that all protocol configs exist - any that don't we will exclude here
// and handle in agent insert
// If an agent insert just occurred then we will end up trying to link the attribute again
// so we keep track of linked attributes to avoid this
// Link any AGENT_LINK attributes to their referenced protocol
Map<AssetAttribute, List<AssetAttribute>> groupedAgentLinksAttributes = getGroupedAgentLinkAttributes(asset.getAttributesStream(), attribute -> true, attribute -> LOG.warning("Linked protocol configuration not found: " + attribute));
groupedAgentLinksAttributes.forEach(this::linkAttributes);
break;
case UPDATE:
List<String> propertyNames = Arrays.asList(persistenceEvent.getPropertyNames());
// Check if attributes of the asset have been modified
int attributesIndex = propertyNames.indexOf("attributes");
if (attributesIndex < 0) {
return;
}
// Attributes have possibly changed so need to compare old and new state to determine any changes to
// AGENT_LINK attributes
List<AssetAttribute> oldAgentLinkedAttributes = attributesFromJson((ObjectValue) persistenceEvent.getPreviousState()[attributesIndex], asset.getId()).filter(AgentLink::hasAgentLink).collect(Collectors.toList());
List<AssetAttribute> newAgentLinkedAttributes = attributesFromJson((ObjectValue) persistenceEvent.getCurrentState()[attributesIndex], asset.getId()).filter(AgentLink::hasAgentLink).collect(Collectors.toList());
// Unlink thing attributes that are in old but not in new
getGroupedAgentLinkAttributes(getAddedOrModifiedAttributes(newAgentLinkedAttributes, oldAgentLinkedAttributes, key -> key.equals(VALUE_TIMESTAMP_FIELD_NAME)), attribute -> true).forEach(this::unlinkAttributes);
// Link thing attributes that are in new but not in old
getGroupedAgentLinkAttributes(getAddedOrModifiedAttributes(oldAgentLinkedAttributes, newAgentLinkedAttributes, key -> key.equals(VALUE_TIMESTAMP_FIELD_NAME)), attribute -> true, attribute -> LOG.warning("Linked protocol configuration not found: " + attribute)).forEach(this::linkAttributes);
break;
case DELETE:
{
// Unlink any AGENT_LINK attributes from the referenced protocol
Map<AssetAttribute, List<AssetAttribute>> groupedAgentLinkAndProtocolAttributes = getGroupedAgentLinkAttributes(asset.getAttributesStream(), attribute -> true);
groupedAgentLinkAndProtocolAttributes.forEach(this::unlinkAttributes);
break;
}
}
}
Aggregations