Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Yassmine Mestiri
thingsboard
Commits
98ad3b98
Commit
98ad3b98
authored
Mar 10, 2023
by
Yassmine Mestiri
Browse files
iot
parent
aea55d6d
Pipeline
#2009
failed with stages
in 0 seconds
Changes
273
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 273+
files are displayed.
Plain diff
Email patch
application/src/main/java/org/thingsboard/server/service/edge/EdgeNotificationService.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.common.data.id.RuleChainId
;
import
org.thingsboard.server.common.data.id.TenantId
;
import
org.thingsboard.server.common.msg.queue.TbCallback
;
import
org.thingsboard.server.gen.transport.TransportProtos
;
public
interface
EdgeNotificationService
{
Edge
setEdgeRootRuleChain
(
TenantId
tenantId
,
Edge
edge
,
RuleChainId
ruleChainId
)
throws
Exception
;
void
pushNotificationToEdge
(
TransportProtos
.
EdgeNotificationMsgProto
edgeNotificationMsg
,
TbCallback
callback
);
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventStorageSettings.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
@Component
@Data
public
class
EdgeEventStorageSettings
{
@Value
(
"${edges.storage.max_read_records_count}"
)
private
int
maxReadRecordsCount
;
@Value
(
"${edges.storage.no_read_records_sleep}"
)
private
long
noRecordsSleepInterval
;
@Value
(
"${edges.storage.sleep_between_batches}"
)
private
long
sleepIntervalBetweenBatches
;
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
com.google.common.util.concurrent.FutureCallback
;
import
com.google.common.util.concurrent.Futures
;
import
io.grpc.Server
;
import
io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder
;
import
io.grpc.stub.StreamObserver
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.stereotype.Service
;
import
org.thingsboard.common.util.ThingsBoardThreadFactory
;
import
org.thingsboard.server.cluster.TbClusterService
;
import
org.thingsboard.server.common.data.DataConstants
;
import
org.thingsboard.server.common.data.ResourceUtils
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.common.data.id.EdgeId
;
import
org.thingsboard.server.common.data.id.TenantId
;
import
org.thingsboard.server.common.data.kv.BasicTsKvEntry
;
import
org.thingsboard.server.common.data.kv.BooleanDataEntry
;
import
org.thingsboard.server.common.data.kv.LongDataEntry
;
import
org.thingsboard.server.common.msg.edge.EdgeEventUpdateMsg
;
import
org.thingsboard.server.common.msg.edge.EdgeSessionMsg
;
import
org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse
;
import
org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest
;
import
org.thingsboard.server.gen.edge.v1.EdgeRpcServiceGrpc
;
import
org.thingsboard.server.gen.edge.v1.RequestMsg
;
import
org.thingsboard.server.gen.edge.v1.ResponseMsg
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
import
org.thingsboard.server.service.edge.EdgeContextComponent
;
import
org.thingsboard.server.service.state.DefaultDeviceStateService
;
import
org.thingsboard.server.service.telemetry.TelemetrySubscriptionService
;
import
javax.annotation.Nullable
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.PreDestroy
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.UUID
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ScheduledFuture
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.locks.Lock
;
import
java.util.concurrent.locks.ReentrantLock
;
import
java.util.function.Consumer
;
@Service
@Slf4j
@ConditionalOnProperty
(
prefix
=
"edges"
,
value
=
"enabled"
,
havingValue
=
"true"
)
@TbCoreComponent
public
class
EdgeGrpcService
extends
EdgeRpcServiceGrpc
.
EdgeRpcServiceImplBase
implements
EdgeRpcService
{
private
final
ConcurrentMap
<
EdgeId
,
EdgeGrpcSession
>
sessions
=
new
ConcurrentHashMap
<>();
private
final
ConcurrentMap
<
EdgeId
,
Lock
>
sessionNewEventsLocks
=
new
ConcurrentHashMap
<>();
private
final
Map
<
EdgeId
,
Boolean
>
sessionNewEvents
=
new
HashMap
<>();
private
final
ConcurrentMap
<
EdgeId
,
ScheduledFuture
<?>>
sessionEdgeEventChecks
=
new
ConcurrentHashMap
<>();
private
final
ConcurrentMap
<
UUID
,
Consumer
<
FromEdgeSyncResponse
>>
localSyncEdgeRequests
=
new
ConcurrentHashMap
<>();
@Value
(
"${edges.rpc.port}"
)
private
int
rpcPort
;
@Value
(
"${edges.rpc.ssl.enabled}"
)
private
boolean
sslEnabled
;
@Value
(
"${edges.rpc.ssl.cert}"
)
private
String
certFileResource
;
@Value
(
"${edges.rpc.ssl.private_key}"
)
private
String
privateKeyResource
;
@Value
(
"${edges.state.persistToTelemetry:false}"
)
private
boolean
persistToTelemetry
;
@Value
(
"${edges.rpc.client_max_keep_alive_time_sec}"
)
private
int
clientMaxKeepAliveTimeSec
;
@Value
(
"${edges.rpc.max_inbound_message_size:4194304}"
)
private
int
maxInboundMessageSize
;
@Value
(
"${edges.scheduler_pool_size}"
)
private
int
schedulerPoolSize
;
@Value
(
"${edges.send_scheduler_pool_size}"
)
private
int
sendSchedulerPoolSize
;
@Autowired
private
EdgeContextComponent
ctx
;
@Autowired
private
TelemetrySubscriptionService
tsSubService
;
@Autowired
private
TbClusterService
clusterService
;
private
Server
server
;
private
ScheduledExecutorService
edgeEventProcessingExecutorService
;
private
ScheduledExecutorService
sendDownlinkExecutorService
;
private
ScheduledExecutorService
executorService
;
@PostConstruct
public
void
init
()
{
log
.
info
(
"Initializing Edge RPC service!"
);
NettyServerBuilder
builder
=
NettyServerBuilder
.
forPort
(
rpcPort
)
.
permitKeepAliveTime
(
clientMaxKeepAliveTimeSec
,
TimeUnit
.
SECONDS
)
.
maxInboundMessageSize
(
maxInboundMessageSize
)
.
addService
(
this
);
if
(
sslEnabled
)
{
try
{
InputStream
certFileIs
=
ResourceUtils
.
getInputStream
(
this
,
certFileResource
);
InputStream
privateKeyFileIs
=
ResourceUtils
.
getInputStream
(
this
,
privateKeyResource
);
builder
.
useTransportSecurity
(
certFileIs
,
privateKeyFileIs
);
}
catch
(
Exception
e
)
{
log
.
error
(
"Unable to set up SSL context. Reason: "
+
e
.
getMessage
(),
e
);
throw
new
RuntimeException
(
"Unable to set up SSL context!"
,
e
);
}
}
server
=
builder
.
build
();
log
.
info
(
"Going to start Edge RPC server using port: {}"
,
rpcPort
);
try
{
server
.
start
();
}
catch
(
IOException
e
)
{
log
.
error
(
"Failed to start Edge RPC server!"
,
e
);
throw
new
RuntimeException
(
"Failed to start Edge RPC server!"
);
}
this
.
edgeEventProcessingExecutorService
=
Executors
.
newScheduledThreadPool
(
schedulerPoolSize
,
ThingsBoardThreadFactory
.
forName
(
"edge-event-check-scheduler"
));
this
.
sendDownlinkExecutorService
=
Executors
.
newScheduledThreadPool
(
sendSchedulerPoolSize
,
ThingsBoardThreadFactory
.
forName
(
"edge-send-scheduler"
));
this
.
executorService
=
Executors
.
newSingleThreadScheduledExecutor
(
ThingsBoardThreadFactory
.
forName
(
"edge-service"
));
log
.
info
(
"Edge RPC service initialized!"
);
}
@PreDestroy
public
void
destroy
()
{
if
(
server
!=
null
)
{
server
.
shutdownNow
();
}
for
(
Map
.
Entry
<
EdgeId
,
ScheduledFuture
<?>>
entry
:
sessionEdgeEventChecks
.
entrySet
())
{
EdgeId
edgeId
=
entry
.
getKey
();
ScheduledFuture
<?>
sessionEdgeEventCheck
=
entry
.
getValue
();
if
(
sessionEdgeEventCheck
!=
null
&&
!
sessionEdgeEventCheck
.
isCancelled
()
&&
!
sessionEdgeEventCheck
.
isDone
())
{
sessionEdgeEventCheck
.
cancel
(
true
);
sessionEdgeEventChecks
.
remove
(
edgeId
);
}
}
if
(
edgeEventProcessingExecutorService
!=
null
)
{
edgeEventProcessingExecutorService
.
shutdownNow
();
}
if
(
sendDownlinkExecutorService
!=
null
)
{
sendDownlinkExecutorService
.
shutdownNow
();
}
if
(
executorService
!=
null
)
{
executorService
.
shutdownNow
();
}
}
@Override
public
StreamObserver
<
RequestMsg
>
handleMsgs
(
StreamObserver
<
ResponseMsg
>
outputStream
)
{
return
new
EdgeGrpcSession
(
ctx
,
outputStream
,
this
::
onEdgeConnect
,
this
::
onEdgeDisconnect
,
sendDownlinkExecutorService
).
getInputStream
();
}
@Override
public
void
onToEdgeSessionMsg
(
TenantId
tenantId
,
EdgeSessionMsg
msg
)
{
executorService
.
execute
(()
->
{
switch
(
msg
.
getMsgType
())
{
case
EDGE_EVENT_UPDATE_TO_EDGE_SESSION_MSG:
EdgeEventUpdateMsg
edgeEventUpdateMsg
=
(
EdgeEventUpdateMsg
)
msg
;
log
.
trace
(
"[{}] onToEdgeSessionMsg [{}]"
,
edgeEventUpdateMsg
.
getTenantId
(),
msg
);
onEdgeEvent
(
tenantId
,
edgeEventUpdateMsg
.
getEdgeId
());
break
;
case
EDGE_SYNC_REQUEST_TO_EDGE_SESSION_MSG:
ToEdgeSyncRequest
toEdgeSyncRequest
=
(
ToEdgeSyncRequest
)
msg
;
log
.
trace
(
"[{}] toEdgeSyncRequest [{}]"
,
toEdgeSyncRequest
.
getTenantId
(),
msg
);
startSyncProcess
(
tenantId
,
toEdgeSyncRequest
.
getEdgeId
(),
toEdgeSyncRequest
.
getId
());
break
;
case
EDGE_SYNC_RESPONSE_FROM_EDGE_SESSION_MSG:
FromEdgeSyncResponse
fromEdgeSyncResponse
=
(
FromEdgeSyncResponse
)
msg
;
log
.
trace
(
"[{}] fromEdgeSyncResponse [{}]"
,
fromEdgeSyncResponse
.
getTenantId
(),
msg
);
processSyncResponse
(
fromEdgeSyncResponse
);
break
;
}
});
}
@Override
public
void
updateEdge
(
TenantId
tenantId
,
Edge
edge
)
{
executorService
.
execute
(()
->
{
EdgeGrpcSession
session
=
sessions
.
get
(
edge
.
getId
());
if
(
session
!=
null
&&
session
.
isConnected
())
{
log
.
debug
(
"[{}] Updating configuration for edge [{}] [{}]"
,
tenantId
,
edge
.
getName
(),
edge
.
getId
());
session
.
onConfigurationUpdate
(
edge
);
}
else
{
log
.
debug
(
"[{}] Session doesn't exist for edge [{}] [{}]"
,
tenantId
,
edge
.
getName
(),
edge
.
getId
());
}
});
}
@Override
public
void
deleteEdge
(
TenantId
tenantId
,
EdgeId
edgeId
)
{
executorService
.
execute
(()
->
{
EdgeGrpcSession
session
=
sessions
.
get
(
edgeId
);
if
(
session
!=
null
&&
session
.
isConnected
())
{
log
.
info
(
"[{}] Closing and removing session for edge [{}]"
,
tenantId
,
edgeId
);
session
.
close
();
sessions
.
remove
(
edgeId
);
final
Lock
newEventLock
=
sessionNewEventsLocks
.
computeIfAbsent
(
edgeId
,
id
->
new
ReentrantLock
());
newEventLock
.
lock
();
try
{
sessionNewEvents
.
remove
(
edgeId
);
}
finally
{
newEventLock
.
unlock
();
}
cancelScheduleEdgeEventsCheck
(
edgeId
);
}
});
}
private
void
onEdgeEvent
(
TenantId
tenantId
,
EdgeId
edgeId
)
{
EdgeGrpcSession
session
=
sessions
.
get
(
edgeId
);
if
(
session
!=
null
&&
session
.
isConnected
())
{
log
.
trace
(
"[{}] onEdgeEvent [{}]"
,
tenantId
,
edgeId
.
getId
());
final
Lock
newEventLock
=
sessionNewEventsLocks
.
computeIfAbsent
(
edgeId
,
id
->
new
ReentrantLock
());
newEventLock
.
lock
();
try
{
if
(
Boolean
.
FALSE
.
equals
(
sessionNewEvents
.
get
(
edgeId
)))
{
log
.
trace
(
"[{}] set session new events flag to true [{}]"
,
tenantId
,
edgeId
.
getId
());
sessionNewEvents
.
put
(
edgeId
,
true
);
}
}
finally
{
newEventLock
.
unlock
();
}
}
}
private
void
onEdgeConnect
(
EdgeId
edgeId
,
EdgeGrpcSession
edgeGrpcSession
)
{
log
.
info
(
"[{}] edge [{}] connected successfully."
,
edgeGrpcSession
.
getSessionId
(),
edgeId
);
sessions
.
put
(
edgeId
,
edgeGrpcSession
);
final
Lock
newEventLock
=
sessionNewEventsLocks
.
computeIfAbsent
(
edgeId
,
id
->
new
ReentrantLock
());
newEventLock
.
lock
();
try
{
sessionNewEvents
.
put
(
edgeId
,
true
);
}
finally
{
newEventLock
.
unlock
();
}
save
(
edgeId
,
DefaultDeviceStateService
.
ACTIVITY_STATE
,
true
);
save
(
edgeId
,
DefaultDeviceStateService
.
LAST_CONNECT_TIME
,
System
.
currentTimeMillis
());
cancelScheduleEdgeEventsCheck
(
edgeId
);
scheduleEdgeEventsCheck
(
edgeGrpcSession
);
}
private
void
startSyncProcess
(
TenantId
tenantId
,
EdgeId
edgeId
,
UUID
requestId
)
{
EdgeGrpcSession
session
=
sessions
.
get
(
edgeId
);
if
(
session
!=
null
)
{
boolean
success
=
false
;
if
(
session
.
isConnected
())
{
session
.
startSyncProcess
(
tenantId
,
edgeId
,
true
);
success
=
true
;
}
clusterService
.
pushEdgeSyncResponseToCore
(
new
FromEdgeSyncResponse
(
requestId
,
tenantId
,
edgeId
,
success
));
}
}
@Override
public
void
processSyncRequest
(
ToEdgeSyncRequest
request
,
Consumer
<
FromEdgeSyncResponse
>
responseConsumer
)
{
log
.
trace
(
"[{}][{}] Processing sync edge request [{}]"
,
request
.
getTenantId
(),
request
.
getId
(),
request
.
getEdgeId
());
UUID
requestId
=
request
.
getId
();
localSyncEdgeRequests
.
put
(
requestId
,
responseConsumer
);
clusterService
.
pushEdgeSyncRequestToCore
(
request
);
scheduleSyncRequestTimeout
(
request
,
requestId
);
}
private
void
scheduleSyncRequestTimeout
(
ToEdgeSyncRequest
request
,
UUID
requestId
)
{
log
.
trace
(
"[{}] scheduling sync edge request"
,
requestId
);
executorService
.
schedule
(()
->
{
log
.
trace
(
"[{}] checking if sync edge request is not processed..."
,
requestId
);
Consumer
<
FromEdgeSyncResponse
>
consumer
=
localSyncEdgeRequests
.
remove
(
requestId
);
if
(
consumer
!=
null
)
{
log
.
trace
(
"[{}] timeout for processing sync edge request."
,
requestId
);
consumer
.
accept
(
new
FromEdgeSyncResponse
(
requestId
,
request
.
getTenantId
(),
request
.
getEdgeId
(),
false
));
}
},
20
,
TimeUnit
.
SECONDS
);
}
private
void
processSyncResponse
(
FromEdgeSyncResponse
response
)
{
log
.
trace
(
"[{}] Received response from sync service: [{}]"
,
response
.
getId
(),
response
);
UUID
requestId
=
response
.
getId
();
Consumer
<
FromEdgeSyncResponse
>
consumer
=
localSyncEdgeRequests
.
remove
(
requestId
);
if
(
consumer
!=
null
)
{
consumer
.
accept
(
response
);
}
else
{
log
.
trace
(
"[{}] Unknown or stale sync response received [{}]"
,
requestId
,
response
);
}
}
private
void
scheduleEdgeEventsCheck
(
EdgeGrpcSession
session
)
{
EdgeId
edgeId
=
session
.
getEdge
().
getId
();
UUID
tenantId
=
session
.
getEdge
().
getTenantId
().
getId
();
if
(
sessions
.
containsKey
(
edgeId
))
{
ScheduledFuture
<?>
edgeEventCheckTask
=
edgeEventProcessingExecutorService
.
schedule
(()
->
{
try
{
final
Lock
newEventLock
=
sessionNewEventsLocks
.
computeIfAbsent
(
edgeId
,
id
->
new
ReentrantLock
());
newEventLock
.
lock
();
try
{
if
(
Boolean
.
TRUE
.
equals
(
sessionNewEvents
.
get
(
edgeId
)))
{
log
.
trace
(
"[{}] Set session new events flag to false"
,
edgeId
.
getId
());
sessionNewEvents
.
put
(
edgeId
,
false
);
Futures
.
addCallback
(
session
.
processEdgeEvents
(),
new
FutureCallback
<>()
{
@Override
public
void
onSuccess
(
Void
result
)
{
scheduleEdgeEventsCheck
(
session
);
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
warn
(
"[{}] Failed to process edge events for edge [{}]!"
,
tenantId
,
session
.
getEdge
().
getId
().
getId
(),
t
);
scheduleEdgeEventsCheck
(
session
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
else
{
scheduleEdgeEventsCheck
(
session
);
}
}
finally
{
newEventLock
.
unlock
();
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"[{}] Failed to process edge events for edge [{}]!"
,
tenantId
,
session
.
getEdge
().
getId
().
getId
(),
e
);
}
},
ctx
.
getEdgeEventStorageSettings
().
getNoRecordsSleepInterval
(),
TimeUnit
.
MILLISECONDS
);
sessionEdgeEventChecks
.
put
(
edgeId
,
edgeEventCheckTask
);
log
.
trace
(
"[{}] Check edge event scheduled for edge [{}]"
,
tenantId
,
edgeId
.
getId
());
}
else
{
log
.
debug
(
"[{}] Session was removed and edge event check schedule must not be started [{}]"
,
tenantId
,
edgeId
.
getId
());
}
}
private
void
cancelScheduleEdgeEventsCheck
(
EdgeId
edgeId
)
{
log
.
trace
(
"[{}] cancelling edge event check for edge"
,
edgeId
);
if
(
sessionEdgeEventChecks
.
containsKey
(
edgeId
))
{
ScheduledFuture
<?>
sessionEdgeEventCheck
=
sessionEdgeEventChecks
.
get
(
edgeId
);
if
(
sessionEdgeEventCheck
!=
null
&&
!
sessionEdgeEventCheck
.
isCancelled
()
&&
!
sessionEdgeEventCheck
.
isDone
())
{
sessionEdgeEventCheck
.
cancel
(
true
);
sessionEdgeEventChecks
.
remove
(
edgeId
);
}
}
}
private
void
onEdgeDisconnect
(
EdgeId
edgeId
)
{
log
.
info
(
"[{}] edge disconnected!"
,
edgeId
);
sessions
.
remove
(
edgeId
);
final
Lock
newEventLock
=
sessionNewEventsLocks
.
computeIfAbsent
(
edgeId
,
id
->
new
ReentrantLock
());
newEventLock
.
lock
();
try
{
sessionNewEvents
.
remove
(
edgeId
);
}
finally
{
newEventLock
.
unlock
();
}
save
(
edgeId
,
DefaultDeviceStateService
.
ACTIVITY_STATE
,
false
);
save
(
edgeId
,
DefaultDeviceStateService
.
LAST_DISCONNECT_TIME
,
System
.
currentTimeMillis
());
cancelScheduleEdgeEventsCheck
(
edgeId
);
}
private
void
save
(
EdgeId
edgeId
,
String
key
,
long
value
)
{
log
.
debug
(
"[{}] Updating long edge telemetry [{}] [{}]"
,
edgeId
,
key
,
value
);
if
(
persistToTelemetry
)
{
tsSubService
.
saveAndNotify
(
TenantId
.
SYS_TENANT_ID
,
edgeId
,
Collections
.
singletonList
(
new
BasicTsKvEntry
(
System
.
currentTimeMillis
(),
new
LongDataEntry
(
key
,
value
))),
new
AttributeSaveCallback
(
edgeId
,
key
,
value
));
}
else
{
tsSubService
.
saveAttrAndNotify
(
TenantId
.
SYS_TENANT_ID
,
edgeId
,
DataConstants
.
SERVER_SCOPE
,
key
,
value
,
new
AttributeSaveCallback
(
edgeId
,
key
,
value
));
}
}
private
void
save
(
EdgeId
edgeId
,
String
key
,
boolean
value
)
{
log
.
debug
(
"[{}] Updating boolean edge telemetry [{}] [{}]"
,
edgeId
,
key
,
value
);
if
(
persistToTelemetry
)
{
tsSubService
.
saveAndNotify
(
TenantId
.
SYS_TENANT_ID
,
edgeId
,
Collections
.
singletonList
(
new
BasicTsKvEntry
(
System
.
currentTimeMillis
(),
new
BooleanDataEntry
(
key
,
value
))),
new
AttributeSaveCallback
(
edgeId
,
key
,
value
));
}
else
{
tsSubService
.
saveAttrAndNotify
(
TenantId
.
SYS_TENANT_ID
,
edgeId
,
DataConstants
.
SERVER_SCOPE
,
key
,
value
,
new
AttributeSaveCallback
(
edgeId
,
key
,
value
));
}
}
private
static
class
AttributeSaveCallback
implements
FutureCallback
<
Void
>
{
private
final
EdgeId
edgeId
;
private
final
String
key
;
private
final
Object
value
;
AttributeSaveCallback
(
EdgeId
edgeId
,
String
key
,
Object
value
)
{
this
.
edgeId
=
edgeId
;
this
.
key
=
key
;
this
.
value
=
value
;
}
@Override
public
void
onSuccess
(
@Nullable
Void
result
)
{
log
.
trace
(
"[{}] Successfully updated attribute [{}] with value [{}]"
,
edgeId
,
key
,
value
);
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
warn
(
"[{}] Failed to update attribute [{}] with value [{}]"
,
edgeId
,
key
,
value
,
t
);
}
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
com.datastax.oss.driver.api.core.uuid.Uuids
;
import
com.google.common.util.concurrent.FutureCallback
;
import
com.google.common.util.concurrent.Futures
;
import
com.google.common.util.concurrent.ListenableFuture
;
import
com.google.common.util.concurrent.SettableFuture
;
import
io.grpc.stub.StreamObserver
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
org.checkerframework.checker.nullness.qual.Nullable
;
import
org.thingsboard.server.common.data.DataConstants
;
import
org.thingsboard.server.common.data.EdgeUtils
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.common.data.edge.EdgeEvent
;
import
org.thingsboard.server.common.data.id.EdgeId
;
import
org.thingsboard.server.common.data.id.TenantId
;
import
org.thingsboard.server.common.data.kv.AttributeKvEntry
;
import
org.thingsboard.server.common.data.kv.BaseAttributeKvEntry
;
import
org.thingsboard.server.common.data.kv.LongDataEntry
;
import
org.thingsboard.server.common.data.page.PageData
;
import
org.thingsboard.server.common.data.page.PageLink
;
import
org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.AttributesRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.ConnectRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.ConnectResponseCode
;
import
org.thingsboard.server.gen.edge.v1.ConnectResponseMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.DownlinkMsg
;
import
org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg
;
import
org.thingsboard.server.gen.edge.v1.EdgeConfiguration
;
import
org.thingsboard.server.gen.edge.v1.EdgeUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.EdgeVersion
;
import
org.thingsboard.server.gen.edge.v1.EntityDataProto
;
import
org.thingsboard.server.gen.edge.v1.EntityViewsRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.RelationRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.RelationUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.RequestMsg
;
import
org.thingsboard.server.gen.edge.v1.RequestMsgType
;
import
org.thingsboard.server.gen.edge.v1.ResponseMsg
;
import
org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.SyncCompletedMsg
;
import
org.thingsboard.server.gen.edge.v1.UplinkMsg
;
import
org.thingsboard.server.gen.edge.v1.UplinkResponseMsg
;
import
org.thingsboard.server.gen.edge.v1.UserCredentialsRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.WidgetBundleTypesRequestMsg
;
import
org.thingsboard.server.service.edge.EdgeContextComponent
;
import
org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.GeneralEdgeEventFetcher
;
import
java.io.Closeable
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.UUID
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.locks.ReentrantLock
;
import
java.util.function.BiConsumer
;
import
java.util.function.Consumer
;
import
java.util.stream.Collectors
;
@Slf4j
@Data
public
final
class
EdgeGrpcSession
implements
Closeable
{
private
static
final
ReentrantLock
downlinkMsgLock
=
new
ReentrantLock
();
private
static
final
int
MAX_DOWNLINK_ATTEMPTS
=
10
;
// max number of attemps to send downlink message if edge connected
private
static
final
String
QUEUE_START_TS_ATTR_KEY
=
"queueStartTs"
;
private
final
UUID
sessionId
;
private
final
BiConsumer
<
EdgeId
,
EdgeGrpcSession
>
sessionOpenListener
;
private
final
Consumer
<
EdgeId
>
sessionCloseListener
;
private
final
EdgeSessionState
sessionState
=
new
EdgeSessionState
();
private
EdgeContextComponent
ctx
;
private
Edge
edge
;
private
StreamObserver
<
RequestMsg
>
inputStream
;
private
StreamObserver
<
ResponseMsg
>
outputStream
;
private
boolean
connected
;
private
boolean
syncCompleted
;
private
EdgeVersion
edgeVersion
;
private
ScheduledExecutorService
sendDownlinkExecutorService
;
EdgeGrpcSession
(
EdgeContextComponent
ctx
,
StreamObserver
<
ResponseMsg
>
outputStream
,
BiConsumer
<
EdgeId
,
EdgeGrpcSession
>
sessionOpenListener
,
Consumer
<
EdgeId
>
sessionCloseListener
,
ScheduledExecutorService
sendDownlinkExecutorService
)
{
this
.
sessionId
=
UUID
.
randomUUID
();
this
.
ctx
=
ctx
;
this
.
outputStream
=
outputStream
;
this
.
sessionOpenListener
=
sessionOpenListener
;
this
.
sessionCloseListener
=
sessionCloseListener
;
this
.
sendDownlinkExecutorService
=
sendDownlinkExecutorService
;
initInputStream
();
}
private
void
initInputStream
()
{
this
.
inputStream
=
new
StreamObserver
<>()
{
@Override
public
void
onNext
(
RequestMsg
requestMsg
)
{
if
(!
connected
&&
requestMsg
.
getMsgType
().
equals
(
RequestMsgType
.
CONNECT_RPC_MESSAGE
))
{
ConnectResponseMsg
responseMsg
=
processConnect
(
requestMsg
.
getConnectRequestMsg
());
outputStream
.
onNext
(
ResponseMsg
.
newBuilder
()
.
setConnectResponseMsg
(
responseMsg
)
.
build
());
if
(
ConnectResponseCode
.
ACCEPTED
!=
responseMsg
.
getResponseCode
())
{
outputStream
.
onError
(
new
RuntimeException
(
responseMsg
.
getErrorMsg
()));
}
else
{
connected
=
true
;
}
}
if
(
connected
)
{
if
(
requestMsg
.
getMsgType
().
equals
(
RequestMsgType
.
SYNC_REQUEST_RPC_MESSAGE
))
{
if
(
requestMsg
.
hasSyncRequestMsg
()
&&
requestMsg
.
getSyncRequestMsg
().
getSyncRequired
())
{
boolean
fullSync
=
true
;
if
(
requestMsg
.
getSyncRequestMsg
().
hasFullSync
())
{
fullSync
=
requestMsg
.
getSyncRequestMsg
().
getFullSync
();
}
startSyncProcess
(
edge
.
getTenantId
(),
edge
.
getId
(),
fullSync
);
}
else
{
syncCompleted
=
true
;
}
}
if
(
requestMsg
.
getMsgType
().
equals
(
RequestMsgType
.
UPLINK_RPC_MESSAGE
))
{
if
(
requestMsg
.
hasUplinkMsg
())
{
onUplinkMsg
(
requestMsg
.
getUplinkMsg
());
}
if
(
requestMsg
.
hasDownlinkResponseMsg
())
{
onDownlinkResponse
(
requestMsg
.
getDownlinkResponseMsg
());
}
}
}
}
@Override
public
void
onError
(
Throwable
t
)
{
log
.
error
(
"[{}] Stream was terminated due to error:"
,
sessionId
,
t
);
closeSession
();
}
@Override
public
void
onCompleted
()
{
log
.
info
(
"[{}] Stream was closed and completed successfully!"
,
sessionId
);
closeSession
();
}
private
void
closeSession
()
{
connected
=
false
;
if
(
edge
!=
null
)
{
try
{
sessionCloseListener
.
accept
(
edge
.
getId
());
}
catch
(
Exception
ignored
)
{
}
}
try
{
outputStream
.
onCompleted
();
}
catch
(
Exception
ignored
)
{
}
}
};
}
public
void
startSyncProcess
(
TenantId
tenantId
,
EdgeId
edgeId
,
boolean
fullSync
)
{
log
.
trace
(
"[{}][{}] Staring edge sync process"
,
tenantId
,
edgeId
);
syncCompleted
=
false
;
interruptGeneralProcessingOnSync
(
tenantId
,
edgeId
);
doSync
(
new
EdgeSyncCursor
(
ctx
,
edge
,
fullSync
));
}
private
void
doSync
(
EdgeSyncCursor
cursor
)
{
if
(
cursor
.
hasNext
())
{
log
.
info
(
"[{}][{}] starting sync process, cursor current idx = {}"
,
edge
.
getTenantId
(),
edge
.
getId
(),
cursor
.
getCurrentIdx
());
ListenableFuture
<
UUID
>
uuidListenableFuture
=
startProcessingEdgeEvents
(
cursor
.
getNext
());
Futures
.
addCallback
(
uuidListenableFuture
,
new
FutureCallback
<>()
{
@Override
public
void
onSuccess
(
@Nullable
UUID
result
)
{
doSync
(
cursor
);
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
error
(
"[{}][{}] Exception during sync process"
,
edge
.
getTenantId
(),
edge
.
getId
(),
t
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
else
{
DownlinkMsg
syncCompleteDownlinkMsg
=
DownlinkMsg
.
newBuilder
()
.
setDownlinkMsgId
(
EdgeUtils
.
nextPositiveInt
())
.
setSyncCompletedMsg
(
SyncCompletedMsg
.
newBuilder
().
build
())
.
build
();
Futures
.
addCallback
(
sendDownlinkMsgsPack
(
Collections
.
singletonList
(
syncCompleteDownlinkMsg
)),
new
FutureCallback
<
Void
>()
{
@Override
public
void
onSuccess
(
Void
result
)
{
syncCompleted
=
true
;
ctx
.
getClusterService
().
onEdgeEventUpdate
(
edge
.
getTenantId
(),
edge
.
getId
());
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
error
(
"[{}][{}] Exception during sending sync complete"
,
edge
.
getTenantId
(),
edge
.
getId
(),
t
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
}
private
void
onUplinkMsg
(
UplinkMsg
uplinkMsg
)
{
ListenableFuture
<
List
<
Void
>>
future
=
processUplinkMsg
(
uplinkMsg
);
Futures
.
addCallback
(
future
,
new
FutureCallback
<>()
{
@Override
public
void
onSuccess
(
@Nullable
List
<
Void
>
result
)
{
UplinkResponseMsg
uplinkResponseMsg
=
UplinkResponseMsg
.
newBuilder
()
.
setUplinkMsgId
(
uplinkMsg
.
getUplinkMsgId
())
.
setSuccess
(
true
).
build
();
sendDownlinkMsg
(
ResponseMsg
.
newBuilder
()
.
setUplinkResponseMsg
(
uplinkResponseMsg
)
.
build
());
}
@Override
public
void
onFailure
(
Throwable
t
)
{
String
errorMsg
=
EdgeUtils
.
createErrorMsgFromRootCauseAndStackTrace
(
t
);
UplinkResponseMsg
uplinkResponseMsg
=
UplinkResponseMsg
.
newBuilder
()
.
setUplinkMsgId
(
uplinkMsg
.
getUplinkMsgId
())
.
setSuccess
(
false
).
setErrorMsg
(
errorMsg
).
build
();
sendDownlinkMsg
(
ResponseMsg
.
newBuilder
()
.
setUplinkResponseMsg
(
uplinkResponseMsg
)
.
build
());
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
private
void
onDownlinkResponse
(
DownlinkResponseMsg
msg
)
{
try
{
if
(
msg
.
getSuccess
())
{
sessionState
.
getPendingMsgsMap
().
remove
(
msg
.
getDownlinkMsgId
());
log
.
debug
(
"[{}] Msg has been processed successfully!Msd Id: [{}], Msg: {}"
,
edge
.
getRoutingKey
(),
msg
.
getDownlinkMsgId
(),
msg
);
}
else
{
log
.
error
(
"[{}] Msg processing failed! Msd Id: [{}], Error msg: {}"
,
edge
.
getRoutingKey
(),
msg
.
getDownlinkMsgId
(),
msg
.
getErrorMsg
());
}
if
(
sessionState
.
getPendingMsgsMap
().
isEmpty
())
{
log
.
debug
(
"[{}] Pending msgs map is empty. Stopping current iteration"
,
edge
.
getRoutingKey
());
stopCurrentSendDownlinkMsgsTask
(
null
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}] Can't process downlink response message [{}]"
,
this
.
sessionId
,
msg
,
e
);
}
}
private
void
sendDownlinkMsg
(
ResponseMsg
downlinkMsg
)
{
log
.
trace
(
"[{}] Sending downlink msg [{}]"
,
this
.
sessionId
,
downlinkMsg
);
if
(
isConnected
())
{
downlinkMsgLock
.
lock
();
try
{
outputStream
.
onNext
(
downlinkMsg
);
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}] Failed to send downlink message [{}]"
,
this
.
sessionId
,
downlinkMsg
,
e
);
connected
=
false
;
sessionCloseListener
.
accept
(
edge
.
getId
());
}
finally
{
downlinkMsgLock
.
unlock
();
}
log
.
trace
(
"[{}] Response msg successfully sent [{}]"
,
this
.
sessionId
,
downlinkMsg
);
}
}
void
onConfigurationUpdate
(
Edge
edge
)
{
log
.
debug
(
"[{}] onConfigurationUpdate [{}]"
,
this
.
sessionId
,
edge
);
this
.
edge
=
edge
;
EdgeUpdateMsg
edgeConfig
=
EdgeUpdateMsg
.
newBuilder
()
.
setConfiguration
(
ctx
.
getEdgeMsgConstructor
().
constructEdgeConfiguration
(
edge
)).
build
();
ResponseMsg
edgeConfigMsg
=
ResponseMsg
.
newBuilder
()
.
setEdgeUpdateMsg
(
edgeConfig
)
.
build
();
sendDownlinkMsg
(
edgeConfigMsg
);
}
ListenableFuture
<
Void
>
processEdgeEvents
()
throws
Exception
{
SettableFuture
<
Void
>
result
=
SettableFuture
.
create
();
log
.
trace
(
"[{}] starting processing edge events"
,
this
.
sessionId
);
if
(
isConnected
()
&&
isSyncCompleted
())
{
Long
queueStartTs
=
getQueueStartTs
().
get
();
GeneralEdgeEventFetcher
fetcher
=
new
GeneralEdgeEventFetcher
(
queueStartTs
,
ctx
.
getEdgeEventService
());
ListenableFuture
<
UUID
>
ifOffsetFuture
=
startProcessingEdgeEvents
(
fetcher
);
Futures
.
addCallback
(
ifOffsetFuture
,
new
FutureCallback
<>()
{
@Override
public
void
onSuccess
(
@Nullable
UUID
ifOffset
)
{
if
(
ifOffset
!=
null
)
{
Long
newStartTs
=
Uuids
.
unixTimestamp
(
ifOffset
);
ListenableFuture
<
List
<
String
>>
updateFuture
=
updateQueueStartTs
(
newStartTs
);
Futures
.
addCallback
(
updateFuture
,
new
FutureCallback
<>()
{
@Override
public
void
onSuccess
(
@Nullable
List
<
String
>
list
)
{
log
.
debug
(
"[{}] queue offset was updated [{}][{}]"
,
sessionId
,
ifOffset
,
newStartTs
);
result
.
set
(
null
);
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
error
(
"[{}] Failed to update queue offset [{}]"
,
sessionId
,
ifOffset
,
t
);
result
.
setException
(
t
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
else
{
log
.
trace
(
"[{}] ifOffset is null. Skipping iteration without db update"
,
sessionId
);
result
.
set
(
null
);
}
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
error
(
"[{}] Failed to process events"
,
sessionId
,
t
);
result
.
setException
(
t
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
else
{
log
.
trace
(
"[{}] edge is not connected or sync is not completed. Skipping iteration"
,
sessionId
);
result
.
set
(
null
);
}
return
result
;
}
private
ListenableFuture
<
UUID
>
startProcessingEdgeEvents
(
EdgeEventFetcher
fetcher
)
{
SettableFuture
<
UUID
>
result
=
SettableFuture
.
create
();
PageLink
pageLink
=
fetcher
.
getPageLink
(
ctx
.
getEdgeEventStorageSettings
().
getMaxReadRecordsCount
());
processEdgeEvents
(
fetcher
,
pageLink
,
result
);
return
result
;
}
private
void
processEdgeEvents
(
EdgeEventFetcher
fetcher
,
PageLink
pageLink
,
SettableFuture
<
UUID
>
result
)
{
try
{
PageData
<
EdgeEvent
>
pageData
=
fetcher
.
fetchEdgeEvents
(
edge
.
getTenantId
(),
edge
,
pageLink
);
if
(
isConnected
()
&&
!
pageData
.
getData
().
isEmpty
())
{
log
.
trace
(
"[{}] [{}] event(s) are going to be processed."
,
this
.
sessionId
,
pageData
.
getData
().
size
());
List
<
DownlinkMsg
>
downlinkMsgsPack
=
convertToDownlinkMsgsPack
(
pageData
.
getData
());
Futures
.
addCallback
(
sendDownlinkMsgsPack
(
downlinkMsgsPack
),
new
FutureCallback
<
Void
>()
{
@Override
public
void
onSuccess
(
@Nullable
Void
tmp
)
{
if
(
isConnected
()
&&
pageData
.
hasNext
())
{
processEdgeEvents
(
fetcher
,
pageLink
.
nextPageLink
(),
result
);
}
else
{
UUID
ifOffset
=
pageData
.
getData
().
get
(
pageData
.
getData
().
size
()
-
1
).
getUuidId
();
result
.
set
(
ifOffset
);
}
}
@Override
public
void
onFailure
(
Throwable
t
)
{
log
.
error
(
"[{}] Failed to send downlink msgs pack"
,
sessionId
,
t
);
result
.
setException
(
t
);
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
else
{
log
.
trace
(
"[{}] no event(s) found. Stop processing edge events"
,
this
.
sessionId
);
result
.
set
(
null
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}] Failed to fetch edge events"
,
this
.
sessionId
,
e
);
result
.
setException
(
e
);
}
}
private
ListenableFuture
<
Void
>
sendDownlinkMsgsPack
(
List
<
DownlinkMsg
>
downlinkMsgsPack
)
{
interruptPreviousSendDownlinkMsgsTask
();
sessionState
.
setSendDownlinkMsgsFuture
(
SettableFuture
.
create
());
sessionState
.
getPendingMsgsMap
().
clear
();
downlinkMsgsPack
.
forEach
(
msg
->
sessionState
.
getPendingMsgsMap
().
put
(
msg
.
getDownlinkMsgId
(),
msg
));
scheduleDownlinkMsgsPackSend
(
1
);
return
sessionState
.
getSendDownlinkMsgsFuture
();
}
private
void
scheduleDownlinkMsgsPackSend
(
int
attempt
)
{
Runnable
sendDownlinkMsgsTask
=
()
->
{
try
{
if
(
isConnected
()
&&
sessionState
.
getPendingMsgsMap
().
values
().
size
()
>
0
)
{
List
<
DownlinkMsg
>
copy
=
new
ArrayList
<>(
sessionState
.
getPendingMsgsMap
().
values
());
if
(
attempt
>
1
)
{
log
.
warn
(
"[{}] Failed to deliver the batch: {}, attempt: {}"
,
this
.
sessionId
,
copy
,
attempt
);
}
log
.
trace
(
"[{}] [{}] downlink msg(s) are going to be send."
,
this
.
sessionId
,
copy
.
size
());
for
(
DownlinkMsg
downlinkMsg
:
copy
)
{
sendDownlinkMsg
(
ResponseMsg
.
newBuilder
()
.
setDownlinkMsg
(
downlinkMsg
)
.
build
());
}
if
(
attempt
<
MAX_DOWNLINK_ATTEMPTS
)
{
scheduleDownlinkMsgsPackSend
(
attempt
+
1
);
}
else
{
log
.
warn
(
"[{}] Failed to deliver the batch after {} attempts. Next messages are going to be discarded {}"
,
this
.
sessionId
,
MAX_DOWNLINK_ATTEMPTS
,
copy
);
stopCurrentSendDownlinkMsgsTask
(
null
);
}
}
else
{
stopCurrentSendDownlinkMsgsTask
(
null
);
}
}
catch
(
Exception
e
)
{
stopCurrentSendDownlinkMsgsTask
(
e
);
}
};
if
(
attempt
==
1
)
{
sendDownlinkExecutorService
.
submit
(
sendDownlinkMsgsTask
);
}
else
{
sessionState
.
setScheduledSendDownlinkTask
(
sendDownlinkExecutorService
.
schedule
(
sendDownlinkMsgsTask
,
ctx
.
getEdgeEventStorageSettings
().
getSleepIntervalBetweenBatches
(),
TimeUnit
.
MILLISECONDS
)
);
}
}
private
DownlinkMsg
convertToDownlinkMsg
(
EdgeEvent
edgeEvent
)
{
log
.
trace
(
"[{}][{}] converting edge event to downlink msg [{}]"
,
edge
.
getTenantId
(),
this
.
sessionId
,
edgeEvent
);
DownlinkMsg
downlinkMsg
=
null
;
try
{
switch
(
edgeEvent
.
getAction
())
{
case
UPDATED:
case
ADDED:
case
DELETED:
case
ASSIGNED_TO_EDGE:
case
UNASSIGNED_FROM_EDGE:
case
ALARM_ACK:
case
ALARM_CLEAR:
case
CREDENTIALS_UPDATED:
case
RELATION_ADD_OR_UPDATE:
case
RELATION_DELETED:
case
ASSIGNED_TO_CUSTOMER:
case
UNASSIGNED_FROM_CUSTOMER:
case
CREDENTIALS_REQUEST:
case
ENTITY_MERGE_REQUEST:
case
RPC_CALL:
downlinkMsg
=
convertEntityEventToDownlink
(
edgeEvent
);
log
.
trace
(
"[{}][{}] entity message processed [{}]"
,
edgeEvent
.
getTenantId
(),
this
.
sessionId
,
downlinkMsg
);
break
;
case
ATTRIBUTES_UPDATED:
case
POST_ATTRIBUTES:
case
ATTRIBUTES_DELETED:
case
TIMESERIES_UPDATED:
downlinkMsg
=
ctx
.
getTelemetryProcessor
().
convertTelemetryEventToDownlink
(
edgeEvent
);
break
;
default
:
log
.
warn
(
"[{}][{}] Unsupported action type [{}]"
,
edge
.
getTenantId
(),
this
.
sessionId
,
edgeEvent
.
getAction
());
}
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}][{}] Exception during converting edge event to downlink msg"
,
edge
.
getTenantId
(),
this
.
sessionId
,
e
);
}
return
downlinkMsg
;
}
private
List
<
DownlinkMsg
>
convertToDownlinkMsgsPack
(
List
<
EdgeEvent
>
edgeEvents
)
{
return
edgeEvents
.
stream
()
.
map
(
this
::
convertToDownlinkMsg
)
.
filter
(
Objects:
:
nonNull
)
.
collect
(
Collectors
.
toList
());
}
private
ListenableFuture
<
Long
>
getQueueStartTs
()
{
ListenableFuture
<
Optional
<
AttributeKvEntry
>>
future
=
ctx
.
getAttributesService
().
find
(
edge
.
getTenantId
(),
edge
.
getId
(),
DataConstants
.
SERVER_SCOPE
,
QUEUE_START_TS_ATTR_KEY
);
return
Futures
.
transform
(
future
,
attributeKvEntryOpt
->
{
if
(
attributeKvEntryOpt
!=
null
&&
attributeKvEntryOpt
.
isPresent
())
{
AttributeKvEntry
attributeKvEntry
=
attributeKvEntryOpt
.
get
();
return
attributeKvEntry
.
getLongValue
().
isPresent
()
?
attributeKvEntry
.
getLongValue
().
get
()
:
0L
;
}
else
{
return
0L
;
}
},
ctx
.
getGrpcCallbackExecutorService
());
}
private
ListenableFuture
<
List
<
String
>>
updateQueueStartTs
(
Long
newStartTs
)
{
log
.
trace
(
"[{}] updating QueueStartTs [{}][{}]"
,
this
.
sessionId
,
edge
.
getId
(),
newStartTs
);
List
<
AttributeKvEntry
>
attributes
=
Collections
.
singletonList
(
new
BaseAttributeKvEntry
(
new
LongDataEntry
(
QUEUE_START_TS_ATTR_KEY
,
newStartTs
),
System
.
currentTimeMillis
()));
return
ctx
.
getAttributesService
().
save
(
edge
.
getTenantId
(),
edge
.
getId
(),
DataConstants
.
SERVER_SCOPE
,
attributes
);
}
private
DownlinkMsg
convertEntityEventToDownlink
(
EdgeEvent
edgeEvent
)
{
log
.
trace
(
"Executing convertEntityEventToDownlink, edgeEvent [{}], action [{}]"
,
edgeEvent
,
edgeEvent
.
getAction
());
switch
(
edgeEvent
.
getType
())
{
case
EDGE:
return
ctx
.
getEdgeProcessor
().
convertEdgeEventToDownlink
(
edgeEvent
);
case
DEVICE:
return
ctx
.
getDeviceProcessor
().
convertDeviceEventToDownlink
(
edgeEvent
);
case
DEVICE_PROFILE:
return
ctx
.
getDeviceProfileProcessor
().
convertDeviceProfileEventToDownlink
(
edgeEvent
);
case
ASSET_PROFILE:
return
ctx
.
getAssetProfileProcessor
().
convertAssetProfileEventToDownlink
(
edgeEvent
);
case
ASSET:
return
ctx
.
getAssetProcessor
().
convertAssetEventToDownlink
(
edgeEvent
);
case
ENTITY_VIEW:
return
ctx
.
getEntityViewProcessor
().
convertEntityViewEventToDownlink
(
edgeEvent
);
case
DASHBOARD:
return
ctx
.
getDashboardProcessor
().
convertDashboardEventToDownlink
(
edgeEvent
);
case
CUSTOMER:
return
ctx
.
getCustomerProcessor
().
convertCustomerEventToDownlink
(
edgeEvent
);
case
RULE_CHAIN:
return
ctx
.
getRuleChainProcessor
().
convertRuleChainEventToDownlink
(
edgeEvent
);
case
RULE_CHAIN_METADATA:
return
ctx
.
getRuleChainProcessor
().
convertRuleChainMetadataEventToDownlink
(
edgeEvent
,
this
.
edgeVersion
);
case
ALARM:
return
ctx
.
getAlarmProcessor
().
convertAlarmEventToDownlink
(
edgeEvent
);
case
USER:
return
ctx
.
getUserProcessor
().
convertUserEventToDownlink
(
edgeEvent
);
case
RELATION:
return
ctx
.
getRelationProcessor
().
convertRelationEventToDownlink
(
edgeEvent
);
case
WIDGETS_BUNDLE:
return
ctx
.
getWidgetBundleProcessor
().
convertWidgetsBundleEventToDownlink
(
edgeEvent
);
case
WIDGET_TYPE:
return
ctx
.
getWidgetTypeProcessor
().
convertWidgetTypeEventToDownlink
(
edgeEvent
);
case
ADMIN_SETTINGS:
return
ctx
.
getAdminSettingsProcessor
().
convertAdminSettingsEventToDownlink
(
edgeEvent
);
case
OTA_PACKAGE:
return
ctx
.
getOtaPackageEdgeProcessor
().
convertOtaPackageEventToDownlink
(
edgeEvent
);
case
QUEUE:
return
ctx
.
getQueueEdgeProcessor
().
convertQueueEventToDownlink
(
edgeEvent
);
default
:
log
.
warn
(
"Unsupported edge event type [{}]"
,
edgeEvent
);
return
null
;
}
}
private
ListenableFuture
<
List
<
Void
>>
processUplinkMsg
(
UplinkMsg
uplinkMsg
)
{
List
<
ListenableFuture
<
Void
>>
result
=
new
ArrayList
<>();
try
{
if
(
uplinkMsg
.
getEntityDataCount
()
>
0
)
{
for
(
EntityDataProto
entityData
:
uplinkMsg
.
getEntityDataList
())
{
result
.
addAll
(
ctx
.
getTelemetryProcessor
().
processTelemetryFromEdge
(
edge
.
getTenantId
(),
entityData
));
}
}
if
(
uplinkMsg
.
getDeviceUpdateMsgCount
()
>
0
)
{
for
(
DeviceUpdateMsg
deviceUpdateMsg
:
uplinkMsg
.
getDeviceUpdateMsgList
())
{
result
.
add
(
ctx
.
getDeviceProcessor
().
processDeviceFromEdge
(
edge
.
getTenantId
(),
edge
,
deviceUpdateMsg
));
}
}
if
(
uplinkMsg
.
getDeviceCredentialsUpdateMsgCount
()
>
0
)
{
for
(
DeviceCredentialsUpdateMsg
deviceCredentialsUpdateMsg
:
uplinkMsg
.
getDeviceCredentialsUpdateMsgList
())
{
result
.
add
(
ctx
.
getDeviceProcessor
().
processDeviceCredentialsFromEdge
(
edge
.
getTenantId
(),
deviceCredentialsUpdateMsg
));
}
}
if
(
uplinkMsg
.
getAlarmUpdateMsgCount
()
>
0
)
{
for
(
AlarmUpdateMsg
alarmUpdateMsg
:
uplinkMsg
.
getAlarmUpdateMsgList
())
{
result
.
add
(
ctx
.
getAlarmProcessor
().
processAlarmFromEdge
(
edge
.
getTenantId
(),
alarmUpdateMsg
));
}
}
if
(
uplinkMsg
.
getRelationUpdateMsgCount
()
>
0
)
{
for
(
RelationUpdateMsg
relationUpdateMsg
:
uplinkMsg
.
getRelationUpdateMsgList
())
{
result
.
add
(
ctx
.
getRelationProcessor
().
processRelationFromEdge
(
edge
.
getTenantId
(),
relationUpdateMsg
));
}
}
if
(
uplinkMsg
.
getRuleChainMetadataRequestMsgCount
()
>
0
)
{
for
(
RuleChainMetadataRequestMsg
ruleChainMetadataRequestMsg
:
uplinkMsg
.
getRuleChainMetadataRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processRuleChainMetadataRequestMsg
(
edge
.
getTenantId
(),
edge
,
ruleChainMetadataRequestMsg
));
}
}
if
(
uplinkMsg
.
getAttributesRequestMsgCount
()
>
0
)
{
for
(
AttributesRequestMsg
attributesRequestMsg
:
uplinkMsg
.
getAttributesRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processAttributesRequestMsg
(
edge
.
getTenantId
(),
edge
,
attributesRequestMsg
));
}
}
if
(
uplinkMsg
.
getRelationRequestMsgCount
()
>
0
)
{
for
(
RelationRequestMsg
relationRequestMsg
:
uplinkMsg
.
getRelationRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processRelationRequestMsg
(
edge
.
getTenantId
(),
edge
,
relationRequestMsg
));
}
}
if
(
uplinkMsg
.
getUserCredentialsRequestMsgCount
()
>
0
)
{
for
(
UserCredentialsRequestMsg
userCredentialsRequestMsg
:
uplinkMsg
.
getUserCredentialsRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processUserCredentialsRequestMsg
(
edge
.
getTenantId
(),
edge
,
userCredentialsRequestMsg
));
}
}
if
(
uplinkMsg
.
getDeviceCredentialsRequestMsgCount
()
>
0
)
{
for
(
DeviceCredentialsRequestMsg
deviceCredentialsRequestMsg
:
uplinkMsg
.
getDeviceCredentialsRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processDeviceCredentialsRequestMsg
(
edge
.
getTenantId
(),
edge
,
deviceCredentialsRequestMsg
));
}
}
if
(
uplinkMsg
.
getDeviceRpcCallMsgCount
()
>
0
)
{
for
(
DeviceRpcCallMsg
deviceRpcCallMsg
:
uplinkMsg
.
getDeviceRpcCallMsgList
())
{
result
.
add
(
ctx
.
getDeviceProcessor
().
processDeviceRpcCallFromEdge
(
edge
.
getTenantId
(),
edge
,
deviceRpcCallMsg
));
}
}
if
(
uplinkMsg
.
getWidgetBundleTypesRequestMsgCount
()
>
0
)
{
for
(
WidgetBundleTypesRequestMsg
widgetBundleTypesRequestMsg
:
uplinkMsg
.
getWidgetBundleTypesRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processWidgetBundleTypesRequestMsg
(
edge
.
getTenantId
(),
edge
,
widgetBundleTypesRequestMsg
));
}
}
if
(
uplinkMsg
.
getEntityViewsRequestMsgCount
()
>
0
)
{
for
(
EntityViewsRequestMsg
entityViewRequestMsg
:
uplinkMsg
.
getEntityViewsRequestMsgList
())
{
result
.
add
(
ctx
.
getEdgeRequestsService
().
processEntityViewsRequestMsg
(
edge
.
getTenantId
(),
edge
,
entityViewRequestMsg
));
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}] Can't process uplink msg [{}]"
,
this
.
sessionId
,
uplinkMsg
,
e
);
return
Futures
.
immediateFailedFuture
(
e
);
}
return
Futures
.
allAsList
(
result
);
}
private
ConnectResponseMsg
processConnect
(
ConnectRequestMsg
request
)
{
log
.
trace
(
"[{}] processConnect [{}]"
,
this
.
sessionId
,
request
);
Optional
<
Edge
>
optional
=
ctx
.
getEdgeService
().
findEdgeByRoutingKey
(
TenantId
.
SYS_TENANT_ID
,
request
.
getEdgeRoutingKey
());
if
(
optional
.
isPresent
())
{
edge
=
optional
.
get
();
try
{
if
(
edge
.
getSecret
().
equals
(
request
.
getEdgeSecret
()))
{
sessionOpenListener
.
accept
(
edge
.
getId
(),
this
);
this
.
edgeVersion
=
request
.
getEdgeVersion
();
return
ConnectResponseMsg
.
newBuilder
()
.
setResponseCode
(
ConnectResponseCode
.
ACCEPTED
)
.
setErrorMsg
(
""
)
.
setConfiguration
(
ctx
.
getEdgeMsgConstructor
().
constructEdgeConfiguration
(
edge
)).
build
();
}
return
ConnectResponseMsg
.
newBuilder
()
.
setResponseCode
(
ConnectResponseCode
.
BAD_CREDENTIALS
)
.
setErrorMsg
(
"Failed to validate the edge!"
)
.
setConfiguration
(
EdgeConfiguration
.
getDefaultInstance
()).
build
();
}
catch
(
Exception
e
)
{
log
.
error
(
"[{}] Failed to process edge connection!"
,
request
.
getEdgeRoutingKey
(),
e
);
return
ConnectResponseMsg
.
newBuilder
()
.
setResponseCode
(
ConnectResponseCode
.
SERVER_UNAVAILABLE
)
.
setErrorMsg
(
"Failed to process edge connection!"
)
.
setConfiguration
(
EdgeConfiguration
.
getDefaultInstance
()).
build
();
}
}
return
ConnectResponseMsg
.
newBuilder
()
.
setResponseCode
(
ConnectResponseCode
.
BAD_CREDENTIALS
)
.
setErrorMsg
(
"Failed to find the edge! Routing key: "
+
request
.
getEdgeRoutingKey
())
.
setConfiguration
(
EdgeConfiguration
.
getDefaultInstance
()).
build
();
}
@Override
public
void
close
()
{
log
.
debug
(
"[{}] Closing session"
,
sessionId
);
connected
=
false
;
try
{
outputStream
.
onCompleted
();
}
catch
(
Exception
e
)
{
log
.
debug
(
"[{}] Failed to close output stream: {}"
,
sessionId
,
e
.
getMessage
());
}
}
private
void
interruptPreviousSendDownlinkMsgsTask
()
{
String
msg
=
String
.
format
(
"[%s] Previous send downlink future was not properly completed, stopping it now!"
,
this
.
sessionId
);
stopCurrentSendDownlinkMsgsTask
(
new
RuntimeException
(
msg
));
}
private
void
interruptGeneralProcessingOnSync
(
TenantId
tenantId
,
EdgeId
edgeId
)
{
String
msg
=
String
.
format
(
"[%s][%s] Sync process started. General processing interrupted!"
,
tenantId
,
edgeId
);
stopCurrentSendDownlinkMsgsTask
(
new
RuntimeException
(
msg
));
}
public
void
stopCurrentSendDownlinkMsgsTask
(
Exception
e
)
{
if
(
sessionState
.
getSendDownlinkMsgsFuture
()
!=
null
&&
!
sessionState
.
getSendDownlinkMsgsFuture
().
isDone
())
{
if
(
e
!=
null
)
{
log
.
warn
(
e
.
getMessage
(),
e
);
sessionState
.
getSendDownlinkMsgsFuture
().
setException
(
e
);
}
else
{
sessionState
.
getSendDownlinkMsgsFuture
().
set
(
null
);
}
}
if
(
sessionState
.
getScheduledSendDownlinkTask
()
!=
null
)
{
sessionState
.
getScheduledSendDownlinkTask
().
cancel
(
true
);
}
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeRpcService.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.common.data.id.EdgeId
;
import
org.thingsboard.server.common.data.id.TenantId
;
import
org.thingsboard.server.common.msg.edge.EdgeSessionMsg
;
import
org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse
;
import
org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest
;
import
java.util.function.Consumer
;
public
interface
EdgeRpcService
{
void
onToEdgeSessionMsg
(
TenantId
tenantId
,
EdgeSessionMsg
msg
);
void
updateEdge
(
TenantId
tenantId
,
Edge
edge
);
void
deleteEdge
(
TenantId
tenantId
,
EdgeId
edgeId
);
void
processSyncRequest
(
ToEdgeSyncRequest
request
,
Consumer
<
FromEdgeSyncResponse
>
responseConsumer
);
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSessionState.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
com.google.common.util.concurrent.SettableFuture
;
import
lombok.Data
;
import
org.thingsboard.server.gen.edge.v1.DownlinkMsg
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
import
java.util.concurrent.ScheduledFuture
;
@Data
public
class
EdgeSessionState
{
private
final
Map
<
Integer
,
DownlinkMsg
>
pendingMsgsMap
=
Collections
.
synchronizedMap
(
new
LinkedHashMap
<>());
private
SettableFuture
<
Void
>
sendDownlinkMsgsFuture
;
private
ScheduledFuture
<?>
scheduledSendDownlinkTask
;
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.common.data.id.EntityId
;
import
org.thingsboard.server.service.edge.EdgeContextComponent
;
import
org.thingsboard.server.service.edge.rpc.fetch.AdminSettingsEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.AssetProfilesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.AssetsEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.CustomerEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.CustomerUsersEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.DashboardsEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.DevicesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.EntityViewsEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.OtaPackagesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.QueuesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.RuleChainsEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.SystemWidgetsBundlesEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.TenantAdminUsersEdgeEventFetcher
;
import
org.thingsboard.server.service.edge.rpc.fetch.TenantWidgetsBundlesEdgeEventFetcher
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.NoSuchElementException
;
public
class
EdgeSyncCursor
{
List
<
EdgeEventFetcher
>
fetchers
=
new
LinkedList
<>();
int
currentIdx
=
0
;
public
EdgeSyncCursor
(
EdgeContextComponent
ctx
,
Edge
edge
,
boolean
fullSync
)
{
if
(
fullSync
)
{
fetchers
.
add
(
new
QueuesEdgeEventFetcher
(
ctx
.
getQueueService
()));
fetchers
.
add
(
new
RuleChainsEdgeEventFetcher
(
ctx
.
getRuleChainService
()));
fetchers
.
add
(
new
AdminSettingsEdgeEventFetcher
(
ctx
.
getAdminSettingsService
(),
ctx
.
getFreemarkerConfig
()));
fetchers
.
add
(
new
DeviceProfilesEdgeEventFetcher
(
ctx
.
getDeviceProfileService
()));
fetchers
.
add
(
new
AssetProfilesEdgeEventFetcher
(
ctx
.
getAssetProfileService
()));
fetchers
.
add
(
new
TenantAdminUsersEdgeEventFetcher
(
ctx
.
getUserService
()));
if
(
edge
.
getCustomerId
()
!=
null
&&
!
EntityId
.
NULL_UUID
.
equals
(
edge
.
getCustomerId
().
getId
()))
{
fetchers
.
add
(
new
CustomerEdgeEventFetcher
());
fetchers
.
add
(
new
CustomerUsersEdgeEventFetcher
(
ctx
.
getUserService
(),
edge
.
getCustomerId
()));
}
}
fetchers
.
add
(
new
DevicesEdgeEventFetcher
(
ctx
.
getDeviceService
()));
fetchers
.
add
(
new
AssetsEdgeEventFetcher
(
ctx
.
getAssetService
()));
fetchers
.
add
(
new
EntityViewsEdgeEventFetcher
(
ctx
.
getEntityViewService
()));
fetchers
.
add
(
new
DashboardsEdgeEventFetcher
(
ctx
.
getDashboardService
()));
if
(
fullSync
)
{
fetchers
.
add
(
new
SystemWidgetsBundlesEdgeEventFetcher
(
ctx
.
getWidgetsBundleService
()));
fetchers
.
add
(
new
TenantWidgetsBundlesEdgeEventFetcher
(
ctx
.
getWidgetsBundleService
()));
fetchers
.
add
(
new
OtaPackagesEdgeEventFetcher
(
ctx
.
getOtaPackageService
()));
}
}
public
boolean
hasNext
()
{
return
fetchers
.
size
()
>
currentIdx
;
}
public
EdgeEventFetcher
getNext
()
{
if
(!
hasNext
())
{
throw
new
NoSuchElementException
();
}
EdgeEventFetcher
edgeEventFetcher
=
fetchers
.
get
(
currentIdx
);
currentIdx
++;
return
edgeEventFetcher
;
}
public
int
getCurrentIdx
()
{
return
currentIdx
;
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.AdminSettings
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
AdminSettingsMsgConstructor
{
public
AdminSettingsUpdateMsg
constructAdminSettingsUpdateMsg
(
AdminSettings
adminSettings
)
{
AdminSettingsUpdateMsg
.
Builder
builder
=
AdminSettingsUpdateMsg
.
newBuilder
()
.
setKey
(
adminSettings
.
getKey
())
.
setJsonValue
(
JacksonUtil
.
toString
(
adminSettings
.
getJsonValue
()));
if
(
adminSettings
.
getId
()
!=
null
)
{
builder
.
setIsSystem
(
true
);
}
return
builder
.
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.alarm.Alarm
;
import
org.thingsboard.server.common.data.id.AssetId
;
import
org.thingsboard.server.common.data.id.DeviceId
;
import
org.thingsboard.server.common.data.id.EntityViewId
;
import
org.thingsboard.server.common.data.id.TenantId
;
import
org.thingsboard.server.dao.asset.AssetService
;
import
org.thingsboard.server.dao.device.DeviceService
;
import
org.thingsboard.server.dao.entityview.EntityViewService
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
AlarmMsgConstructor
{
@Autowired
private
DeviceService
deviceService
;
@Autowired
private
AssetService
assetService
;
@Autowired
private
EntityViewService
entityViewService
;
public
AlarmUpdateMsg
constructAlarmUpdatedMsg
(
TenantId
tenantId
,
UpdateMsgType
msgType
,
Alarm
alarm
)
{
String
entityName
=
null
;
switch
(
alarm
.
getOriginator
().
getEntityType
())
{
case
DEVICE:
entityName
=
deviceService
.
findDeviceById
(
tenantId
,
new
DeviceId
(
alarm
.
getOriginator
().
getId
())).
getName
();
break
;
case
ASSET:
entityName
=
assetService
.
findAssetById
(
tenantId
,
new
AssetId
(
alarm
.
getOriginator
().
getId
())).
getName
();
break
;
case
ENTITY_VIEW:
entityName
=
entityViewService
.
findEntityViewById
(
tenantId
,
new
EntityViewId
(
alarm
.
getOriginator
().
getId
())).
getName
();
break
;
}
AlarmUpdateMsg
.
Builder
builder
=
AlarmUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
alarm
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
alarm
.
getId
().
getId
().
getLeastSignificantBits
())
.
setName
(
alarm
.
getName
())
.
setType
(
alarm
.
getType
())
.
setOriginatorName
(
entityName
)
.
setOriginatorType
(
alarm
.
getOriginator
().
getEntityType
().
name
())
.
setSeverity
(
alarm
.
getSeverity
().
name
())
.
setStatus
(
alarm
.
getStatus
().
name
())
.
setStartTs
(
alarm
.
getStartTs
())
.
setEndTs
(
alarm
.
getEndTs
())
.
setAckTs
(
alarm
.
getAckTs
())
.
setClearTs
(
alarm
.
getClearTs
())
.
setDetails
(
JacksonUtil
.
toString
(
alarm
.
getDetails
()))
.
setPropagate
(
alarm
.
isPropagate
())
.
setPropagateToOwner
(
alarm
.
isPropagateToOwner
())
.
setPropagateToTenant
(
alarm
.
isPropagateToTenant
());
return
builder
.
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.asset.Asset
;
import
org.thingsboard.server.common.data.id.AssetId
;
import
org.thingsboard.server.gen.edge.v1.AssetUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
AssetMsgConstructor
{
public
AssetUpdateMsg
constructAssetUpdatedMsg
(
UpdateMsgType
msgType
,
Asset
asset
)
{
AssetUpdateMsg
.
Builder
builder
=
AssetUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
asset
.
getUuidId
().
getMostSignificantBits
())
.
setIdLSB
(
asset
.
getUuidId
().
getLeastSignificantBits
())
.
setName
(
asset
.
getName
())
.
setType
(
asset
.
getType
());
if
(
asset
.
getLabel
()
!=
null
)
{
builder
.
setLabel
(
asset
.
getLabel
());
}
if
(
asset
.
getCustomerId
()
!=
null
)
{
builder
.
setCustomerIdMSB
(
asset
.
getCustomerId
().
getId
().
getMostSignificantBits
());
builder
.
setCustomerIdLSB
(
asset
.
getCustomerId
().
getId
().
getLeastSignificantBits
());
}
if
(
asset
.
getAssetProfileId
()
!=
null
)
{
builder
.
setAssetProfileIdMSB
(
asset
.
getAssetProfileId
().
getId
().
getMostSignificantBits
());
builder
.
setAssetProfileIdLSB
(
asset
.
getAssetProfileId
().
getId
().
getLeastSignificantBits
());
}
if
(
asset
.
getAdditionalInfo
()
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
asset
.
getAdditionalInfo
()));
}
return
builder
.
build
();
}
public
AssetUpdateMsg
constructAssetDeleteMsg
(
AssetId
assetId
)
{
return
AssetUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
assetId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
assetId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetProfileMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
com.google.protobuf.ByteString
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.asset.AssetProfile
;
import
org.thingsboard.server.common.data.id.AssetProfileId
;
import
org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
import
java.nio.charset.StandardCharsets
;
@Component
@TbCoreComponent
public
class
AssetProfileMsgConstructor
{
public
AssetProfileUpdateMsg
constructAssetProfileUpdatedMsg
(
UpdateMsgType
msgType
,
AssetProfile
assetProfile
)
{
AssetProfileUpdateMsg
.
Builder
builder
=
AssetProfileUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
assetProfile
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
assetProfile
.
getId
().
getId
().
getLeastSignificantBits
())
.
setName
(
assetProfile
.
getName
())
.
setDefault
(
assetProfile
.
isDefault
());
if
(
assetProfile
.
getDefaultDashboardId
()
!=
null
)
{
builder
.
setDefaultDashboardIdMSB
(
assetProfile
.
getDefaultDashboardId
().
getId
().
getMostSignificantBits
())
.
setDefaultDashboardIdLSB
(
assetProfile
.
getDefaultDashboardId
().
getId
().
getLeastSignificantBits
());
}
if
(
assetProfile
.
getDefaultQueueName
()
!=
null
)
{
builder
.
setDefaultQueueName
(
assetProfile
.
getDefaultQueueName
());
}
if
(
assetProfile
.
getDescription
()
!=
null
)
{
builder
.
setDescription
(
assetProfile
.
getDescription
());
}
if
(
assetProfile
.
getImage
()
!=
null
)
{
builder
.
setImage
(
ByteString
.
copyFrom
(
assetProfile
.
getImage
().
getBytes
(
StandardCharsets
.
UTF_8
)));
}
return
builder
.
build
();
}
public
AssetProfileUpdateMsg
constructAssetProfileDeleteMsg
(
AssetProfileId
assetProfileId
)
{
return
AssetProfileUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
assetProfileId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
assetProfileId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.Customer
;
import
org.thingsboard.server.common.data.id.CustomerId
;
import
org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
CustomerMsgConstructor
{
public
CustomerUpdateMsg
constructCustomerUpdatedMsg
(
UpdateMsgType
msgType
,
Customer
customer
)
{
CustomerUpdateMsg
.
Builder
builder
=
CustomerUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
customer
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
customer
.
getId
().
getId
().
getLeastSignificantBits
())
.
setTitle
(
customer
.
getTitle
());
if
(
customer
.
getCountry
()
!=
null
)
{
builder
.
setCountry
(
customer
.
getCountry
());
}
if
(
customer
.
getState
()
!=
null
)
{
builder
.
setState
(
customer
.
getState
());
}
if
(
customer
.
getCity
()
!=
null
)
{
builder
.
setCity
(
customer
.
getCity
());
}
if
(
customer
.
getAddress
()
!=
null
)
{
builder
.
setAddress
(
customer
.
getAddress
());
}
if
(
customer
.
getAddress2
()
!=
null
)
{
builder
.
setAddress2
(
customer
.
getAddress2
());
}
if
(
customer
.
getZip
()
!=
null
)
{
builder
.
setZip
(
customer
.
getZip
());
}
if
(
customer
.
getPhone
()
!=
null
)
{
builder
.
setPhone
(
customer
.
getPhone
());
}
if
(
customer
.
getEmail
()
!=
null
)
{
builder
.
setEmail
(
customer
.
getEmail
());
}
if
(
customer
.
getAdditionalInfo
()
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
customer
.
getAdditionalInfo
()));
}
return
builder
.
build
();
}
public
CustomerUpdateMsg
constructCustomerDeleteMsg
(
CustomerId
customerId
)
{
return
CustomerUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
customerId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
customerId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.Dashboard
;
import
org.thingsboard.server.common.data.id.DashboardId
;
import
org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
DashboardMsgConstructor
{
public
DashboardUpdateMsg
constructDashboardUpdatedMsg
(
UpdateMsgType
msgType
,
Dashboard
dashboard
)
{
DashboardUpdateMsg
.
Builder
builder
=
DashboardUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
dashboard
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
dashboard
.
getId
().
getId
().
getLeastSignificantBits
())
.
setTitle
(
dashboard
.
getTitle
())
.
setConfiguration
(
JacksonUtil
.
toString
(
dashboard
.
getConfiguration
()));
if
(
dashboard
.
getAssignedCustomers
()
!=
null
)
{
builder
.
setAssignedCustomers
(
JacksonUtil
.
toString
(
dashboard
.
getAssignedCustomers
()));
}
return
builder
.
build
();
}
public
DashboardUpdateMsg
constructDashboardDeleteMsg
(
DashboardId
dashboardId
)
{
return
DashboardUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
dashboardId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
dashboardId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.google.protobuf.ByteString
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.Device
;
import
org.thingsboard.server.common.data.id.DeviceId
;
import
org.thingsboard.server.common.data.security.DeviceCredentials
;
import
org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg
;
import
org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.RpcRequestMsg
;
import
org.thingsboard.server.gen.edge.v1.RpcResponseMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.DataDecodingEncodingService
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
import
java.util.UUID
;
@Component
@TbCoreComponent
public
class
DeviceMsgConstructor
{
@Autowired
private
DataDecodingEncodingService
dataDecodingEncodingService
;
public
DeviceUpdateMsg
constructDeviceUpdatedMsg
(
UpdateMsgType
msgType
,
Device
device
,
String
conflictName
)
{
DeviceUpdateMsg
.
Builder
builder
=
DeviceUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
device
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
device
.
getId
().
getId
().
getLeastSignificantBits
())
.
setName
(
device
.
getName
())
.
setType
(
device
.
getType
());
if
(
device
.
getLabel
()
!=
null
)
{
builder
.
setLabel
(
device
.
getLabel
());
}
if
(
device
.
getCustomerId
()
!=
null
)
{
builder
.
setCustomerIdMSB
(
device
.
getCustomerId
().
getId
().
getMostSignificantBits
());
builder
.
setCustomerIdLSB
(
device
.
getCustomerId
().
getId
().
getLeastSignificantBits
());
}
if
(
device
.
getDeviceProfileId
()
!=
null
)
{
builder
.
setDeviceProfileIdMSB
(
device
.
getDeviceProfileId
().
getId
().
getMostSignificantBits
());
builder
.
setDeviceProfileIdLSB
(
device
.
getDeviceProfileId
().
getId
().
getLeastSignificantBits
());
}
if
(
device
.
getAdditionalInfo
()
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
device
.
getAdditionalInfo
()));
}
if
(
device
.
getFirmwareId
()
!=
null
)
{
builder
.
setFirmwareIdMSB
(
device
.
getFirmwareId
().
getId
().
getMostSignificantBits
())
.
setFirmwareIdLSB
(
device
.
getFirmwareId
().
getId
().
getLeastSignificantBits
());
}
if
(
conflictName
!=
null
)
{
builder
.
setConflictName
(
conflictName
);
}
if
(
device
.
getDeviceData
()
!=
null
)
{
builder
.
setDeviceDataBytes
(
ByteString
.
copyFrom
(
dataDecodingEncodingService
.
encode
(
device
.
getDeviceData
())));
}
return
builder
.
build
();
}
public
DeviceCredentialsUpdateMsg
constructDeviceCredentialsUpdatedMsg
(
DeviceCredentials
deviceCredentials
)
{
DeviceCredentialsUpdateMsg
.
Builder
builder
=
DeviceCredentialsUpdateMsg
.
newBuilder
()
.
setDeviceIdMSB
(
deviceCredentials
.
getDeviceId
().
getId
().
getMostSignificantBits
())
.
setDeviceIdLSB
(
deviceCredentials
.
getDeviceId
().
getId
().
getLeastSignificantBits
());
if
(
deviceCredentials
.
getCredentialsType
()
!=
null
)
{
builder
.
setCredentialsType
(
deviceCredentials
.
getCredentialsType
().
name
())
.
setCredentialsId
(
deviceCredentials
.
getCredentialsId
());
}
if
(
deviceCredentials
.
getCredentialsValue
()
!=
null
)
{
builder
.
setCredentialsValue
(
deviceCredentials
.
getCredentialsValue
());
}
return
builder
.
build
();
}
public
DeviceUpdateMsg
constructDeviceDeleteMsg
(
DeviceId
deviceId
)
{
return
DeviceUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
deviceId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
deviceId
.
getId
().
getLeastSignificantBits
()).
build
();
}
public
DeviceRpcCallMsg
constructDeviceRpcCallMsg
(
UUID
deviceId
,
JsonNode
body
)
{
DeviceRpcCallMsg
.
Builder
builder
=
constructDeviceRpcMsg
(
deviceId
,
body
);
if
(
body
.
has
(
"error"
)
||
body
.
has
(
"response"
))
{
RpcResponseMsg
.
Builder
responseBuilder
=
RpcResponseMsg
.
newBuilder
();
if
(
body
.
has
(
"error"
))
{
responseBuilder
.
setError
(
body
.
get
(
"error"
).
asText
());
}
else
{
responseBuilder
.
setResponse
(
body
.
get
(
"response"
).
asText
());
}
builder
.
setResponseMsg
(
responseBuilder
.
build
());
}
else
{
RpcRequestMsg
.
Builder
requestBuilder
=
RpcRequestMsg
.
newBuilder
();
requestBuilder
.
setMethod
(
body
.
get
(
"method"
).
asText
());
requestBuilder
.
setParams
(
body
.
get
(
"params"
).
asText
());
builder
.
setRequestMsg
(
requestBuilder
.
build
());
}
return
builder
.
build
();
}
private
DeviceRpcCallMsg
.
Builder
constructDeviceRpcMsg
(
UUID
deviceId
,
JsonNode
body
)
{
DeviceRpcCallMsg
.
Builder
builder
=
DeviceRpcCallMsg
.
newBuilder
()
.
setDeviceIdMSB
(
deviceId
.
getMostSignificantBits
())
.
setDeviceIdLSB
(
deviceId
.
getLeastSignificantBits
())
.
setRequestId
(
body
.
get
(
"requestId"
).
asInt
());
if
(
body
.
get
(
"oneway"
)
!=
null
)
{
builder
.
setOneway
(
body
.
get
(
"oneway"
).
asBoolean
());
}
if
(
body
.
get
(
"requestUUID"
)
!=
null
)
{
UUID
requestUUID
=
UUID
.
fromString
(
body
.
get
(
"requestUUID"
).
asText
());
builder
.
setRequestUuidMSB
(
requestUUID
.
getMostSignificantBits
())
.
setRequestUuidLSB
(
requestUUID
.
getLeastSignificantBits
());
}
if
(
body
.
get
(
"expirationTime"
)
!=
null
)
{
builder
.
setExpirationTime
(
body
.
get
(
"expirationTime"
).
asLong
());
}
if
(
body
.
get
(
"persisted"
)
!=
null
)
{
builder
.
setPersisted
(
body
.
get
(
"persisted"
).
asBoolean
());
}
if
(
body
.
get
(
"retries"
)
!=
null
)
{
builder
.
setRetries
(
body
.
get
(
"retries"
).
asInt
());
}
if
(
body
.
get
(
"additionalInfo"
)
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
body
.
get
(
"additionalInfo"
)));
}
if
(
body
.
get
(
"serviceId"
)
!=
null
)
{
builder
.
setServiceId
(
body
.
get
(
"serviceId"
).
asText
());
}
if
(
body
.
get
(
"sessionId"
)
!=
null
)
{
builder
.
setSessionId
(
body
.
get
(
"sessionId"
).
asText
());
}
return
builder
;
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceProfileMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
com.google.protobuf.ByteString
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.DeviceProfile
;
import
org.thingsboard.server.common.data.id.DeviceProfileId
;
import
org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.DataDecodingEncodingService
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
import
java.nio.charset.StandardCharsets
;
@Component
@TbCoreComponent
public
class
DeviceProfileMsgConstructor
{
@Autowired
private
DataDecodingEncodingService
dataDecodingEncodingService
;
public
DeviceProfileUpdateMsg
constructDeviceProfileUpdatedMsg
(
UpdateMsgType
msgType
,
DeviceProfile
deviceProfile
)
{
DeviceProfileUpdateMsg
.
Builder
builder
=
DeviceProfileUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
deviceProfile
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
deviceProfile
.
getId
().
getId
().
getLeastSignificantBits
())
.
setName
(
deviceProfile
.
getName
())
.
setDefault
(
deviceProfile
.
isDefault
())
.
setType
(
deviceProfile
.
getType
().
name
())
.
setProfileDataBytes
(
ByteString
.
copyFrom
(
dataDecodingEncodingService
.
encode
(
deviceProfile
.
getProfileData
())));
if
(
deviceProfile
.
getDefaultQueueName
()
!=
null
)
{
builder
.
setDefaultQueueName
(
deviceProfile
.
getDefaultQueueName
());
}
if
(
deviceProfile
.
getDescription
()
!=
null
)
{
builder
.
setDescription
(
deviceProfile
.
getDescription
());
}
if
(
deviceProfile
.
getTransportType
()
!=
null
)
{
builder
.
setTransportType
(
deviceProfile
.
getTransportType
().
name
());
}
if
(
deviceProfile
.
getProvisionType
()
!=
null
)
{
builder
.
setProvisionType
(
deviceProfile
.
getProvisionType
().
name
());
}
if
(
deviceProfile
.
getProvisionDeviceKey
()
!=
null
)
{
builder
.
setProvisionDeviceKey
(
deviceProfile
.
getProvisionDeviceKey
());
}
if
(
deviceProfile
.
getImage
()
!=
null
)
{
builder
.
setImage
(
ByteString
.
copyFrom
(
deviceProfile
.
getImage
().
getBytes
(
StandardCharsets
.
UTF_8
)));
}
if
(
deviceProfile
.
getFirmwareId
()
!=
null
)
{
builder
.
setFirmwareIdMSB
(
deviceProfile
.
getFirmwareId
().
getId
().
getMostSignificantBits
())
.
setFirmwareIdLSB
(
deviceProfile
.
getFirmwareId
().
getId
().
getLeastSignificantBits
());
}
return
builder
.
build
();
}
public
DeviceProfileUpdateMsg
constructDeviceProfileDeleteMsg
(
DeviceProfileId
deviceProfileId
)
{
return
DeviceProfileUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
deviceProfileId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
deviceProfileId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EdgeMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.edge.Edge
;
import
org.thingsboard.server.gen.edge.v1.EdgeConfiguration
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
EdgeMsgConstructor
{
public
EdgeConfiguration
constructEdgeConfiguration
(
Edge
edge
)
{
EdgeConfiguration
.
Builder
builder
=
EdgeConfiguration
.
newBuilder
()
.
setEdgeIdMSB
(
edge
.
getId
().
getId
().
getMostSignificantBits
())
.
setEdgeIdLSB
(
edge
.
getId
().
getId
().
getLeastSignificantBits
())
.
setTenantIdMSB
(
edge
.
getTenantId
().
getId
().
getMostSignificantBits
())
.
setTenantIdLSB
(
edge
.
getTenantId
().
getId
().
getLeastSignificantBits
())
.
setName
(
edge
.
getName
())
.
setType
(
edge
.
getType
())
.
setRoutingKey
(
edge
.
getRoutingKey
())
.
setSecret
(
edge
.
getSecret
())
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
edge
.
getAdditionalInfo
()))
.
setCloudType
(
"CE"
);
if
(
edge
.
getCustomerId
()
!=
null
)
{
builder
.
setCustomerIdMSB
(
edge
.
getCustomerId
().
getId
().
getMostSignificantBits
())
.
setCustomerIdLSB
(
edge
.
getCustomerId
().
getId
().
getLeastSignificantBits
());
}
return
builder
.
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
com.google.gson.Gson
;
import
com.google.gson.JsonArray
;
import
com.google.gson.JsonElement
;
import
com.google.gson.JsonObject
;
import
com.google.gson.JsonPrimitive
;
import
com.google.gson.reflect.TypeToken
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.DataConstants
;
import
org.thingsboard.server.common.data.StringUtils
;
import
org.thingsboard.server.common.data.edge.EdgeEventActionType
;
import
org.thingsboard.server.common.data.id.EntityId
;
import
org.thingsboard.server.common.transport.adaptor.JsonConverter
;
import
org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg
;
import
org.thingsboard.server.gen.edge.v1.EntityDataProto
;
import
org.thingsboard.server.gen.transport.TransportProtos
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
import
java.util.List
;
@Component
@Slf4j
@TbCoreComponent
public
class
EntityDataMsgConstructor
{
public
EntityDataProto
constructEntityDataMsg
(
EntityId
entityId
,
EdgeEventActionType
actionType
,
JsonElement
entityData
)
{
EntityDataProto
.
Builder
builder
=
EntityDataProto
.
newBuilder
()
.
setEntityIdMSB
(
entityId
.
getId
().
getMostSignificantBits
())
.
setEntityIdLSB
(
entityId
.
getId
().
getLeastSignificantBits
())
.
setEntityType
(
entityId
.
getEntityType
().
name
());
switch
(
actionType
)
{
case
TIMESERIES_UPDATED:
try
{
JsonObject
data
=
entityData
.
getAsJsonObject
();
long
ts
;
if
(
data
.
get
(
"ts"
)
!=
null
&&
!
data
.
get
(
"ts"
).
isJsonNull
())
{
ts
=
data
.
getAsJsonPrimitive
(
"ts"
).
getAsLong
();
}
else
{
ts
=
System
.
currentTimeMillis
();
}
builder
.
setPostTelemetryMsg
(
JsonConverter
.
convertToTelemetryProto
(
data
.
getAsJsonObject
(
"data"
),
ts
));
}
catch
(
Exception
e
)
{
log
.
warn
(
"[{}] Can't convert to telemetry proto, entityData [{}]"
,
entityId
,
entityData
,
e
);
}
break
;
case
ATTRIBUTES_UPDATED:
try
{
JsonObject
data
=
entityData
.
getAsJsonObject
();
TransportProtos
.
PostAttributeMsg
attributesUpdatedMsg
=
JsonConverter
.
convertToAttributesProto
(
data
.
getAsJsonObject
(
"kv"
));
builder
.
setAttributesUpdatedMsg
(
attributesUpdatedMsg
);
builder
.
setPostAttributeScope
(
getScopeOfDefault
(
data
));
}
catch
(
Exception
e
)
{
log
.
warn
(
"[{}] Can't convert to AttributesUpdatedMsg proto, entityData [{}]"
,
entityId
,
entityData
,
e
);
}
break
;
case
POST_ATTRIBUTES:
try
{
JsonObject
data
=
entityData
.
getAsJsonObject
();
TransportProtos
.
PostAttributeMsg
postAttributesMsg
=
JsonConverter
.
convertToAttributesProto
(
data
.
getAsJsonObject
(
"kv"
));
builder
.
setPostAttributesMsg
(
postAttributesMsg
);
builder
.
setPostAttributeScope
(
getScopeOfDefault
(
data
));
}
catch
(
Exception
e
)
{
log
.
warn
(
"[{}] Can't convert to PostAttributesMsg, entityData [{}]"
,
entityId
,
entityData
,
e
);
}
break
;
case
ATTRIBUTES_DELETED:
try
{
AttributeDeleteMsg
.
Builder
attributeDeleteMsg
=
AttributeDeleteMsg
.
newBuilder
();
attributeDeleteMsg
.
setScope
(
entityData
.
getAsJsonObject
().
getAsJsonPrimitive
(
"scope"
).
getAsString
());
JsonArray
jsonArray
=
entityData
.
getAsJsonObject
().
getAsJsonArray
(
"keys"
);
List
<
String
>
keys
=
new
Gson
().
fromJson
(
jsonArray
.
toString
(),
new
TypeToken
<>(){}.
getType
());
attributeDeleteMsg
.
addAllAttributeNames
(
keys
);
attributeDeleteMsg
.
build
();
builder
.
setAttributeDeleteMsg
(
attributeDeleteMsg
);
}
catch
(
Exception
e
)
{
log
.
warn
(
"[{}] Can't convert to AttributeDeleteMsg proto, entityData [{}]"
,
entityId
,
entityData
,
e
);
}
break
;
}
return
builder
.
build
();
}
private
String
getScopeOfDefault
(
JsonObject
data
)
{
JsonPrimitive
scope
=
data
.
getAsJsonPrimitive
(
"scope"
);
String
result
=
DataConstants
.
SERVER_SCOPE
;
if
(
scope
!=
null
&&
StringUtils
.
isNotBlank
(
scope
.
getAsString
()))
{
result
=
scope
.
getAsString
();
}
return
result
;
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.EntityView
;
import
org.thingsboard.server.common.data.id.EntityViewId
;
import
org.thingsboard.server.gen.edge.v1.EdgeEntityType
;
import
org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
EntityViewMsgConstructor
{
public
EntityViewUpdateMsg
constructEntityViewUpdatedMsg
(
UpdateMsgType
msgType
,
EntityView
entityView
)
{
EdgeEntityType
entityType
;
switch
(
entityView
.
getEntityId
().
getEntityType
())
{
case
DEVICE:
entityType
=
EdgeEntityType
.
DEVICE
;
break
;
case
ASSET:
entityType
=
EdgeEntityType
.
ASSET
;
break
;
default
:
throw
new
RuntimeException
(
"Unsupported entity type ["
+
entityView
.
getEntityId
().
getEntityType
()
+
"]"
);
}
EntityViewUpdateMsg
.
Builder
builder
=
EntityViewUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
entityView
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
entityView
.
getId
().
getId
().
getLeastSignificantBits
())
.
setName
(
entityView
.
getName
())
.
setType
(
entityView
.
getType
())
.
setEntityIdMSB
(
entityView
.
getEntityId
().
getId
().
getMostSignificantBits
())
.
setEntityIdLSB
(
entityView
.
getEntityId
().
getId
().
getLeastSignificantBits
())
.
setEntityType
(
entityType
);
if
(
entityView
.
getCustomerId
()
!=
null
)
{
builder
.
setCustomerIdMSB
(
entityView
.
getCustomerId
().
getId
().
getMostSignificantBits
());
builder
.
setCustomerIdLSB
(
entityView
.
getCustomerId
().
getId
().
getLeastSignificantBits
());
}
if
(
entityView
.
getAdditionalInfo
()
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
entityView
.
getAdditionalInfo
()));
}
return
builder
.
build
();
}
public
EntityViewUpdateMsg
constructEntityViewDeleteMsg
(
EntityViewId
entityViewId
)
{
return
EntityViewUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
entityViewId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
entityViewId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/OtaPackageMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
com.google.protobuf.ByteString
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.common.util.JacksonUtil
;
import
org.thingsboard.server.common.data.OtaPackage
;
import
org.thingsboard.server.common.data.id.OtaPackageId
;
import
org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
OtaPackageMsgConstructor
{
public
OtaPackageUpdateMsg
constructOtaPackageUpdatedMsg
(
UpdateMsgType
msgType
,
OtaPackage
otaPackage
)
{
OtaPackageUpdateMsg
.
Builder
builder
=
OtaPackageUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
otaPackage
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
otaPackage
.
getId
().
getId
().
getLeastSignificantBits
())
.
setType
(
otaPackage
.
getType
().
name
())
.
setTitle
(
otaPackage
.
getTitle
())
.
setVersion
(
otaPackage
.
getVersion
())
.
setTag
(
otaPackage
.
getTag
());
if
(
otaPackage
.
getDeviceProfileId
()
!=
null
)
{
builder
.
setDeviceProfileIdMSB
(
otaPackage
.
getDeviceProfileId
().
getId
().
getMostSignificantBits
())
.
setDeviceProfileIdLSB
(
otaPackage
.
getDeviceProfileId
().
getId
().
getLeastSignificantBits
());
}
if
(
otaPackage
.
getUrl
()
!=
null
)
{
builder
.
setUrl
(
otaPackage
.
getUrl
());
}
if
(
otaPackage
.
getAdditionalInfo
()
!=
null
)
{
builder
.
setAdditionalInfo
(
JacksonUtil
.
toString
(
otaPackage
.
getAdditionalInfo
()));
}
if
(
otaPackage
.
getFileName
()
!=
null
)
{
builder
.
setFileName
(
otaPackage
.
getFileName
());
}
if
(
otaPackage
.
getContentType
()
!=
null
)
{
builder
.
setContentType
(
otaPackage
.
getContentType
());
}
if
(
otaPackage
.
getChecksumAlgorithm
()
!=
null
)
{
builder
.
setChecksumAlgorithm
(
otaPackage
.
getChecksumAlgorithm
().
name
());
}
if
(
otaPackage
.
getChecksum
()
!=
null
)
{
builder
.
setChecksum
(
otaPackage
.
getChecksum
());
}
if
(
otaPackage
.
getDataSize
()
!=
null
)
{
builder
.
setDataSize
(
otaPackage
.
getDataSize
());
}
if
(
otaPackage
.
getData
()
!=
null
)
{
builder
.
setData
(
ByteString
.
copyFrom
(
otaPackage
.
getData
().
array
()));
}
return
builder
.
build
();
}
public
OtaPackageUpdateMsg
constructOtaPackageDeleteMsg
(
OtaPackageId
otaPackageId
)
{
return
OtaPackageUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
otaPackageId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
otaPackageId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/QueueMsgConstructor.java
0 → 100644
View file @
98ad3b98
/**
* Copyright © 2016-2022 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.service.edge.rpc.constructor
;
import
org.springframework.stereotype.Component
;
import
org.thingsboard.server.common.data.id.QueueId
;
import
org.thingsboard.server.common.data.queue.ProcessingStrategy
;
import
org.thingsboard.server.common.data.queue.Queue
;
import
org.thingsboard.server.common.data.queue.SubmitStrategy
;
import
org.thingsboard.server.gen.edge.v1.ProcessingStrategyProto
;
import
org.thingsboard.server.gen.edge.v1.QueueUpdateMsg
;
import
org.thingsboard.server.gen.edge.v1.SubmitStrategyProto
;
import
org.thingsboard.server.gen.edge.v1.UpdateMsgType
;
import
org.thingsboard.server.queue.util.TbCoreComponent
;
@Component
@TbCoreComponent
public
class
QueueMsgConstructor
{
public
QueueUpdateMsg
constructQueueUpdatedMsg
(
UpdateMsgType
msgType
,
Queue
queue
)
{
QueueUpdateMsg
.
Builder
builder
=
QueueUpdateMsg
.
newBuilder
()
.
setMsgType
(
msgType
)
.
setIdMSB
(
queue
.
getId
().
getId
().
getMostSignificantBits
())
.
setIdLSB
(
queue
.
getId
().
getId
().
getLeastSignificantBits
())
.
setTenantIdMSB
(
queue
.
getTenantId
().
getId
().
getMostSignificantBits
())
.
setTenantIdLSB
(
queue
.
getTenantId
().
getId
().
getLeastSignificantBits
())
.
setName
(
queue
.
getName
())
.
setTopic
(
queue
.
getTopic
())
.
setPollInterval
(
queue
.
getPollInterval
())
.
setPartitions
(
queue
.
getPartitions
())
.
setConsumerPerPartition
(
queue
.
isConsumerPerPartition
())
.
setPackProcessingTimeout
(
queue
.
getPackProcessingTimeout
())
.
setSubmitStrategy
(
createSubmitStrategyProto
(
queue
.
getSubmitStrategy
()))
.
setProcessingStrategy
(
createProcessingStrategyProto
(
queue
.
getProcessingStrategy
()));
return
builder
.
build
();
}
private
ProcessingStrategyProto
createProcessingStrategyProto
(
ProcessingStrategy
processingStrategy
)
{
return
ProcessingStrategyProto
.
newBuilder
()
.
setType
(
processingStrategy
.
getType
().
name
())
.
setRetries
(
processingStrategy
.
getRetries
())
.
setFailurePercentage
(
processingStrategy
.
getFailurePercentage
())
.
setPauseBetweenRetries
(
processingStrategy
.
getPauseBetweenRetries
())
.
setMaxPauseBetweenRetries
(
processingStrategy
.
getMaxPauseBetweenRetries
())
.
build
();
}
private
SubmitStrategyProto
createSubmitStrategyProto
(
SubmitStrategy
submitStrategy
)
{
return
SubmitStrategyProto
.
newBuilder
()
.
setType
(
submitStrategy
.
getType
().
name
())
.
setBatchSize
(
submitStrategy
.
getBatchSize
())
.
build
();
}
public
QueueUpdateMsg
constructQueueDeleteMsg
(
QueueId
queueId
)
{
return
QueueUpdateMsg
.
newBuilder
()
.
setMsgType
(
UpdateMsgType
.
ENTITY_DELETED_RPC_MESSAGE
)
.
setIdMSB
(
queueId
.
getId
().
getMostSignificantBits
())
.
setIdLSB
(
queueId
.
getId
().
getLeastSignificantBits
()).
build
();
}
}
Prev
1
…
7
8
9
10
11
12
13
14
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment