Search in sources :

Example 1 with AssetAttribute

use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.

the class AbstractProtocol method updateLinkedAttribute.

/**
 * Update the value of a linked attribute. Call this to publish new sensor values. This will apply any
 * {@link MessageFilter}s that have been set for the {@link Attribute} against the {@link AttributeState#value}
 * before sending on the sensor queue.
 */
@SuppressWarnings("unchecked")
protected final void updateLinkedAttribute(final AttributeState finalState, long timestamp) {
    withLock(getProtocolName() + "::updateLinkedAttribute", () -> {
        AttributeState state = finalState;
        AssetAttribute attribute = linkedAttributes.get(state.getAttributeRef());
        if (attribute == null) {
            LOG.severe("Update linked attribute called for un-linked attribute: " + state);
            return;
        }
        if (state.getValue().isPresent()) {
            List<MessageFilter> filters;
            Value value = state.getValue().get();
            filters = linkedAttributeFilters.get(state.getAttributeRef());
            if (filters != null) {
                LOG.fine("Applying message filters to sensor value...");
                for (MessageFilter filter : filters) {
                    if (filter.getMessageType() != value.getType().getModelType()) {
                        LOG.fine("Message filter type '" + filter.getMessageType().getName() + "' is not compatible with actual message type '" + value.getType().getModelType().getName() + "': " + filter.getClass().getName());
                        value = null;
                    } else {
                        try {
                            LOG.finest("Applying message filter: " + filter.getClass().getName());
                            value = filter.process(value);
                        } catch (Exception e) {
                            LOG.log(Level.SEVERE, "Message filter threw and exception during processing of message: " + filter.getClass().getName(), e);
                            value = null;
                        }
                    }
                    if (value == null) {
                        break;
                    }
                }
            }
            // Do basic value conversion
            Optional<ValueType> attributeValueType = attribute.getType().map(AttributeType::getValueType);
            if (value != null && attributeValueType.isPresent()) {
                if (attributeValueType.get() != value.getType()) {
                    LOG.fine("Converting value: " + value.getType() + " -> " + attributeValueType.get());
                    Optional<Value> convertedValue = Values.convert(value, attributeValueType.get());
                    if (!convertedValue.isPresent()) {
                        LOG.warning("Failed to convert value: " + value.getType() + " -> " + attributeValueType.get());
                    } else {
                        value = convertedValue.get();
                    }
                }
            }
            state = new AttributeState(state.getAttributeRef(), value);
        }
        AttributeEvent attributeEvent = new AttributeEvent(state, timestamp);
        LOG.fine("Sending on sensor queue: " + attributeEvent);
        producerTemplate.sendBodyAndHeader(SENSOR_QUEUE, attributeEvent, Protocol.SENSOR_QUEUE_SOURCE_PROTOCOL, getProtocolName());
        if (locationLinkedAttributes.contains(state.getAttributeRef())) {
            // Check value type is compatible
            Point location = state.getValue().map(value -> {
                if (value.getType() != ValueType.ARRAY) {
                    LOG.warning("Location linked attribute type is not an array");
                    return null;
                }
                Optional<List<NumberValue>> coordinates = Values.getArrayElements((ArrayValue) value, NumberValue.class, false, false);
                if (!coordinates.isPresent() || coordinates.get().size() != 2 || Math.abs(coordinates.get().get(0).getNumber()) > 180 || Math.abs(coordinates.get().get(1).getNumber()) > 90) {
                    LOG.warning("Location linked attribute value must contain longitude then latitude in a 2 value number array");
                    return null;
                }
                try {
                    return new GeometryFactory().createPoint(new Coordinate(coordinates.get().get(0).getNumber(), coordinates.get().get(1).getNumber()));
                } catch (Exception e) {
                    return null;
                }
            }).orElse(null);
            updateAssetLocation(state.getAttributeRef().getEntityId(), location);
        }
    });
}
Also used : java.util(java.util) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) ConnectionStatus(org.openremote.model.asset.agent.ConnectionStatus) ValidationFailure(org.openremote.model.ValidationFailure) MessageFilter(org.openremote.agent.protocol.filter.MessageFilter) Point(com.vividsolutions.jts.geom.Point) Level(java.util.logging.Level) AgentLink(org.openremote.model.asset.agent.AgentLink) GlobalLock.withLockReturning(org.openremote.container.concurrent.GlobalLock.withLockReturning) Container(org.openremote.container.Container) ProducerTemplate(org.apache.camel.ProducerTemplate) Coordinate(com.vividsolutions.jts.geom.Coordinate) MessageBrokerService(org.openremote.container.message.MessageBrokerService) Logger(java.util.logging.Logger) MessageBrokerSetupService(org.openremote.container.message.MessageBrokerSetupService) AssetMeta(org.openremote.model.asset.AssetMeta) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) org.openremote.model.value(org.openremote.model.value) RouteBuilder(org.apache.camel.builder.RouteBuilder) TimerService(org.openremote.container.timer.TimerService) MessageBrokerContext(org.openremote.container.message.MessageBrokerContext) org.openremote.model.attribute(org.openremote.model.attribute) ProtocolDescriptor(org.openremote.model.asset.agent.ProtocolDescriptor) GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) ValueHolder(org.openremote.model.ValueHolder) AssetAttribute(org.openremote.model.asset.AssetAttribute) GlobalLock(org.openremote.container.concurrent.GlobalLock) GlobalLock.withLock(org.openremote.container.concurrent.GlobalLock.withLock) GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) Point(com.vividsolutions.jts.geom.Point) Coordinate(com.vividsolutions.jts.geom.Coordinate) AssetAttribute(org.openremote.model.asset.AssetAttribute) MessageFilter(org.openremote.agent.protocol.filter.MessageFilter)

