use of org.openremote.model.asset.agent.AgentLink in project openremote by openremote.
the class AgentService method startAgent.
protected void startAgent(Agent<?, ?, ?> agent) {
withLock(getClass().getSimpleName() + "::startAgent", () -> {
Protocol<?> protocol = null;
try {
protocol = agent.getProtocolInstance();
protocolInstanceMap.put(agent.getId(), protocol);
LOG.fine("Starting protocol instance: " + protocol);
protocol.start(container);
LOG.fine("Started protocol instance:" + protocol);
LOG.finer("Linking attributes to protocol instance: " + protocol);
// Get all assets that have attributes with agent link meta for this agent
List<Asset<?>> assets = assetStorageService.findAll(new AssetQuery().attributes(new AttributePredicate().meta(new NameValuePredicate(AGENT_LINK, new StringPredicate(agent.getId()), false, new NameValuePredicate.Path("id")))));
LOG.finer("Found '" + assets.size() + "' asset(s) with attributes linked to this protocol instance: " + protocol);
assets.forEach(asset -> getGroupedAgentLinkAttributes(asset.getAttributes().stream(), assetAttribute -> assetAttribute.getMetaValue(AGENT_LINK).map(agentLink -> agentLink.getId().equals(agent.getId())).orElse(false)).forEach((agnt, attributes) -> linkAttributes(agnt, asset.getId(), attributes)));
} catch (Exception e) {
if (protocol != null) {
try {
protocol.stop(container);
} catch (Exception ignored) {
}
}
protocolInstanceMap.remove(agent.getId());
LOG.log(Level.SEVERE, "Failed to start protocol instance for agent: " + agent, e);
sendAttributeEvent(new AttributeEvent(agent.getId(), Agent.STATUS.getName(), ConnectionStatus.ERROR));
}
});
}
use of org.openremote.model.asset.agent.AgentLink in project openremote by openremote.
the class AssetViewActivity method onAgentStatusEvent.
protected void onAgentStatusEvent(AgentStatusEvent event) {
for (AttributeView attributeView : attributeViews) {
AssetAttribute assetAttribute = attributeView.getAttribute();
Optional<AttributeRef> assetAttributeRef = assetAttribute.getReference();
if (asset.getWellKnownType() == AssetType.AGENT) {
if (assetAttributeRef.map(ref -> ref.equals(event.getProtocolConfiguration())).orElse(false)) {
attributeView.setStatus(event.getConnectionStatus());
}
} else {
AgentLink.getAgentLink(assetAttribute).filter(agentLink -> agentLink.equals(event.getProtocolConfiguration())).ifPresent(agentLink -> {
attributeView.setStatus(event.getConnectionStatus());
});
}
}
}
use of org.openremote.model.asset.agent.AgentLink in project openremote by openremote.
the class HTTPProtocol method doLinkAttribute.
@Override
protected void doLinkAttribute(String assetId, Attribute<?> attribute, HTTPAgentLink agentLink) {
AttributeRef attributeRef = new AttributeRef(assetId, attribute.getName());
String method = agentLink.getMethod().map(Enum::name).orElse(DEFAULT_HTTP_METHOD);
String path = agentLink.getPath().orElse(null);
String contentType = agentLink.getContentType().orElse(null);
Map<String, List<String>> headers = agentLink.getHeaders().orElse(null);
Map<String, List<String>> queryParams = agentLink.getQueryParameters().orElse(null);
Integer pollingMillis = agentLink.getPollingMillis().map(millis -> Math.max(millis, MIN_POLLING_MILLIS)).orElse(null);
boolean pagingEnabled = agentLink.getPagingMode().orElse(false);
String pollingAttribute = agentLink.getPollingAttribute().orElse(null);
if (!TextUtil.isNullOrEmpty(pollingAttribute)) {
synchronized (pollingLinkedAttributeMap) {
AttributeRef pollingSourceRef = new AttributeRef(attributeRef.getId(), pollingAttribute);
pollingLinkedAttributeMap.compute(pollingSourceRef, (ref, links) -> {
if (links == null) {
links = new HashSet<>();
}
links.add(attributeRef);
return links;
});
}
}
String body = agentLink.getWriteValue().orElse(null);
if (client == null) {
LOG.warning("Client is undefined: " + this);
return;
}
HttpClientRequest clientRequest = buildClientRequest(path, method, headers != null ? WebTargetBuilder.mapToMultivaluedMap(headers, new MultivaluedHashMap<>()) : null, queryParams != null ? WebTargetBuilder.mapToMultivaluedMap(queryParams, new MultivaluedHashMap<>()) : null, pagingEnabled, contentType);
LOG.fine("Creating HTTP request for attributeRef '" + clientRequest + "': " + attributeRef);
requestMap.put(attributeRef, clientRequest);
Optional.ofNullable(pollingMillis).ifPresent(seconds -> pollingMap.put(attributeRef, schedulePollingRequest(attributeRef, agentLink, clientRequest, body, seconds)));
}
use of org.openremote.model.asset.agent.AgentLink in project openremote by openremote.
the class ValueUtil method doInitialise.
/**
* Initialise the asset model and throw an {@link IllegalStateException} exception if a problem is detected; this
* can be called by applications at startup to fail hard and fast if the asset model is un-usable
*/
protected static void doInitialise() throws IllegalStateException {
assetInfoMap = new HashMap<>();
assetTypeMap = new HashMap<>();
agentLinkMap = new HashMap<>();
metaItemDescriptors = new ArrayList<>();
valueDescriptors = new ArrayList<>();
generator = null;
// Provide basic Object Mapper and enhance once asset model is initialised
JSON = configureObjectMapper(new ObjectMapper());
LOG.info("Initialising asset model...");
Map<Class<? extends Asset<?>>, List<NameHolder>> assetDescriptorProviders = new TreeMap<>(new ClassHierarchyComparator());
// noinspection RedundantCast
assetDescriptorProviders.put((Class<? extends Asset<?>>) (Class<?>) Asset.class, new ArrayList<>(getDescriptorFields(Asset.class)));
getModelProviders().forEach(assetModelProvider -> {
LOG.fine("Processing asset model provider: " + assetModelProvider.getClass().getSimpleName());
LOG.fine("Auto scan = " + assetModelProvider.useAutoScan());
if (assetModelProvider.useAutoScan()) {
Set<Class<? extends Asset<?>>> assetClasses = getAssetClasses(assetModelProvider);
LOG.fine("Found " + assetClasses.size() + " asset class(es)");
assetClasses.forEach(assetClass -> assetDescriptorProviders.computeIfAbsent(assetClass, aClass -> new ArrayList<>(getDescriptorFields(aClass))));
ModelDescriptors modelDescriptors = assetModelProvider.getClass().getAnnotation(ModelDescriptors.class);
if (modelDescriptors != null) {
for (ModelDescriptor modelDescriptor : modelDescriptors.value()) {
Class<? extends Asset<?>> assetClass = (Class<? extends Asset<?>>) modelDescriptor.assetType();
assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(getDescriptorFields(modelDescriptor.provider()));
return list;
});
}
}
}
if (assetModelProvider.getAssetDescriptors() != null) {
for (AssetDescriptor<?> assetDescriptor : assetModelProvider.getAssetDescriptors()) {
Class<? extends Asset<?>> assetClass = assetDescriptor.getType();
assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
if (list == null) {
list = new ArrayList<>();
}
list.add(assetDescriptor);
return list;
});
}
}
if (assetModelProvider.getAttributeDescriptors() != null) {
assetModelProvider.getAttributeDescriptors().forEach((assetClass, attributeDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(attributeDescriptors);
return list;
}));
}
if (assetModelProvider.getMetaItemDescriptors() != null) {
assetModelProvider.getMetaItemDescriptors().forEach((assetClass, metaDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(metaDescriptors);
return list;
}));
}
if (assetModelProvider.getValueDescriptors() != null) {
assetModelProvider.getValueDescriptors().forEach((assetClass, valueDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(valueDescriptors);
return list;
}));
}
});
// Build each asset info checking that no conflicts occur
Map<Class<? extends Asset<?>>, List<NameHolder>> copy = new HashMap<>(assetDescriptorProviders);
assetDescriptorProviders.forEach((assetClass, descriptors) -> {
// Skip abstract classes as a start point - they should be in the class hierarchy of concrete class
if (!Modifier.isAbstract(assetClass.getModifiers())) {
AssetTypeInfo assetInfo = buildAssetInfo(assetClass, copy);
assetInfoMap.put(assetClass, assetInfo);
assetTypeMap.put(assetInfo.getAssetDescriptor().getName(), assetClass);
if (assetInfo.getAssetDescriptor() instanceof AgentDescriptor) {
AgentDescriptor<?, ?, ?> agentDescriptor = (AgentDescriptor<?, ?, ?>) assetInfo.getAssetDescriptor();
String agentLinkName = agentDescriptor.getAgentLinkClass().getSimpleName();
if (agentLinkMap.containsKey(agentLinkName) && agentLinkMap.get(agentLinkName) != agentDescriptor.getAgentLinkClass()) {
throw new IllegalStateException("AgentLink simple class name must be unique, duplicate found for: " + agentDescriptor.getAgentLinkClass());
}
agentLinkMap.put(agentLinkName, agentDescriptor.getAgentLinkClass());
}
}
});
// Check each value type implements serializable interface
List<ValueDescriptor<?>> nonSerializableValueDescriptors = new ArrayList<>();
valueDescriptors.forEach(vd -> {
if (!Serializable.class.isAssignableFrom(vd.getType())) {
nonSerializableValueDescriptors.add(vd);
}
});
if (!nonSerializableValueDescriptors.isEmpty()) {
String vds = nonSerializableValueDescriptors.stream().map(ValueDescriptor::toString).collect(Collectors.joining(",\n"));
throw new IllegalStateException("One or more value types do not implement java.io.Serializable: " + vds);
}
// Call on finished on each provider
assetModelProviders.forEach(AssetModelProvider::onAssetModelFinished);
// Add agent link sub types to object mapper (need to avoid circular dependency)
NamedType[] agentLinkSubTypes = Arrays.stream(getAgentLinkClasses()).map(agentLinkClass -> new NamedType(agentLinkClass, agentLinkClass.getSimpleName())).toArray(NamedType[]::new);
JSON.registerSubtypes(agentLinkSubTypes);
doSchemaInit();
}
use of org.openremote.model.asset.agent.AgentLink in project openremote by openremote.
the class ProtocolUtil method createGenericAttributeMessageConsumer.
public static Consumer<String> createGenericAttributeMessageConsumer(String assetId, Attribute<?> attribute, AgentLink<?> agentLink, Supplier<Long> currentMillisSupplier, Consumer<AttributeState> stateConsumer) {
ValueFilter[] matchFilters = agentLink.getMessageMatchFilters().orElse(null);
ValuePredicate matchPredicate = agentLink.getMessageMatchPredicate().orElse(null);
if (matchPredicate == null) {
return null;
}
return message -> {
if (!TextUtil.isNullOrEmpty(message)) {
Object messageFiltered = applyValueFilters(message, matchFilters);
if (messageFiltered != null) {
if (matchPredicate.asPredicate(currentMillisSupplier).test(messageFiltered)) {
Protocol.LOG.finest("Inbound message meets attribute matching meta so writing state to state consumer for attribute: asssetId=" + assetId + ", attribute=" + attribute.getName());
stateConsumer.accept(new AttributeState(assetId, attribute.getName(), message));
}
}
}
};
}
Aggregations