Commit c4cd601dcbbbec90a83dfe8508766f7dd94e5d53
1 parent
7d72a467
Improvements to Tenant rules and plugins startup sequence
Showing
18 changed files
with
114 additions
and
97 deletions
@@ -136,6 +136,9 @@ public class ActorSystemContext { | @@ -136,6 +136,9 @@ public class ActorSystemContext { | ||
136 | @Value("${actors.statistics.persist_frequency}") | 136 | @Value("${actors.statistics.persist_frequency}") |
137 | @Getter private long statisticsPersistFrequency; | 137 | @Getter private long statisticsPersistFrequency; |
138 | 138 | ||
139 | + @Value("${actors.tenant.create_components_on_init}") | ||
140 | + @Getter private boolean tenantComponentsInitEnabled; | ||
141 | + | ||
139 | @Getter @Setter private ActorSystem actorSystem; | 142 | @Getter @Setter private ActorSystem actorSystem; |
140 | 143 | ||
141 | @Getter @Setter private ActorRef appActor; | 144 | @Getter @Setter private ActorRef appActor; |
@@ -174,7 +174,7 @@ public class AppActor extends ContextAwareActor { | @@ -174,7 +174,7 @@ public class AppActor extends ContextAwareActor { | ||
174 | TenantId tenantId = toDeviceActorMsg.getTenantId(); | 174 | TenantId tenantId = toDeviceActorMsg.getTenantId(); |
175 | ActorRef tenantActor = getOrCreateTenantActor(tenantId); | 175 | ActorRef tenantActor = getOrCreateTenantActor(tenantId); |
176 | if (toDeviceActorMsg.getPayload().getMsgType().requiresRulesProcessing()) { | 176 | if (toDeviceActorMsg.getPayload().getMsgType().requiresRulesProcessing()) { |
177 | - tenantActor.tell(new RuleChainDeviceMsg(toDeviceActorMsg, ruleManager.getRuleChain()), context().self()); | 177 | + tenantActor.tell(new RuleChainDeviceMsg(toDeviceActorMsg, ruleManager.getRuleChain(this.context())), context().self()); |
178 | } else { | 178 | } else { |
179 | tenantActor.tell(toDeviceActorMsg, context().self()); | 179 | tenantActor.tell(toDeviceActorMsg, context().self()); |
180 | } | 180 | } |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.shared.plugin; | 16 | package org.thingsboard.server.actors.shared.plugin; |
17 | 17 | ||
18 | +import akka.actor.ActorContext; | ||
18 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
19 | import org.thingsboard.server.actors.service.DefaultActorService; | 20 | import org.thingsboard.server.actors.service.DefaultActorService; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -30,6 +31,12 @@ public class TenantPluginManager extends PluginManager { | @@ -30,6 +31,12 @@ public class TenantPluginManager extends PluginManager { | ||
30 | this.tenantId = tenantId; | 31 | this.tenantId = tenantId; |
31 | } | 32 | } |
32 | 33 | ||
34 | + public void init(ActorContext context) { | ||
35 | + if (systemContext.isTenantComponentsInitEnabled()) { | ||
36 | + super.init(context); | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
33 | @Override | 40 | @Override |
34 | FetchFunction<PluginMetaData> getFetchPluginsFunction() { | 41 | FetchFunction<PluginMetaData> getFetchPluginsFunction() { |
35 | return link -> pluginService.findTenantPlugins(tenantId, link); | 42 | return link -> pluginService.findTenantPlugins(tenantId, link); |
@@ -25,7 +25,6 @@ import org.thingsboard.server.actors.rule.RuleActorChain; | @@ -25,7 +25,6 @@ import org.thingsboard.server.actors.rule.RuleActorChain; | ||
25 | import org.thingsboard.server.actors.rule.RuleActorMetaData; | 25 | import org.thingsboard.server.actors.rule.RuleActorMetaData; |
26 | import org.thingsboard.server.actors.rule.SimpleRuleActorChain; | 26 | import org.thingsboard.server.actors.rule.SimpleRuleActorChain; |
27 | import org.thingsboard.server.actors.service.ContextAwareActor; | 27 | import org.thingsboard.server.actors.service.ContextAwareActor; |
28 | -import org.thingsboard.server.actors.service.DefaultActorService; | ||
29 | import org.thingsboard.server.common.data.id.RuleId; | 28 | import org.thingsboard.server.common.data.id.RuleId; |
30 | import org.thingsboard.server.common.data.id.TenantId; | 29 | import org.thingsboard.server.common.data.id.TenantId; |
31 | import org.thingsboard.server.common.data.page.PageDataIterable; | 30 | import org.thingsboard.server.common.data.page.PageDataIterable; |
@@ -72,6 +71,9 @@ public abstract class RuleManager { | @@ -72,6 +71,9 @@ public abstract class RuleManager { | ||
72 | } | 71 | } |
73 | 72 | ||
74 | public Optional<ActorRef> update(ActorContext context, RuleId ruleId, ComponentLifecycleEvent event) { | 73 | public Optional<ActorRef> update(ActorContext context, RuleId ruleId, ComponentLifecycleEvent event) { |
74 | + if (ruleMap == null) { | ||
75 | + init(context); | ||
76 | + } | ||
75 | RuleMetaData rule; | 77 | RuleMetaData rule; |
76 | if (event != ComponentLifecycleEvent.DELETED) { | 78 | if (event != ComponentLifecycleEvent.DELETED) { |
77 | rule = systemContext.getRuleService().findRuleById(ruleId); | 79 | rule = systemContext.getRuleService().findRuleById(ruleId); |
@@ -111,11 +113,13 @@ public abstract class RuleManager { | @@ -111,11 +113,13 @@ public abstract class RuleManager { | ||
111 | .withDispatcher(getDispatcherName()), rId.toString())); | 113 | .withDispatcher(getDispatcherName()), rId.toString())); |
112 | } | 114 | } |
113 | 115 | ||
114 | - public RuleActorChain getRuleChain() { | 116 | + public RuleActorChain getRuleChain(ActorContext context) { |
117 | + if (ruleMap == null) { | ||
118 | + init(context); | ||
119 | + } | ||
115 | return ruleChain; | 120 | return ruleChain; |
116 | } | 121 | } |
117 | 122 | ||
118 | - | ||
119 | private void refreshRuleChain() { | 123 | private void refreshRuleChain() { |
120 | Set<RuleActorMetaData> activeRuleSet = new HashSet<>(); | 124 | Set<RuleActorMetaData> activeRuleSet = new HashSet<>(); |
121 | for (Map.Entry<RuleMetaData, RuleActorMetaData> rule : ruleMap.entrySet()) { | 125 | for (Map.Entry<RuleMetaData, RuleActorMetaData> rule : ruleMap.entrySet()) { |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.actors.shared.rule; | 16 | package org.thingsboard.server.actors.shared.rule; |
17 | 17 | ||
18 | +import akka.actor.ActorContext; | ||
18 | import org.thingsboard.server.actors.ActorSystemContext; | 19 | import org.thingsboard.server.actors.ActorSystemContext; |
19 | import org.thingsboard.server.actors.service.DefaultActorService; | 20 | import org.thingsboard.server.actors.service.DefaultActorService; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -27,6 +28,12 @@ public class TenantRuleManager extends RuleManager { | @@ -27,6 +28,12 @@ public class TenantRuleManager extends RuleManager { | ||
27 | super(systemContext, tenantId); | 28 | super(systemContext, tenantId); |
28 | } | 29 | } |
29 | 30 | ||
31 | + public void init(ActorContext context) { | ||
32 | + if (systemContext.isTenantComponentsInitEnabled()) { | ||
33 | + super.init(context); | ||
34 | + } | ||
35 | + } | ||
36 | + | ||
30 | @Override | 37 | @Override |
31 | FetchFunction<RuleMetaData> getFetchRulesFunction() { | 38 | FetchFunction<RuleMetaData> getFetchRulesFunction() { |
32 | return link -> ruleService.findTenantRules(tenantId, link); | 39 | return link -> ruleService.findTenantRules(tenantId, link); |
@@ -151,18 +151,13 @@ public class TenantActor extends ContextAwareActor { | @@ -151,18 +151,13 @@ public class TenantActor extends ContextAwareActor { | ||
151 | private void process(RuleChainDeviceMsg msg) { | 151 | private void process(RuleChainDeviceMsg msg) { |
152 | ToDeviceActorMsg toDeviceActorMsg = msg.getToDeviceActorMsg(); | 152 | ToDeviceActorMsg toDeviceActorMsg = msg.getToDeviceActorMsg(); |
153 | ActorRef deviceActor = getOrCreateDeviceActor(toDeviceActorMsg.getDeviceId()); | 153 | ActorRef deviceActor = getOrCreateDeviceActor(toDeviceActorMsg.getDeviceId()); |
154 | - RuleActorChain chain = new ComplexRuleActorChain(msg.getRuleChain(), ruleManager.getRuleChain()); | 154 | + RuleActorChain chain = new ComplexRuleActorChain(msg.getRuleChain(), ruleManager.getRuleChain(this.context())); |
155 | deviceActor.tell(new RuleChainDeviceMsg(toDeviceActorMsg, chain), context().self()); | 155 | deviceActor.tell(new RuleChainDeviceMsg(toDeviceActorMsg, chain), context().self()); |
156 | } | 156 | } |
157 | 157 | ||
158 | private ActorRef getOrCreateDeviceActor(DeviceId deviceId) { | 158 | private ActorRef getOrCreateDeviceActor(DeviceId deviceId) { |
159 | - ActorRef deviceActor = deviceActors.get(deviceId); | ||
160 | - if (deviceActor == null) { | ||
161 | - deviceActor = context().actorOf(Props.create(new DeviceActor.ActorCreator(systemContext, tenantId, deviceId)) | ||
162 | - .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), deviceId.toString()); | ||
163 | - deviceActors.put(deviceId, deviceActor); | ||
164 | - } | ||
165 | - return deviceActor; | 159 | + return deviceActors.computeIfAbsent(deviceId, k -> context().actorOf(Props.create(new DeviceActor.ActorCreator(systemContext, tenantId, deviceId)) |
160 | + .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), deviceId.toString())); | ||
166 | } | 161 | } |
167 | 162 | ||
168 | public static class ActorCreator extends ContextBasedCreator<TenantActor> { | 163 | public static class ActorCreator extends ContextBasedCreator<TenantActor> { |
@@ -15,30 +15,16 @@ | @@ -15,30 +15,16 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.controller; | 16 | package org.thingsboard.server.controller; |
17 | 17 | ||
18 | -import com.google.common.util.concurrent.ListenableFuture; | ||
19 | import org.apache.commons.lang3.StringUtils; | 18 | import org.apache.commons.lang3.StringUtils; |
20 | import org.springframework.http.HttpStatus; | 19 | import org.springframework.http.HttpStatus; |
21 | import org.springframework.security.access.prepost.PreAuthorize; | 20 | import org.springframework.security.access.prepost.PreAuthorize; |
22 | import org.springframework.web.bind.annotation.*; | 21 | import org.springframework.web.bind.annotation.*; |
23 | -import org.thingsboard.server.common.data.Customer; | ||
24 | -import org.thingsboard.server.common.data.Event; | ||
25 | import org.thingsboard.server.common.data.alarm.*; | 22 | import org.thingsboard.server.common.data.alarm.*; |
26 | -import org.thingsboard.server.common.data.asset.Asset; | ||
27 | import org.thingsboard.server.common.data.id.*; | 23 | import org.thingsboard.server.common.data.id.*; |
28 | -import org.thingsboard.server.common.data.page.TextPageData; | ||
29 | -import org.thingsboard.server.common.data.page.TextPageLink; | ||
30 | import org.thingsboard.server.common.data.page.TimePageData; | 24 | import org.thingsboard.server.common.data.page.TimePageData; |
31 | import org.thingsboard.server.common.data.page.TimePageLink; | 25 | import org.thingsboard.server.common.data.page.TimePageLink; |
32 | -import org.thingsboard.server.dao.asset.AssetSearchQuery; | ||
33 | -import org.thingsboard.server.dao.exception.IncorrectParameterException; | ||
34 | -import org.thingsboard.server.dao.model.ModelConstants; | ||
35 | import org.thingsboard.server.exception.ThingsboardErrorCode; | 26 | import org.thingsboard.server.exception.ThingsboardErrorCode; |
36 | import org.thingsboard.server.exception.ThingsboardException; | 27 | import org.thingsboard.server.exception.ThingsboardException; |
37 | -import org.thingsboard.server.service.security.model.SecurityUser; | ||
38 | - | ||
39 | -import java.util.ArrayList; | ||
40 | -import java.util.List; | ||
41 | -import java.util.stream.Collectors; | ||
42 | 28 | ||
43 | @RestController | 29 | @RestController |
44 | @RequestMapping("/api") | 30 | @RequestMapping("/api") |
@@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.CustomerId; | @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.CustomerId; | ||
27 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
28 | import org.thingsboard.server.common.data.page.TextPageData; | 28 | import org.thingsboard.server.common.data.page.TextPageData; |
29 | import org.thingsboard.server.common.data.page.TextPageLink; | 29 | import org.thingsboard.server.common.data.page.TextPageLink; |
30 | -import org.thingsboard.server.dao.asset.AssetSearchQuery; | 30 | +import org.thingsboard.server.common.data.asset.AssetSearchQuery; |
31 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 31 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
32 | import org.thingsboard.server.dao.model.ModelConstants; | 32 | import org.thingsboard.server.dao.model.ModelConstants; |
33 | import org.thingsboard.server.exception.ThingsboardException; | 33 | import org.thingsboard.server.exception.ThingsboardException; |
@@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
28 | import org.thingsboard.server.common.data.page.TextPageData; | 28 | import org.thingsboard.server.common.data.page.TextPageData; |
29 | import org.thingsboard.server.common.data.page.TextPageLink; | 29 | import org.thingsboard.server.common.data.page.TextPageLink; |
30 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 30 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
31 | -import org.thingsboard.server.dao.device.DeviceSearchQuery; | 31 | +import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
32 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 32 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
33 | import org.thingsboard.server.dao.model.ModelConstants; | 33 | import org.thingsboard.server.dao.model.ModelConstants; |
34 | import org.thingsboard.server.exception.ThingsboardException; | 34 | import org.thingsboard.server.exception.ThingsboardException; |
@@ -159,6 +159,8 @@ cassandra: | @@ -159,6 +159,8 @@ cassandra: | ||
159 | 159 | ||
160 | # Actor system parameters | 160 | # Actor system parameters |
161 | actors: | 161 | actors: |
162 | + tenant: | ||
163 | + create_components_on_init: true | ||
162 | session: | 164 | session: |
163 | sync: | 165 | sync: |
164 | # Default timeout for processing request using synchronous session (HTTP, CoAP) in milliseconds | 166 | # Default timeout for processing request using synchronous session (HTTP, CoAP) in milliseconds |
@@ -97,28 +97,28 @@ public abstract class AbstractControllerTest { | @@ -97,28 +97,28 @@ public abstract class AbstractControllerTest { | ||
97 | 97 | ||
98 | protected static final String SYS_ADMIN_EMAIL = "sysadmin@thingsboard.org"; | 98 | protected static final String SYS_ADMIN_EMAIL = "sysadmin@thingsboard.org"; |
99 | private static final String SYS_ADMIN_PASSWORD = "sysadmin"; | 99 | private static final String SYS_ADMIN_PASSWORD = "sysadmin"; |
100 | - | 100 | + |
101 | protected static final String TENANT_ADMIN_EMAIL = "testtenant@thingsboard.org"; | 101 | protected static final String TENANT_ADMIN_EMAIL = "testtenant@thingsboard.org"; |
102 | private static final String TENANT_ADMIN_PASSWORD = "tenant"; | 102 | private static final String TENANT_ADMIN_PASSWORD = "tenant"; |
103 | 103 | ||
104 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; | 104 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; |
105 | private static final String CUSTOMER_USER_PASSWORD = "customer"; | 105 | private static final String CUSTOMER_USER_PASSWORD = "customer"; |
106 | - | 106 | + |
107 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), | 107 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), |
108 | MediaType.APPLICATION_JSON.getSubtype(), | 108 | MediaType.APPLICATION_JSON.getSubtype(), |
109 | Charset.forName("utf8")); | 109 | Charset.forName("utf8")); |
110 | 110 | ||
111 | protected MockMvc mockMvc; | 111 | protected MockMvc mockMvc; |
112 | - | 112 | + |
113 | protected String token; | 113 | protected String token; |
114 | protected String refreshToken; | 114 | protected String refreshToken; |
115 | protected String username; | 115 | protected String username; |
116 | 116 | ||
117 | private TenantId tenantId; | 117 | private TenantId tenantId; |
118 | - | 118 | + |
119 | @SuppressWarnings("rawtypes") | 119 | @SuppressWarnings("rawtypes") |
120 | private HttpMessageConverter mappingJackson2HttpMessageConverter; | 120 | private HttpMessageConverter mappingJackson2HttpMessageConverter; |
121 | - | 121 | + |
122 | @Autowired | 122 | @Autowired |
123 | private WebApplicationContext webApplicationContext; | 123 | private WebApplicationContext webApplicationContext; |
124 | 124 | ||
@@ -132,7 +132,7 @@ public abstract class AbstractControllerTest { | @@ -132,7 +132,7 @@ public abstract class AbstractControllerTest { | ||
132 | log.info("Finished test: {}", description.getMethodName()); | 132 | log.info("Finished test: {}", description.getMethodName()); |
133 | } | 133 | } |
134 | }; | 134 | }; |
135 | - | 135 | + |
136 | @Autowired | 136 | @Autowired |
137 | void setConverters(HttpMessageConverter<?>[] converters) { | 137 | void setConverters(HttpMessageConverter<?>[] converters) { |
138 | 138 | ||
@@ -144,7 +144,7 @@ public abstract class AbstractControllerTest { | @@ -144,7 +144,7 @@ public abstract class AbstractControllerTest { | ||
144 | Assert.assertNotNull("the JSON message converter must not be null", | 144 | Assert.assertNotNull("the JSON message converter must not be null", |
145 | this.mappingJackson2HttpMessageConverter); | 145 | this.mappingJackson2HttpMessageConverter); |
146 | } | 146 | } |
147 | - | 147 | + |
148 | @Before | 148 | @Before |
149 | public void setup() throws Exception { | 149 | public void setup() throws Exception { |
150 | log.info("Executing setup"); | 150 | log.info("Executing setup"); |
@@ -188,7 +188,7 @@ public abstract class AbstractControllerTest { | @@ -188,7 +188,7 @@ public abstract class AbstractControllerTest { | ||
188 | public void teardown() throws Exception { | 188 | public void teardown() throws Exception { |
189 | log.info("Executing teardown"); | 189 | log.info("Executing teardown"); |
190 | loginSysAdmin(); | 190 | loginSysAdmin(); |
191 | - doDelete("/api/tenant/"+tenantId.getId().toString()) | 191 | + doDelete("/api/tenant/" + tenantId.getId().toString()) |
192 | .andExpect(status().isOk()); | 192 | .andExpect(status().isOk()); |
193 | log.info("Executed teardown"); | 193 | log.info("Executed teardown"); |
194 | } | 194 | } |
@@ -196,7 +196,7 @@ public abstract class AbstractControllerTest { | @@ -196,7 +196,7 @@ public abstract class AbstractControllerTest { | ||
196 | protected void loginSysAdmin() throws Exception { | 196 | protected void loginSysAdmin() throws Exception { |
197 | login(SYS_ADMIN_EMAIL, SYS_ADMIN_PASSWORD); | 197 | login(SYS_ADMIN_EMAIL, SYS_ADMIN_PASSWORD); |
198 | } | 198 | } |
199 | - | 199 | + |
200 | protected void loginTenantAdmin() throws Exception { | 200 | protected void loginTenantAdmin() throws Exception { |
201 | login(TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD); | 201 | login(TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD); |
202 | } | 202 | } |
@@ -204,13 +204,13 @@ public abstract class AbstractControllerTest { | @@ -204,13 +204,13 @@ public abstract class AbstractControllerTest { | ||
204 | protected void loginCustomerUser() throws Exception { | 204 | protected void loginCustomerUser() throws Exception { |
205 | login(CUSTOMER_USER_EMAIL, CUSTOMER_USER_PASSWORD); | 205 | login(CUSTOMER_USER_EMAIL, CUSTOMER_USER_PASSWORD); |
206 | } | 206 | } |
207 | - | 207 | + |
208 | protected User createUserAndLogin(User user, String password) throws Exception { | 208 | protected User createUserAndLogin(User user, String password) throws Exception { |
209 | User savedUser = doPost("/api/user", user, User.class); | 209 | User savedUser = doPost("/api/user", user, User.class); |
210 | logout(); | 210 | logout(); |
211 | doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken) | 211 | doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken) |
212 | - .andExpect(status().isSeeOther()) | ||
213 | - .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken)); | 212 | + .andExpect(status().isSeeOther()) |
213 | + .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken)); | ||
214 | JsonNode tokenInfo = readResponse(doPost("/api/noauth/activate", "activateToken", TestMailService.currentActivateToken, "password", password).andExpect(status().isOk()), JsonNode.class); | 214 | JsonNode tokenInfo = readResponse(doPost("/api/noauth/activate", "activateToken", TestMailService.currentActivateToken, "password", password).andExpect(status().isOk()), JsonNode.class); |
215 | validateAndSetJwtToken(tokenInfo, user.getEmail()); | 215 | validateAndSetJwtToken(tokenInfo, user.getEmail()); |
216 | return savedUser; | 216 | return savedUser; |
@@ -247,14 +247,14 @@ public abstract class AbstractControllerTest { | @@ -247,14 +247,14 @@ public abstract class AbstractControllerTest { | ||
247 | Assert.assertNotNull(token); | 247 | Assert.assertNotNull(token); |
248 | Assert.assertFalse(token.isEmpty()); | 248 | Assert.assertFalse(token.isEmpty()); |
249 | int i = token.lastIndexOf('.'); | 249 | int i = token.lastIndexOf('.'); |
250 | - Assert.assertTrue(i>0); | ||
251 | - String withoutSignature = token.substring(0, i+1); | ||
252 | - Jwt<Header,Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature); | 250 | + Assert.assertTrue(i > 0); |
251 | + String withoutSignature = token.substring(0, i + 1); | ||
252 | + Jwt<Header, Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature); | ||
253 | Claims claims = jwsClaims.getBody(); | 253 | Claims claims = jwsClaims.getBody(); |
254 | String subject = claims.getSubject(); | 254 | String subject = claims.getSubject(); |
255 | Assert.assertEquals(username, subject); | 255 | Assert.assertEquals(username, subject); |
256 | } | 256 | } |
257 | - | 257 | + |
258 | protected void logout() throws Exception { | 258 | protected void logout() throws Exception { |
259 | this.token = null; | 259 | this.token = null; |
260 | this.refreshToken = null; | 260 | this.refreshToken = null; |
@@ -266,24 +266,24 @@ public abstract class AbstractControllerTest { | @@ -266,24 +266,24 @@ public abstract class AbstractControllerTest { | ||
266 | request.header(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM, "Bearer " + this.token); | 266 | request.header(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM, "Bearer " + this.token); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | - | 269 | + |
270 | protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { | 270 | protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { |
271 | MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); | 271 | MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); |
272 | setJwtToken(getRequest); | 272 | setJwtToken(getRequest); |
273 | return mockMvc.perform(getRequest); | 273 | return mockMvc.perform(getRequest); |
274 | } | 274 | } |
275 | - | 275 | + |
276 | protected <T> T doGet(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { | 276 | protected <T> T doGet(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { |
277 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); | 277 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); |
278 | } | 278 | } |
279 | - | 279 | + |
280 | protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception { | 280 | protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception { |
281 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); | 281 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); |
282 | } | 282 | } |
283 | - | 283 | + |
284 | protected <T> T doGetTypedWithPageLink(String urlTemplate, TypeReference<T> responseType, | 284 | protected <T> T doGetTypedWithPageLink(String urlTemplate, TypeReference<T> responseType, |
285 | - TextPageLink pageLink, | ||
286 | - Object... urlVariables) throws Exception { | 285 | + TextPageLink pageLink, |
286 | + Object... urlVariables) throws Exception { | ||
287 | List<Object> pageLinkVariables = new ArrayList<>(); | 287 | List<Object> pageLinkVariables = new ArrayList<>(); |
288 | urlTemplate += "limit={limit}"; | 288 | urlTemplate += "limit={limit}"; |
289 | pageLinkVariables.add(pageLink.getLimit()); | 289 | pageLinkVariables.add(pageLink.getLimit()); |
@@ -299,18 +299,18 @@ public abstract class AbstractControllerTest { | @@ -299,18 +299,18 @@ public abstract class AbstractControllerTest { | ||
299 | urlTemplate += "&textOffset={textOffset}"; | 299 | urlTemplate += "&textOffset={textOffset}"; |
300 | pageLinkVariables.add(pageLink.getTextOffset()); | 300 | pageLinkVariables.add(pageLink.getTextOffset()); |
301 | } | 301 | } |
302 | - | ||
303 | - Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()]; | 302 | + |
303 | + Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()]; | ||
304 | System.arraycopy(urlVariables, 0, vars, 0, urlVariables.length); | 304 | System.arraycopy(urlVariables, 0, vars, 0, urlVariables.length); |
305 | System.arraycopy(pageLinkVariables.toArray(), 0, vars, urlVariables.length, pageLinkVariables.size()); | 305 | System.arraycopy(pageLinkVariables.toArray(), 0, vars, urlVariables.length, pageLinkVariables.size()); |
306 | - | 306 | + |
307 | return readResponse(doGet(urlTemplate, vars).andExpect(status().isOk()), responseType); | 307 | return readResponse(doGet(urlTemplate, vars).andExpect(status().isOk()), responseType); |
308 | } | 308 | } |
309 | - | 309 | + |
310 | protected <T> T doPost(String urlTemplate, Class<T> responseClass, String... params) throws Exception { | 310 | protected <T> T doPost(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
311 | return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); | 311 | return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); |
312 | } | 312 | } |
313 | - | 313 | + |
314 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { | 314 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { |
315 | return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); | 315 | return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); |
316 | } | 316 | } |
@@ -318,15 +318,15 @@ public abstract class AbstractControllerTest { | @@ -318,15 +318,15 @@ public abstract class AbstractControllerTest { | ||
318 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { | 318 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
319 | return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); | 319 | return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); |
320 | } | 320 | } |
321 | - | 321 | + |
322 | protected ResultActions doPost(String urlTemplate, String... params) throws Exception { | 322 | protected ResultActions doPost(String urlTemplate, String... params) throws Exception { |
323 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); | 323 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
324 | setJwtToken(postRequest); | 324 | setJwtToken(postRequest); |
325 | populateParams(postRequest, params); | 325 | populateParams(postRequest, params); |
326 | return mockMvc.perform(postRequest); | 326 | return mockMvc.perform(postRequest); |
327 | } | 327 | } |
328 | - | ||
329 | - protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception { | 328 | + |
329 | + protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception { | ||
330 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); | 330 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
331 | setJwtToken(postRequest); | 331 | setJwtToken(postRequest); |
332 | String json = json(content); | 332 | String json = json(content); |
@@ -334,25 +334,25 @@ public abstract class AbstractControllerTest { | @@ -334,25 +334,25 @@ public abstract class AbstractControllerTest { | ||
334 | populateParams(postRequest, params); | 334 | populateParams(postRequest, params); |
335 | return mockMvc.perform(postRequest); | 335 | return mockMvc.perform(postRequest); |
336 | } | 336 | } |
337 | - | 337 | + |
338 | protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { | 338 | protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { |
339 | MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); | 339 | MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); |
340 | setJwtToken(deleteRequest); | 340 | setJwtToken(deleteRequest); |
341 | populateParams(deleteRequest, params); | 341 | populateParams(deleteRequest, params); |
342 | return mockMvc.perform(deleteRequest); | 342 | return mockMvc.perform(deleteRequest); |
343 | } | 343 | } |
344 | - | 344 | + |
345 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { | 345 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { |
346 | if (params != null && params.length > 0) { | 346 | if (params != null && params.length > 0) { |
347 | Assert.assertEquals(params.length % 2, 0); | 347 | Assert.assertEquals(params.length % 2, 0); |
348 | MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); | 348 | MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); |
349 | - for (int i=0;i<params.length;i+=2) { | ||
350 | - paramsMap.add(params[i], params[i+1]); | 349 | + for (int i = 0; i < params.length; i += 2) { |
350 | + paramsMap.add(params[i], params[i + 1]); | ||
351 | } | 351 | } |
352 | request.params(paramsMap); | 352 | request.params(paramsMap); |
353 | } | 353 | } |
354 | } | 354 | } |
355 | - | 355 | + |
356 | @SuppressWarnings("unchecked") | 356 | @SuppressWarnings("unchecked") |
357 | protected String json(Object o) throws IOException { | 357 | protected String json(Object o) throws IOException { |
358 | MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); | 358 | MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); |
@@ -360,14 +360,14 @@ public abstract class AbstractControllerTest { | @@ -360,14 +360,14 @@ public abstract class AbstractControllerTest { | ||
360 | o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); | 360 | o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); |
361 | return mockHttpOutputMessage.getBodyAsString(); | 361 | return mockHttpOutputMessage.getBodyAsString(); |
362 | } | 362 | } |
363 | - | 363 | + |
364 | @SuppressWarnings("unchecked") | 364 | @SuppressWarnings("unchecked") |
365 | protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception { | 365 | protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception { |
366 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); | 366 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); |
367 | MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); | 367 | MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); |
368 | return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); | 368 | return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); |
369 | } | 369 | } |
370 | - | 370 | + |
371 | protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { | 371 | protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { |
372 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); | 372 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); |
373 | ObjectMapper mapper = new ObjectMapper(); | 373 | ObjectMapper mapper = new ObjectMapper(); |
common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java
renamed from
dao/src/main/java/org/thingsboard/server/dao/asset/AssetSearchQuery.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.asset; | 16 | +package org.thingsboard.server.common.data.asset; |
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import org.thingsboard.server.common.data.EntityType; | 19 | import org.thingsboard.server.common.data.EntityType; |
@@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.relation.EntityRelationsQuery; | ||
22 | import org.thingsboard.server.common.data.relation.EntityTypeFilter; | 22 | import org.thingsboard.server.common.data.relation.EntityTypeFilter; |
23 | import org.thingsboard.server.common.data.relation.RelationsSearchParameters; | 23 | import org.thingsboard.server.common.data.relation.RelationsSearchParameters; |
24 | 24 | ||
25 | -import javax.annotation.Nullable; | ||
26 | import java.util.Collections; | 25 | import java.util.Collections; |
27 | import java.util.List; | 26 | import java.util.List; |
28 | 27 | ||
@@ -33,9 +32,7 @@ import java.util.List; | @@ -33,9 +32,7 @@ import java.util.List; | ||
33 | public class AssetSearchQuery { | 32 | public class AssetSearchQuery { |
34 | 33 | ||
35 | private RelationsSearchParameters parameters; | 34 | private RelationsSearchParameters parameters; |
36 | - @Nullable | ||
37 | private String relationType; | 35 | private String relationType; |
38 | - @Nullable | ||
39 | private List<String> assetTypes; | 36 | private List<String> assetTypes; |
40 | 37 | ||
41 | public EntityRelationsQuery toEntitySearchQuery() { | 38 | public EntityRelationsQuery toEntitySearchQuery() { |
dao/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java
renamed from
dao/src/main/java/org/thingsboard/server/dao/device/DeviceSearchQuery.java
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.server.dao.device; | 16 | +package org.thingsboard.server.common.data.device; |
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import org.thingsboard.server.common.data.EntityType; | 19 | import org.thingsboard.server.common.data.EntityType; |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.asset; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.asset; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.EntitySubtype; | 19 | import org.thingsboard.server.common.data.EntitySubtype; |
20 | import org.thingsboard.server.common.data.asset.Asset; | 20 | import org.thingsboard.server.common.data.asset.Asset; |
21 | +import org.thingsboard.server.common.data.asset.AssetSearchQuery; | ||
21 | import org.thingsboard.server.common.data.id.AssetId; | 22 | import org.thingsboard.server.common.data.id.AssetId; |
22 | import org.thingsboard.server.common.data.id.CustomerId; | 23 | import org.thingsboard.server.common.data.id.CustomerId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.EntitySubtype; | @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.EntitySubtype; | ||
29 | import org.thingsboard.server.common.data.EntityType; | 29 | import org.thingsboard.server.common.data.EntityType; |
30 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | import org.thingsboard.server.common.data.asset.Asset; | 31 | import org.thingsboard.server.common.data.asset.Asset; |
32 | +import org.thingsboard.server.common.data.asset.AssetSearchQuery; | ||
32 | import org.thingsboard.server.common.data.id.AssetId; | 33 | import org.thingsboard.server.common.data.id.AssetId; |
33 | import org.thingsboard.server.common.data.id.CustomerId; | 34 | import org.thingsboard.server.common.data.id.CustomerId; |
34 | import org.thingsboard.server.common.data.id.EntityId; | 35 | import org.thingsboard.server.common.data.id.EntityId; |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.Device; | 19 | import org.thingsboard.server.common.data.Device; |
20 | import org.thingsboard.server.common.data.EntitySubtype; | 20 | import org.thingsboard.server.common.data.EntitySubtype; |
21 | +import org.thingsboard.server.common.data.device.DeviceSearchQuery; | ||
21 | import org.thingsboard.server.common.data.id.CustomerId; | 22 | import org.thingsboard.server.common.data.id.CustomerId; |
22 | import org.thingsboard.server.common.data.id.DeviceId; | 23 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
25 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | import org.springframework.util.StringUtils; | 26 | import org.springframework.util.StringUtils; |
27 | import org.thingsboard.server.common.data.*; | 27 | import org.thingsboard.server.common.data.*; |
28 | +import org.thingsboard.server.common.data.device.DeviceSearchQuery; | ||
28 | import org.thingsboard.server.common.data.id.CustomerId; | 29 | import org.thingsboard.server.common.data.id.CustomerId; |
29 | import org.thingsboard.server.common.data.id.DeviceId; | 30 | import org.thingsboard.server.common.data.id.DeviceId; |
30 | import org.thingsboard.server.common.data.id.EntityId; | 31 | import org.thingsboard.server.common.data.id.EntityId; |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.transport.mqtt; | 16 | package org.thingsboard.server.transport.mqtt; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import io.netty.channel.Channel; | ||
19 | import io.netty.channel.ChannelHandlerContext; | 20 | import io.netty.channel.ChannelHandlerContext; |
20 | import io.netty.channel.ChannelInboundHandlerAdapter; | 21 | import io.netty.channel.ChannelInboundHandlerAdapter; |
21 | import io.netty.handler.codec.mqtt.*; | 22 | import io.netty.handler.codec.mqtt.*; |
@@ -45,6 +46,8 @@ import org.thingsboard.server.transport.mqtt.util.SslUtil; | @@ -45,6 +46,8 @@ import org.thingsboard.server.transport.mqtt.util.SslUtil; | ||
45 | 46 | ||
46 | import javax.net.ssl.SSLPeerUnverifiedException; | 47 | import javax.net.ssl.SSLPeerUnverifiedException; |
47 | import javax.security.cert.X509Certificate; | 48 | import javax.security.cert.X509Certificate; |
49 | +import java.net.InetSocketAddress; | ||
50 | +import java.net.SocketAddress; | ||
48 | import java.util.ArrayList; | 51 | import java.util.ArrayList; |
49 | import java.util.List; | 52 | import java.util.List; |
50 | 53 | ||
@@ -71,6 +74,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -71,6 +74,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
71 | private final RelationService relationService; | 74 | private final RelationService relationService; |
72 | private final SslHandler sslHandler; | 75 | private final SslHandler sslHandler; |
73 | private volatile boolean connected; | 76 | private volatile boolean connected; |
77 | + private volatile InetSocketAddress address; | ||
74 | private volatile GatewaySessionCtx gatewaySessionCtx; | 78 | private volatile GatewaySessionCtx gatewaySessionCtx; |
75 | 79 | ||
76 | public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, | 80 | public MqttTransportHandler(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, |
@@ -94,30 +98,36 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -94,30 +98,36 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
94 | } | 98 | } |
95 | 99 | ||
96 | private void processMqttMsg(ChannelHandlerContext ctx, MqttMessage msg) { | 100 | private void processMqttMsg(ChannelHandlerContext ctx, MqttMessage msg) { |
97 | - deviceSessionCtx.setChannel(ctx); | ||
98 | - switch (msg.fixedHeader().messageType()) { | ||
99 | - case CONNECT: | ||
100 | - processConnect(ctx, (MqttConnectMessage) msg); | ||
101 | - break; | ||
102 | - case PUBLISH: | ||
103 | - processPublish(ctx, (MqttPublishMessage) msg); | ||
104 | - break; | ||
105 | - case SUBSCRIBE: | ||
106 | - processSubscribe(ctx, (MqttSubscribeMessage) msg); | ||
107 | - break; | ||
108 | - case UNSUBSCRIBE: | ||
109 | - processUnsubscribe(ctx, (MqttUnsubscribeMessage) msg); | ||
110 | - break; | ||
111 | - case PINGREQ: | ||
112 | - if (checkConnected(ctx)) { | ||
113 | - ctx.writeAndFlush(new MqttMessage(new MqttFixedHeader(PINGRESP, false, AT_MOST_ONCE, false, 0))); | ||
114 | - } | ||
115 | - break; | ||
116 | - case DISCONNECT: | ||
117 | - if (checkConnected(ctx)) { | ||
118 | - processDisconnect(ctx); | ||
119 | - } | ||
120 | - break; | 101 | + address = (InetSocketAddress) ctx.channel().remoteAddress(); |
102 | + if (msg.fixedHeader() == null) { | ||
103 | + log.info("[{}:{}] Invalid message received", address.getHostName(), address.getPort()); | ||
104 | + processDisconnect(ctx); | ||
105 | + } else { | ||
106 | + deviceSessionCtx.setChannel(ctx); | ||
107 | + switch (msg.fixedHeader().messageType()) { | ||
108 | + case CONNECT: | ||
109 | + processConnect(ctx, (MqttConnectMessage) msg); | ||
110 | + break; | ||
111 | + case PUBLISH: | ||
112 | + processPublish(ctx, (MqttPublishMessage) msg); | ||
113 | + break; | ||
114 | + case SUBSCRIBE: | ||
115 | + processSubscribe(ctx, (MqttSubscribeMessage) msg); | ||
116 | + break; | ||
117 | + case UNSUBSCRIBE: | ||
118 | + processUnsubscribe(ctx, (MqttUnsubscribeMessage) msg); | ||
119 | + break; | ||
120 | + case PINGREQ: | ||
121 | + if (checkConnected(ctx)) { | ||
122 | + ctx.writeAndFlush(new MqttMessage(new MqttFixedHeader(PINGRESP, false, AT_MOST_ONCE, false, 0))); | ||
123 | + } | ||
124 | + break; | ||
125 | + case DISCONNECT: | ||
126 | + if (checkConnected(ctx)) { | ||
127 | + processDisconnect(ctx); | ||
128 | + } | ||
129 | + break; | ||
130 | + } | ||
121 | } | 131 | } |
122 | } | 132 | } |
123 | 133 | ||
@@ -313,9 +323,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | @@ -313,9 +323,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement | ||
313 | 323 | ||
314 | private void processDisconnect(ChannelHandlerContext ctx) { | 324 | private void processDisconnect(ChannelHandlerContext ctx) { |
315 | ctx.close(); | 325 | ctx.close(); |
316 | - processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId())); | ||
317 | - if (gatewaySessionCtx != null) { | ||
318 | - gatewaySessionCtx.onGatewayDisconnect(); | 326 | + if (connected) { |
327 | + processor.process(SessionCloseMsg.onDisconnect(deviceSessionCtx.getSessionId())); | ||
328 | + if (gatewaySessionCtx != null) { | ||
329 | + gatewaySessionCtx.onGatewayDisconnect(); | ||
330 | + } | ||
319 | } | 331 | } |
320 | } | 332 | } |
321 | 333 |