Browse Source

Merge branch 'master' into feature/TB-74

pull/465/head
Andrew Shvayka 9 years ago
parent
commit
a075d9591d
  1. 1
      dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java
  2. 20
      dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java
  3. 44
      transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java
  4. 22
      transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java
  5. 39
      ui/src/app/home/home-links.controller.js
  6. 16
      ui/src/app/home/home-links.tpl.html

1
dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java

@ -22,6 +22,7 @@ import javax.annotation.PreDestroy;
import java.util.concurrent.Executors;
public abstract class JpaAbstractDaoListeningExecutorService {
protected ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
@PreDestroy

20
dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java

@ -17,9 +17,7 @@ package org.thingsboard.server.dao.sql.timeseries;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
@ -36,10 +34,12 @@ import org.thingsboard.server.dao.timeseries.TimeseriesDao;
import org.thingsboard.server.dao.util.SqlDao;
import javax.annotation.Nullable;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID;
@ -50,6 +50,8 @@ import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID;
@SqlDao
public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService implements TimeseriesDao {
private ListeningExecutorService insertService = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
@Autowired
private TsKvRepository tsKvRepository;
@ -232,7 +234,8 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp
entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
return service.submit(() -> {
log.trace("Saving entity: " + entity);
return insertService.submit(() -> {
tsKvRepository.save(entity);
return null;
});
@ -240,7 +243,7 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp
@Override
public ListenableFuture<Void> savePartition(EntityId entityId, long tsKvEntryTs, String key, long ttl) {
return service.submit(() -> null);
return insertService.submit(() -> null);
}
@Override
@ -254,10 +257,15 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp
latestEntity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
latestEntity.setLongValue(tsKvEntry.getLongValue().orElse(null));
latestEntity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
return service.submit(() -> {
return insertService.submit(() -> {
tsKvLatestRepository.save(latestEntity);
return null;
});
}
@PreDestroy
void onDestroy() {
insertService.shutdown();
}
}

44
transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java

@ -16,6 +16,7 @@
package org.thingsboard.server.transport.mqtt.session;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.netty.buffer.ByteBuf;
@ -24,6 +25,7 @@ import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.handler.codec.mqtt.*;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.msg.core.*;
import org.thingsboard.server.common.msg.kv.AttributesKVMsg;
@ -35,6 +37,7 @@ import org.thingsboard.server.transport.mqtt.MqttTopics;
import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
@ -83,7 +86,7 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
if (responseMsg.isSuccess()) {
MsgType requestMsgType = responseMsg.getRequestMsgType();
Integer requestId = responseMsg.getRequestId();
if (requestMsgType == MsgType.POST_ATTRIBUTES_REQUEST || requestMsgType == MsgType.POST_TELEMETRY_REQUEST) {
if (requestId >= 0 && requestMsgType == MsgType.POST_ATTRIBUTES_REQUEST || requestMsgType == MsgType.POST_TELEMETRY_REQUEST) {
return Optional.of(MqttTransportHandler.createMqttPubAckMsg(requestId));
}
}
@ -135,40 +138,43 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
if (responseData.isPresent()) {
AttributesKVMsg msg = responseData.get();
if (msg.getClientAttributes() != null) {
msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v));
addValues(result, msg.getClientAttributes());
}
if (msg.getSharedAttributes() != null) {
msg.getSharedAttributes().forEach(v -> addValueToJson(result, "value", v));
addValues(result, msg.getSharedAttributes());
}
}
return createMqttPublishMsg(topic, result);
}
private void addValues(JsonObject result, List<AttributeKvEntry> kvList) {
if (kvList.size() == 1) {
addValueToJson(result, "value", kvList.get(0));
} else {
JsonObject values;
if (result.has("values")) {
values = result.get("values").getAsJsonObject();
} else {
values = new JsonObject();
result.add("values", values);
}
kvList.forEach(value -> addValueToJson(values, value.getKey(), value));
}
}
private void addValueToJson(JsonObject json, String name, KvEntry entry) {
switch (entry.getDataType()) {
case BOOLEAN:
Optional<Boolean> booleanValue = entry.getBooleanValue();
if (booleanValue.isPresent()) {
json.addProperty(name, booleanValue.get());
}
entry.getBooleanValue().ifPresent(aBoolean -> json.addProperty(name, aBoolean));
break;
case STRING:
Optional<String> stringValue = entry.getStrValue();
if (stringValue.isPresent()) {
json.addProperty(name, stringValue.get());
}
entry.getStrValue().ifPresent(aString -> json.addProperty(name, aString));
break;
case DOUBLE:
Optional<Double> doubleValue = entry.getDoubleValue();
if (doubleValue.isPresent()) {
json.addProperty(name, doubleValue.get());
}
entry.getDoubleValue().ifPresent(aDouble -> json.addProperty(name, aDouble));
break;
case LONG:
Optional<Long> longValue = entry.getLongValue();
if (longValue.isPresent()) {
json.addProperty(name, longValue.get());
}
entry.getLongValue().ifPresent(aLong -> json.addProperty(name, aLong));
break;
}
}

22
transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java

@ -41,10 +41,7 @@ import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import static org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor.validateJsonPayload;
@ -193,13 +190,22 @@ public class GatewaySessionCtx {
int requestId = jsonObj.get("id").getAsInt();
String deviceName = jsonObj.get(DEVICE_PROPERTY).getAsString();
boolean clientScope = jsonObj.get("client").getAsBoolean();
String key = jsonObj.get("key").getAsString();
Set<String> keys;
if (jsonObj.has("key")) {
keys = Collections.singleton(jsonObj.get("key").getAsString());
} else {
JsonArray keysArray = jsonObj.get("keys").getAsJsonArray();
keys = new HashSet<>();
for (JsonElement keyObj : keysArray) {
keys.add(keyObj.getAsString());
}
}
BasicGetAttributesRequest request;
if (clientScope) {
request = new BasicGetAttributesRequest(requestId, Collections.singleton(key), null);
request = new BasicGetAttributesRequest(requestId, keys, null);
} else {
request = new BasicGetAttributesRequest(requestId, null, Collections.singleton(key));
request = new BasicGetAttributesRequest(requestId, null, keys);
}
GatewayDeviceSessionCtx deviceSessionCtx = devices.get(deviceName);
processor.process(new BasicToDeviceActorSessionMsg(deviceSessionCtx.getDevice(),
@ -251,7 +257,7 @@ public class GatewaySessionCtx {
}
private void ack(MqttPublishMessage msg) {
if(msg.variableHeader().messageId() > 0) {
if (msg.variableHeader().messageId() > 0) {
writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msg.variableHeader().messageId()));
}
}

39
ui/src/app/home/home-links.controller.js

@ -17,7 +17,42 @@
import './home-links.scss';
/*@ngInject*/
export default function HomeLinksController($scope, menu) {
export default function HomeLinksController($scope, $mdMedia, menu) {
var vm = this;
vm.model = menu.getHomeSections();
vm.sectionColspan = sectionColspan;
$scope.$watch(function() { return $mdMedia('lg'); }, function() {
updateColumnCount();
});
$scope.$watch(function() { return $mdMedia('gt-lg'); }, function() {
updateColumnCount();
});
updateColumnCount();
menu.getHomeSections().then((homeSections) => {
vm.model = homeSections;
});
function updateColumnCount() {
vm.cols = 2;
if ($mdMedia('lg')) {
vm.cols = 3;
}
if ($mdMedia('gt-lg')) {
vm.cols = 4;
}
}
function sectionColspan(section) {
var colspan = vm.cols;
if (section && section.places && section.places.length <= colspan) {
colspan = section.places.length;
}
return colspan;
}
}

16
ui/src/app/home/home-links.tpl.html

@ -15,8 +15,8 @@
limitations under the License.
-->
<md-grid-list class="tb-home-links" md-cols="2" md-cols-lg="3" md-cols-gt-lg="4" md-row-height="280px">
<md-grid-tile md-colspan="2" md-colspan-gt-sm="{{section.places.length}}" ng-repeat="section in vm.model">
<md-grid-list class="tb-home-links" md-cols="{{vm.cols}}" md-row-height="280px">
<md-grid-tile md-colspan="2" md-colspan-gt-sm="{{vm.sectionColspan(section)}}" ng-repeat="section in vm.model">
<md-card style='width: 100%;'>
<md-card-title>
<md-card-title-text>
@ -25,12 +25,12 @@
</md-card-title>
<md-card-content>
<md-grid-list md-row-height="170px" md-cols="{{section.places.length}}" md-cols-gt-md="{{section.places.length}}">
<md-grid-tile class="card-tile" ng-repeat="place in section.places">
<md-button class="tb-card-button md-raised md-primary" layout="column" ui-sref="{{place.state}}">
<md-icon class="material-icons tb-md-96" aria-label="{{place.icon}}">{{place.icon}}</md-icon>
<span translate>{{place.name}}</span>
</md-button>
</md-grid-tile>
<md-grid-tile class="card-tile" ng-repeat="place in section.places">
<md-button class="tb-card-button md-raised md-primary" layout="column" ui-sref="{{place.state}}">
<md-icon class="material-icons tb-md-96" aria-label="{{place.icon}}">{{place.icon}}</md-icon>
<span translate>{{place.name}}</span>
</md-button>
</md-grid-tile>
</md-grid-list>
</md-card-content>
</md-card>

Loading…
Cancel
Save