Example 2 with AssetAttribute

use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.

the class AbstractProtocol method processLinkedAttributeWrite.

protected final void processLinkedAttributeWrite(AttributeEvent event) {
    LOG.finest("Processing linked attribute write on " + getProtocolName() + ": " + event);
    withLock(getProtocolName() + "::processLinkedAttributeWrite", () -> {
        AssetAttribute attribute = linkedAttributes.get(event.getAttributeRef());
        if (attribute == null) {
            LOG.warning("Attribute doesn't exist on this protocol: " + event.getAttributeRef());
        } else {
            AssetAttribute protocolConfiguration = getLinkedProtocolConfiguration(attribute);
            processLinkedAttributeWrite(event, protocolConfiguration);
        }
    });
}
Also used : AssetAttribute(org.openremote.model.asset.AssetAttribute)

Example 3 with AssetAttribute

use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.

the class AbstractHttpServerProtocol method createDeployment.

protected ResteasyDeployment createDeployment(Application application, AssetAttribute protocolConfiguration) {
    ResteasyDeployment resteasyDeployment = new ResteasyDeployment();
    resteasyDeployment.setApplication(application);
    List<String> allowedOrigins;
    if (devMode) {
        allowedOrigins = Collections.singletonList("*");
    } else {
        Optional<MetaItem> allowedOriginsMeta = protocolConfiguration.getMetaItem(META_PROTOCOL_ALLOWED_ORIGINS);
        allowedOrigins = allowedOriginsMeta.flatMap(AbstractValueHolder::getValueAsString).map(Collections::singletonList).orElseGet(() -> allowedOriginsMeta.flatMap(AbstractValueHolder::getValueAsArray).flatMap(arrayValue -> Values.getArrayElements(arrayValue, StringValue.class, true, false, StringValue::getString)).orElse(null));
    }
    if (allowedOrigins != null) {
        String allowedMethods = protocolConfiguration.getMetaItem(META_PROTOCOL_ALLOWED_METHODS).flatMap(AbstractValueHolder::getValueAsString).orElse(DEFAULT_ALLOWED_METHODS);
        if (TextUtil.isNullOrEmpty(allowedMethods)) {
            throw new IllegalArgumentException("Allowed methods meta item must be a non empty string: " + META_PROTOCOL_ALLOWED_METHODS);
        }
        CorsFilter corsFilter = new CorsFilter();
        corsFilter.getAllowedOrigins().addAll(allowedOrigins);
        corsFilter.setAllowedMethods(allowedMethods);
        resteasyDeployment.getProviders().add(corsFilter);
    }
    return resteasyDeployment;
}
Also used : java.util(java.util) ServletException(javax.servlet.ServletException) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) AttributeRef(org.openremote.model.attribute.AttributeRef) ArrayValue(org.openremote.model.value.ArrayValue) Application(javax.ws.rs.core.Application) ServletInfo(io.undertow.servlet.api.ServletInfo) HttpMethod(javax.ws.rs.HttpMethod) Level(java.util.logging.Level) Servlets(io.undertow.servlet.Servlets) Container(org.openremote.container.Container) Lists(com.google.common.collect.Lists) ResteasyDeployment(org.jboss.resteasy.spi.ResteasyDeployment) TextUtil(org.openremote.model.util.TextUtil) PROTOCOL_NAMESPACE(org.openremote.model.Constants.PROTOCOL_NAMESPACE) AbstractValueHolder(org.openremote.model.AbstractValueHolder) StringValue(org.openremote.model.value.StringValue) org.openremote.container.web(org.openremote.container.web) Pair(org.openremote.model.util.Pair) ModelValueMessageBodyConverter(org.openremote.container.json.ModelValueMessageBodyConverter) Logger(java.util.logging.Logger) DeploymentManager(io.undertow.servlet.api.DeploymentManager) HttpServlet30Dispatcher(org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher) AbstractProtocol(org.openremote.agent.protocol.AbstractProtocol) HttpHandler(io.undertow.server.HttpHandler) MetaItem(org.openremote.model.attribute.MetaItem) IdentityService(org.openremote.container.security.IdentityService) CorsFilter(org.jboss.resteasy.plugins.interceptors.CorsFilter) RoleBasedSecurityFeature(org.jboss.resteasy.plugins.interceptors.RoleBasedSecurityFeature) JacksonConfig(org.openremote.container.json.JacksonConfig) DeploymentInfo(io.undertow.servlet.api.DeploymentInfo) Values(org.openremote.model.value.Values) Pattern(java.util.regex.Pattern) ValueHolder(org.openremote.model.ValueHolder) AssetAttribute(org.openremote.model.asset.AssetAttribute) CorsFilter(org.jboss.resteasy.plugins.interceptors.CorsFilter) ResteasyDeployment(org.jboss.resteasy.spi.ResteasyDeployment) MetaItem(org.openremote.model.attribute.MetaItem) AbstractValueHolder(org.openremote.model.AbstractValueHolder) StringValue(org.openremote.model.value.StringValue)

Example 4 with AssetAttribute

use of org.openremote.model.asset.AssetAttribute 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)));
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) ConnectionStatus(org.openremote.model.asset.agent.ConnectionStatus) HashMap(java.util.HashMap) ResteasyWebTarget(org.jboss.resteasy.client.jaxrs.ResteasyWebTarget) HttpMethod(javax.ws.rs.HttpMethod) Level(java.util.logging.Level) Container(org.openremote.container.Container) MediaType(javax.ws.rs.core.MediaType) Future(java.util.concurrent.Future) Map(java.util.Map) TextUtil(org.openremote.model.util.TextUtil) PROTOCOL_NAMESPACE(org.openremote.model.Constants.PROTOCOL_NAMESPACE) AbstractValueHolder(org.openremote.model.AbstractValueHolder) Pair(org.openremote.model.util.Pair) IOException(java.io.IOException) Invocation(javax.ws.rs.client.Invocation) Logger(java.util.logging.Logger) Entity(javax.ws.rs.client.Entity) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) AbstractProtocol(org.openremote.agent.protocol.AbstractProtocol) AssetMeta(org.openremote.model.asset.AssetMeta) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) List(java.util.List) org.openremote.model.value(org.openremote.model.value) Response(javax.ws.rs.core.Response) org.openremote.model.attribute(org.openremote.model.attribute) Optional(java.util.Optional) WebTarget(javax.ws.rs.client.WebTarget) AssetAttribute(org.openremote.model.asset.AssetAttribute) Protocol(org.openremote.agent.protocol.Protocol) GlobalLock.withLock(org.openremote.container.concurrent.GlobalLock.withLock) ResteasyWebTarget(org.jboss.resteasy.client.jaxrs.ResteasyWebTarget) List(java.util.List) ResteasyWebTarget(org.jboss.resteasy.client.jaxrs.ResteasyWebTarget) WebTarget(javax.ws.rs.client.WebTarget)

Example 5 with AssetAttribute

use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.

the class HttpClientProtocol method doLinkProtocolConfiguration.

@Override
protected void doLinkProtocolConfiguration(AssetAttribute protocolConfiguration) {
    final AttributeRef protocolRef = protocolConfiguration.getReferenceOrThrow();
    if (!protocolConfiguration.isEnabled()) {
        updateStatus(protocolRef, ConnectionStatus.DISABLED);
        return;
    }
    String baseUri = protocolConfiguration.getMetaItem(META_PROTOCOL_BASE_URI).flatMap(AbstractValueHolder::getValueAsString).orElseThrow(() -> new IllegalArgumentException("Missing or invalid require meta item: " + META_PROTOCOL_BASE_URI));
    /* We're going to fail hard and fast if optional meta items are incorrectly configured */
    Optional<OAuthGrant> oAuthGrant = getOAuthGrant(protocolConfiguration);
    Optional<StringValue> username = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_USERNAME, StringValue.class, false, true);
    Optional<StringValue> password = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PASSWORD, StringValue.class, false, true);
    boolean followRedirects = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_FOLLOW_REDIRECTS, BooleanValue.class, false, true).map(BooleanValue::getBoolean).orElse(false);
    List<Integer> failureCodes = protocolConfiguration.getMetaItem(META_FAILURE_CODES).flatMap(AbstractValueHolder::getValueAsArray).flatMap(arrayValue -> Values.getArrayElements(arrayValue, NumberValue.class, true, false, number -> Values.getIntegerCoerced(number).orElse(null))).orElse(null);
    Optional<MultivaluedMap<String, String>> headers = Values.getMetaItemValueOrThrow(protocolConfiguration, META_HEADERS, ObjectValue.class, false, true).flatMap(objectValue -> getMultivaluedMap(objectValue, true));
    Optional<MultivaluedMap<String, String>> queryParams = Values.getMetaItemValueOrThrow(protocolConfiguration, META_QUERY_PARAMETERS, ObjectValue.class, false, true).flatMap(objectValue -> getMultivaluedMap(objectValue, false));
    String pingPath = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PING_PATH, StringValue.class, false, true).map(StringValue::getString).orElse(null);
    if ((username.isPresent() && !password.isPresent()) || (!username.isPresent() && password.isPresent())) {
        throw new IllegalArgumentException("Both username and password must be set for basic authentication");
    }
    WebTargetBuilder webTargetBuilder = new WebTargetBuilder(baseUri);
    if (oAuthGrant.isPresent()) {
        LOG.info("Adding OAuth");
        webTargetBuilder.setOAuthAuthentication(oAuthGrant.get());
    } else {
        // noinspection ConstantConditions
        username.ifPresent(stringValue -> {
            LOG.info("Adding Basic Authentication");
            webTargetBuilder.setBasicAuthentication(stringValue.getString(), password.get().getString());
        });
    }
    headers.ifPresent(webTargetBuilder::setInjectHeaders);
    queryParams.ifPresent(webTargetBuilder::setInjectQueryParameters);
    webTargetBuilder.followRedirects(followRedirects);
    LOG.fine("Creating web target client '" + baseUri + "'");
    ResteasyWebTarget client = webTargetBuilder.build();
    clientMap.put(protocolRef, new Pair<>(client, failureCodes));
    updateStatus(protocolRef, ConnectionStatus.UNKNOWN);
    if (pingPath == null) {
        return;
    }
    String pingMethod = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PING_METHOD, StringValue.class, false, true).map(StringValue::getString).orElse(DEFAULT_HTTP_METHOD);
    Value pingBody = protocolConfiguration.getMetaItem(META_PROTOCOL_PING_BODY).flatMap(AbstractValueHolder::getValue).orElse(null);
    MultivaluedMap<String, String> pingQueryParams = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PING_QUERY_PARAMETERS, ObjectValue.class, false, true).flatMap(objectValue -> getMultivaluedMap(objectValue, false)).orElse(null);
    Integer pingPollingSeconds = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PING_SECONDS, NumberValue.class, false, true).map(polling -> Values.getIntegerCoerced(polling).map(seconds -> seconds < 1 ? null : seconds).orElseThrow(() -> new IllegalArgumentException("Ping polling seconds meta item must be an integer >= 1"))).orElse(DEFAULT_PING_SECONDS);
    String contentType = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_PING_CONTENT_TYPE, StringValue.class, false, true).map(StringValue::getString).orElse(null);
    HttpClientRequest pingRequest = buildClientRequest(client, pingPath, pingMethod, null, pingQueryParams, null, true, pingBody, contentType);
    LOG.info("Creating ping polling request '" + pingRequest + "'");
    requestMap.put(protocolRef, pingRequest);
    pollingMap.put(protocolRef, schedulePollingRequest(null, protocolRef, pingRequest, pingPollingSeconds));
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) ConnectionStatus(org.openremote.model.asset.agent.ConnectionStatus) HashMap(java.util.HashMap) ResteasyWebTarget(org.jboss.resteasy.client.jaxrs.ResteasyWebTarget) HttpMethod(javax.ws.rs.HttpMethod) Level(java.util.logging.Level) Container(org.openremote.container.Container) MediaType(javax.ws.rs.core.MediaType) Future(java.util.concurrent.Future) Map(java.util.Map) TextUtil(org.openremote.model.util.TextUtil) PROTOCOL_NAMESPACE(org.openremote.model.Constants.PROTOCOL_NAMESPACE) AbstractValueHolder(org.openremote.model.AbstractValueHolder) Pair(org.openremote.model.util.Pair) IOException(java.io.IOException) Invocation(javax.ws.rs.client.Invocation) Logger(java.util.logging.Logger) Entity(javax.ws.rs.client.Entity) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) AbstractProtocol(org.openremote.agent.protocol.AbstractProtocol) AssetMeta(org.openremote.model.asset.AssetMeta) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) List(java.util.List) org.openremote.model.value(org.openremote.model.value) Response(javax.ws.rs.core.Response) org.openremote.model.attribute(org.openremote.model.attribute) Optional(java.util.Optional) WebTarget(javax.ws.rs.client.WebTarget) AssetAttribute(org.openremote.model.asset.AssetAttribute) Protocol(org.openremote.agent.protocol.Protocol) GlobalLock.withLock(org.openremote.container.concurrent.GlobalLock.withLock) AbstractValueHolder(org.openremote.model.AbstractValueHolder) ResteasyWebTarget(org.jboss.resteasy.client.jaxrs.ResteasyWebTarget) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Aggregations

AssetAttribute (org.openremote.model.asset.AssetAttribute)26 Logger (java.util.logging.Logger)7 Level (java.util.logging.Level)6 Asset (org.openremote.model.asset.Asset)6 AssetMeta (org.openremote.model.asset.AssetMeta)6 Values (org.openremote.model.value.Values)6 List (java.util.List)5 Optional (java.util.Optional)5 Consumer (java.util.function.Consumer)5 Container (org.openremote.container.Container)5 ProtocolConfiguration (org.openremote.model.asset.agent.ProtocolConfiguration)5 Pair (org.openremote.model.util.Pair)5 java.util (java.util)4 Protocol (org.openremote.agent.protocol.Protocol)4 GlobalLock.withLock (org.openremote.container.concurrent.GlobalLock.withLock)4 TextUtil (org.openremote.model.util.TextUtil)4 TimeUnit (java.util.concurrent.TimeUnit)3 HttpMethod (javax.ws.rs.HttpMethod)3 AbstractProtocol (org.openremote.agent.protocol.AbstractProtocol)3 ServerAsset (org.openremote.manager.asset.ServerAsset)3