94 changed files with 390 additions and 1062 deletions
@ -1,123 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.system; |
|
||||
|
|
||||
import com.fasterxml.jackson.core.type.TypeReference; |
|
||||
import com.google.common.collect.ImmutableMap; |
|
||||
import org.junit.Before; |
|
||||
import org.junit.Test; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentials; |
|
||||
import org.thingsboard.server.controller.AbstractControllerTest; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
import static org.junit.Assert.assertEquals; |
|
||||
|
|
||||
public class BaseDeviceOfflineTest extends AbstractControllerTest { |
|
||||
|
|
||||
private Device deviceA; |
|
||||
private Device deviceB; |
|
||||
private DeviceCredentials credA; |
|
||||
private DeviceCredentials credB; |
|
||||
|
|
||||
@Before |
|
||||
public void before() throws Exception { |
|
||||
loginTenantAdmin(); |
|
||||
deviceA = createDevice("DevA", "VMS"); |
|
||||
credA = getCredentials(deviceA.getUuidId()); |
|
||||
deviceB = createDevice("DevB", "SOLAR"); |
|
||||
credB = getCredentials(deviceB.getUuidId()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void offlineDevicesCanBeFoundByLastConnectField() throws Exception { |
|
||||
makeDeviceContact(credA); |
|
||||
Thread.sleep(1000); |
|
||||
makeDeviceContact(credB); |
|
||||
Thread.sleep(100); |
|
||||
List<Device> devices = doGetTyped("/api/device/offline?contactType=CONNECT&threshold=700", new TypeReference<List<Device>>() { |
|
||||
}); |
|
||||
|
|
||||
assertEquals(devices.toString(),1, devices.size()); |
|
||||
assertEquals("DevA", devices.get(0).getName()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void offlineDevicesCanBeFoundByLastUpdateField() throws Exception { |
|
||||
makeDeviceUpdate(credA); |
|
||||
Thread.sleep(1000); |
|
||||
makeDeviceUpdate(credB); |
|
||||
makeDeviceContact(credA); |
|
||||
Thread.sleep(100); |
|
||||
List<Device> devices = doGetTyped("/api/device/offline?contactType=UPLOAD&threshold=700", new TypeReference<List<Device>>() { |
|
||||
}); |
|
||||
|
|
||||
assertEquals(devices.toString(),1, devices.size()); |
|
||||
assertEquals("DevA", devices.get(0).getName()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void onlineDevicesCanBeFoundByLastConnectField() throws Exception { |
|
||||
makeDeviceContact(credB); |
|
||||
Thread.sleep(1000); |
|
||||
makeDeviceContact(credA); |
|
||||
Thread.sleep(100); |
|
||||
List<Device> devices = doGetTyped("/api/device/online?contactType=CONNECT&threshold=700", new TypeReference<List<Device>>() { |
|
||||
}); |
|
||||
|
|
||||
assertEquals(devices.toString(),1, devices.size()); |
|
||||
assertEquals("DevA", devices.get(0).getName()); |
|
||||
} |
|
||||
|
|
||||
@Test |
|
||||
public void onlineDevicesCanBeFoundByLastUpdateField() throws Exception { |
|
||||
makeDeviceUpdate(credB); |
|
||||
Thread.sleep(1000); |
|
||||
makeDeviceUpdate(credA); |
|
||||
makeDeviceContact(credB); |
|
||||
Thread.sleep(100); |
|
||||
List<Device> devices = doGetTyped("/api/device/online?contactType=UPLOAD&threshold=700", new TypeReference<List<Device>>() { |
|
||||
}); |
|
||||
|
|
||||
assertEquals(devices.toString(),1, devices.size()); |
|
||||
assertEquals("DevA", devices.get(0).getName()); |
|
||||
} |
|
||||
|
|
||||
private Device createDevice(String name, String type) throws Exception { |
|
||||
Device device = new Device(); |
|
||||
device.setName(name); |
|
||||
device.setType(type); |
|
||||
long currentTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10); |
|
||||
device.setLastConnectTs(currentTime); |
|
||||
device.setLastUpdateTs(currentTime); |
|
||||
return doPost("/api/device", device, Device.class); |
|
||||
} |
|
||||
|
|
||||
private DeviceCredentials getCredentials(UUID deviceId) throws Exception { |
|
||||
return doGet("/api/device/" + deviceId.toString() + "/credentials", DeviceCredentials.class); |
|
||||
} |
|
||||
|
|
||||
private void makeDeviceUpdate(DeviceCredentials credentials) throws Exception { |
|
||||
doPost("/api/v1/" + credentials.getCredentialsId() + "/attributes", ImmutableMap.of("keyA", "valueA"), new String[]{}); |
|
||||
} |
|
||||
|
|
||||
private void makeDeviceContact(DeviceCredentials credentials) throws Exception { |
|
||||
doGet("/api/v1/" + credentials.getCredentialsId() + "/attributes?clientKeys=keyA,keyB,keyC"); |
|
||||
} |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.system.nosql; |
|
||||
|
|
||||
import org.thingsboard.server.dao.service.DaoNoSqlTest; |
|
||||
import org.thingsboard.server.system.BaseDeviceOfflineTest; |
|
||||
|
|
||||
@DaoNoSqlTest |
|
||||
public class DeviceOfflineNoSqlTest extends BaseDeviceOfflineTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.system.sql; |
|
||||
|
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
import org.thingsboard.server.system.BaseDeviceOfflineTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class DeviceOfflineSqlTest extends BaseDeviceOfflineTest { |
|
||||
} |
|
||||
@ -1,40 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.common.data.device; |
|
||||
|
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Data; |
|
||||
import lombok.ToString; |
|
||||
|
|
||||
@Data |
|
||||
@AllArgsConstructor |
|
||||
@ToString |
|
||||
public class DeviceStatusQuery { |
|
||||
|
|
||||
private Status status; |
|
||||
private ContactType contactType; |
|
||||
private long threshold; |
|
||||
|
|
||||
|
|
||||
public enum Status { |
|
||||
ONLINE, OFFLINE |
|
||||
} |
|
||||
|
|
||||
public enum ContactType { |
|
||||
CONNECT, UPLOAD |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.dao.device; |
|
||||
|
|
||||
import com.google.common.util.concurrent.ListenableFuture; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.device.DeviceStatusQuery; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
public interface DeviceOfflineService { |
|
||||
|
|
||||
void online(Device device, boolean isUpdate); |
|
||||
|
|
||||
void offline(Device device); |
|
||||
|
|
||||
ListenableFuture<List<Device>> findOfflineDevices(UUID tenantId, DeviceStatusQuery.ContactType contactType, long offlineThreshold); |
|
||||
|
|
||||
ListenableFuture<List<Device>> findOnlineDevices(UUID tenantId, DeviceStatusQuery.ContactType contactType, long offlineThreshold); |
|
||||
} |
|
||||
@ -1,62 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.server.dao.device; |
|
||||
|
|
||||
import com.google.common.util.concurrent.ListenableFuture; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.stereotype.Service; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.device.DeviceStatusQuery; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
import static org.thingsboard.server.common.data.device.DeviceStatusQuery.Status.OFFLINE; |
|
||||
import static org.thingsboard.server.common.data.device.DeviceStatusQuery.Status.ONLINE; |
|
||||
|
|
||||
@Service |
|
||||
public class DeviceOfflineServiceImpl implements DeviceOfflineService { |
|
||||
|
|
||||
@Autowired |
|
||||
private DeviceDao deviceDao; |
|
||||
|
|
||||
@Override |
|
||||
public void online(Device device, boolean isUpdate) { |
|
||||
long current = System.currentTimeMillis(); |
|
||||
device.setLastConnectTs(current); |
|
||||
if(isUpdate) { |
|
||||
device.setLastUpdateTs(current); |
|
||||
} |
|
||||
deviceDao.saveDeviceStatus(device); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void offline(Device device) { |
|
||||
online(device, false); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public ListenableFuture<List<Device>> findOfflineDevices(UUID tenantId, DeviceStatusQuery.ContactType contactType, long offlineThreshold) { |
|
||||
DeviceStatusQuery statusQuery = new DeviceStatusQuery(OFFLINE, contactType, offlineThreshold); |
|
||||
return deviceDao.findDevicesByTenantIdAndStatus(tenantId, statusQuery); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public ListenableFuture<List<Device>> findOnlineDevices(UUID tenantId, DeviceStatusQuery.ContactType contactType, long offlineThreshold) { |
|
||||
DeviceStatusQuery statusQuery = new DeviceStatusQuery(ONLINE, contactType, offlineThreshold); |
|
||||
return deviceDao.findDevicesByTenantIdAndStatus(tenantId, statusQuery); |
|
||||
} |
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2018 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.rule.engine.mail; |
|
||||
|
|
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
|
||||
import org.apache.velocity.Template; |
|
||||
import org.apache.velocity.VelocityContext; |
|
||||
import org.apache.velocity.runtime.RuntimeServices; |
|
||||
import org.apache.velocity.runtime.RuntimeSingleton; |
|
||||
import org.apache.velocity.runtime.parser.ParseException; |
|
||||
import org.apache.velocity.runtime.parser.node.SimpleNode; |
|
||||
import org.thingsboard.server.common.msg.TbMsg; |
|
||||
|
|
||||
import java.io.IOException; |
|
||||
import java.io.StringReader; |
|
||||
import java.io.StringWriter; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
import static org.thingsboard.server.common.msg.TbMsgDataType.JSON; |
|
||||
|
|
||||
public class RuleVelocityUtils { |
|
||||
|
|
||||
public static VelocityContext createContext(TbMsg msg) throws IOException { |
|
||||
VelocityContext context = new VelocityContext(); |
|
||||
context.put("originator", msg.getOriginator()); |
|
||||
context.put("type", msg.getType()); |
|
||||
context.put("metadata", msg.getMetaData().values()); |
|
||||
if (msg.getDataType() == JSON) { |
|
||||
Map map = new ObjectMapper().readValue(msg.getData(), Map.class); |
|
||||
context.put("msg", map); |
|
||||
} else { |
|
||||
context.put("msg", msg.getData()); |
|
||||
} |
|
||||
return context; |
|
||||
} |
|
||||
|
|
||||
public static String merge(Template template, VelocityContext context) { |
|
||||
StringWriter writer = new StringWriter(); |
|
||||
template.merge(context, writer); |
|
||||
return writer.toString(); |
|
||||
} |
|
||||
|
|
||||
public static Template create(String source, String templateName) throws ParseException { |
|
||||
RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices(); |
|
||||
StringReader reader = new StringReader(source); |
|
||||
SimpleNode node = runtimeServices.parse(reader, templateName); |
|
||||
Template template = new Template(); |
|
||||
template.setRuntimeServices(runtimeServices); |
|
||||
template.setData(node); |
|
||||
template.initDocument(); |
|
||||
return template; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue