23 changed files with 814 additions and 119 deletions
@ -0,0 +1,89 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.msg.queue.RuleEngineException; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrategy; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.CountDownLatch; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
public class ProcessingAttemptContext { |
||||
|
|
||||
|
private final TbRuleEngineSubmitStrategy submitStrategy; |
||||
|
|
||||
|
private final CountDownLatch processingTimeoutLatch = new CountDownLatch(1); |
||||
|
@Getter |
||||
|
private final ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> pendingMap; |
||||
|
@Getter |
||||
|
private final ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> successMap = new ConcurrentHashMap<>(); |
||||
|
@Getter |
||||
|
private final ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> failedMap = new ConcurrentHashMap<>(); |
||||
|
@Getter |
||||
|
private final ConcurrentMap<TenantId, RuleEngineException> exceptionsMap = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
public ProcessingAttemptContext(TbRuleEngineSubmitStrategy submitStrategy) { |
||||
|
this.submitStrategy = submitStrategy; |
||||
|
this.pendingMap = submitStrategy.getPendingMap(); |
||||
|
} |
||||
|
|
||||
|
public boolean await(long packProcessingTimeout, TimeUnit milliseconds) throws InterruptedException { |
||||
|
return processingTimeoutLatch.await(packProcessingTimeout, milliseconds); |
||||
|
} |
||||
|
|
||||
|
public void onSuccess(UUID id) { |
||||
|
TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg> msg; |
||||
|
boolean empty = false; |
||||
|
synchronized (pendingMap) { |
||||
|
msg = pendingMap.remove(id); |
||||
|
if (msg != null) { |
||||
|
empty = pendingMap.isEmpty(); |
||||
|
} |
||||
|
} |
||||
|
if (msg != null) { |
||||
|
successMap.put(id, msg); |
||||
|
} |
||||
|
submitStrategy.onSuccess(id); |
||||
|
if (empty) { |
||||
|
processingTimeoutLatch.countDown(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void onFailure(TenantId tenantId, UUID id, RuleEngineException e) { |
||||
|
TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg> msg; |
||||
|
boolean empty = false; |
||||
|
synchronized (pendingMap) { |
||||
|
msg = pendingMap.remove(id); |
||||
|
if (msg != null) { |
||||
|
empty = pendingMap.isEmpty(); |
||||
|
} |
||||
|
} |
||||
|
if (msg != null) { |
||||
|
failedMap.put(id, msg); |
||||
|
exceptionsMap.putIfAbsent(tenantId, e); |
||||
|
} |
||||
|
if (empty) { |
||||
|
processingTimeoutLatch.countDown(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
public abstract class AbstractTbRuleEngineSubmitStrategy implements TbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
protected final String queueName; |
||||
|
protected List<IdMsgPair> orderedMsgList; |
||||
|
private volatile boolean stopped; |
||||
|
|
||||
|
public AbstractTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
this.queueName = queueName; |
||||
|
} |
||||
|
|
||||
|
protected abstract void doOnSuccess(UUID id); |
||||
|
|
||||
|
@Override |
||||
|
public void init(List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs) { |
||||
|
orderedMsgList = msgs.stream().map(msg -> new IdMsgPair(UUID.randomUUID(), msg)).collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getPendingMap() { |
||||
|
return orderedMsgList.stream().collect(Collectors.toConcurrentMap(pair -> pair.uuid, pair -> pair.msg)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void update(ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> reprocessMap) { |
||||
|
List<IdMsgPair> newOrderedMsgList = new ArrayList<>(reprocessMap.size()); |
||||
|
for (IdMsgPair pair : orderedMsgList) { |
||||
|
if (reprocessMap.containsKey(pair.uuid)) { |
||||
|
newOrderedMsgList.add(pair); |
||||
|
} |
||||
|
} |
||||
|
orderedMsgList = newOrderedMsgList; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onSuccess(UUID id) { |
||||
|
if (!stopped) { |
||||
|
doOnSuccess(id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void stop() { |
||||
|
stopped = true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.ExecutorService; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
import java.util.function.BiConsumer; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class BatchTbRuleEngineSubmitStrategy extends AbstractTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
private final int batchSize; |
||||
|
private final AtomicInteger packIdx = new AtomicInteger(0); |
||||
|
private final Map<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> pendingPack = new LinkedHashMap<>(); |
||||
|
private volatile BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer; |
||||
|
|
||||
|
public BatchTbRuleEngineSubmitStrategy(String queueName, int batchSize) { |
||||
|
super(queueName); |
||||
|
this.batchSize = batchSize; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void submitAttempt(BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer) { |
||||
|
this.msgConsumer = msgConsumer; |
||||
|
submitNext(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void update(ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> reprocessMap) { |
||||
|
super.update(reprocessMap); |
||||
|
packIdx.set(0); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void doOnSuccess(UUID id) { |
||||
|
boolean endOfPendingPack; |
||||
|
synchronized (pendingPack) { |
||||
|
TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg> msg = pendingPack.remove(id); |
||||
|
endOfPendingPack = msg != null && pendingPack.isEmpty(); |
||||
|
} |
||||
|
if (endOfPendingPack) { |
||||
|
packIdx.incrementAndGet(); |
||||
|
submitNext(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void submitNext() { |
||||
|
int listSize = orderedMsgList.size(); |
||||
|
int startIdx = Math.min(packIdx.get() * batchSize, listSize); |
||||
|
int endIdx = Math.min(startIdx + batchSize, listSize); |
||||
|
synchronized (pendingPack) { |
||||
|
pendingPack.clear(); |
||||
|
for (int i = startIdx; i < endIdx; i++) { |
||||
|
IdMsgPair pair = orderedMsgList.get(i); |
||||
|
pendingPack.put(pair.uuid, pair.msg); |
||||
|
} |
||||
|
} |
||||
|
int submitSize = pendingPack.size(); |
||||
|
if (log.isInfoEnabled() && submitSize > 0) { |
||||
|
log.info("[{}] submitting [{}] messages to rule engine", queueName, submitSize); |
||||
|
} |
||||
|
pendingPack.forEach(msgConsumer); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.ExecutorService; |
||||
|
import java.util.function.BiConsumer; |
||||
|
import java.util.function.Function; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class BurstTbRuleEngineSubmitStrategy extends AbstractTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
public BurstTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
super(queueName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void submitAttempt(BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer) { |
||||
|
if (log.isInfoEnabled()) { |
||||
|
log.info("[{}] submitting [{}] messages to rule engine", queueName, orderedMsgList.size()); |
||||
|
} |
||||
|
orderedMsgList.forEach(pair -> msgConsumer.accept(pair.uuid, pair.msg)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void doOnSuccess(UUID id) { |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
public class IdMsgPair { |
||||
|
final UUID uuid; |
||||
|
final TbProtoQueueMsg<ToRuleEngineMsg> msg; |
||||
|
|
||||
|
public IdMsgPair(UUID uuid, TbProtoQueueMsg<ToRuleEngineMsg> msg) { |
||||
|
this.uuid = uuid; |
||||
|
this.msg = msg; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,108 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import com.google.protobuf.InvalidProtocolBufferException; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
||||
|
import org.thingsboard.server.common.msg.TbMsg; |
||||
|
import org.thingsboard.server.common.msg.gen.MsgProtos; |
||||
|
import org.thingsboard.server.common.msg.queue.TbMsgCallback; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
import java.util.Queue; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
import java.util.function.BiConsumer; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Slf4j |
||||
|
public abstract class SequentialByEntityIdTbRuleEngineSubmitStrategy extends AbstractTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
private volatile BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer; |
||||
|
private volatile ConcurrentMap<UUID, EntityId> msgToEntityIdMap = new ConcurrentHashMap<>(); |
||||
|
private volatile ConcurrentMap<EntityId, Queue<IdMsgPair>> entityIdToListMap = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
public SequentialByEntityIdTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
super(queueName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void init(List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs) { |
||||
|
super.init(msgs); |
||||
|
initMaps(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void submitAttempt(BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer) { |
||||
|
this.msgConsumer = msgConsumer; |
||||
|
entityIdToListMap.forEach((entityId, queue) -> { |
||||
|
IdMsgPair msg = queue.peek(); |
||||
|
if (msg != null) { |
||||
|
msgConsumer.accept(msg.uuid, msg.msg); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void update(ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> reprocessMap) { |
||||
|
super.update(reprocessMap); |
||||
|
initMaps(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void doOnSuccess(UUID id) { |
||||
|
EntityId entityId = msgToEntityIdMap.get(id); |
||||
|
if (entityId != null) { |
||||
|
Queue<IdMsgPair> queue = entityIdToListMap.get(entityId); |
||||
|
if (queue != null) { |
||||
|
IdMsgPair next = null; |
||||
|
synchronized (queue) { |
||||
|
IdMsgPair expected = queue.peek(); |
||||
|
if (expected != null && expected.uuid.equals(id)) { |
||||
|
queue.poll(); |
||||
|
next = queue.peek(); |
||||
|
} |
||||
|
} |
||||
|
if (next != null) { |
||||
|
msgConsumer.accept(next.uuid, next.msg); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void initMaps() { |
||||
|
msgToEntityIdMap.clear(); |
||||
|
entityIdToListMap.clear(); |
||||
|
for (IdMsgPair pair : orderedMsgList) { |
||||
|
EntityId entityId = getEntityId(pair.msg.getValue()); |
||||
|
if (entityId != null) { |
||||
|
msgToEntityIdMap.put(pair.uuid, entityId); |
||||
|
entityIdToListMap.computeIfAbsent(entityId, id -> new LinkedList<>()).add(pair); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected abstract EntityId getEntityId(TransportProtos.ToRuleEngineMsg msg); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import com.google.protobuf.InvalidProtocolBufferException; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
||||
|
import org.thingsboard.server.common.msg.gen.MsgProtos; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class SequentialByOriginatorIdTbRuleEngineSubmitStrategy extends SequentialByEntityIdTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
public SequentialByOriginatorIdTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
super(queueName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected EntityId getEntityId(TransportProtos.ToRuleEngineMsg msg) { |
||||
|
try { |
||||
|
MsgProtos.TbMsgProto proto = MsgProtos.TbMsgProto.parseFrom(msg.getTbMsg()); |
||||
|
return EntityIdFactory.getByTypeAndUuid(proto.getEntityType(), new UUID(proto.getEntityIdMSB(), proto.getEntityIdLSB())); |
||||
|
} catch (InvalidProtocolBufferException e) { |
||||
|
log.warn("[{}] Failed to parse TbMsg: {}", queueName, msg); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
public class SequentialByTenantIdTbRuleEngineSubmitStrategy extends SequentialByEntityIdTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
public SequentialByTenantIdTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
super(queueName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected EntityId getEntityId(TransportProtos.ToRuleEngineMsg msg) { |
||||
|
return new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
import java.util.function.BiConsumer; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class SequentialTbRuleEngineSubmitStrategy extends AbstractTbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
private final AtomicInteger msgIdx = new AtomicInteger(0); |
||||
|
private volatile BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer; |
||||
|
private volatile UUID expectedMsgId; |
||||
|
|
||||
|
public SequentialTbRuleEngineSubmitStrategy(String queueName) { |
||||
|
super(queueName); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void submitAttempt(BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer) { |
||||
|
this.msgConsumer = msgConsumer; |
||||
|
msgIdx.set(0); |
||||
|
submitNext(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void update(ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> reprocessMap) { |
||||
|
super.update(reprocessMap); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void doOnSuccess(UUID id) { |
||||
|
if (expectedMsgId.equals(id)) { |
||||
|
msgIdx.incrementAndGet(); |
||||
|
submitNext(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void submitNext() { |
||||
|
int listSize = orderedMsgList.size(); |
||||
|
int idx = msgIdx.get(); |
||||
|
if (idx < listSize) { |
||||
|
IdMsgPair pair = orderedMsgList.get(idx); |
||||
|
expectedMsgId = pair.uuid; |
||||
|
if (log.isInfoEnabled()) { |
||||
|
log.info("[{}] submitting [{}] message to rule engine", queueName, pair.msg); |
||||
|
} |
||||
|
msgConsumer.accept(pair.uuid, pair.msg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
import java.util.concurrent.ConcurrentMap; |
||||
|
import java.util.function.BiConsumer; |
||||
|
|
||||
|
public interface TbRuleEngineSubmitStrategy { |
||||
|
|
||||
|
void init(List<TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgs); |
||||
|
|
||||
|
ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> getPendingMap(); |
||||
|
|
||||
|
void submitAttempt(BiConsumer<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> msgConsumer); |
||||
|
|
||||
|
void update(ConcurrentMap<UUID, TbProtoQueueMsg<TransportProtos.ToRuleEngineMsg>> reprocessMap); |
||||
|
|
||||
|
void onSuccess(UUID id); |
||||
|
|
||||
|
void stop(); |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.processing; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.queue.settings.TbRuleEngineQueueSubmitStrategyConfiguration; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class TbRuleEngineSubmitStrategyFactory { |
||||
|
|
||||
|
public TbRuleEngineSubmitStrategy newInstance(String name, TbRuleEngineQueueSubmitStrategyConfiguration configuration) { |
||||
|
switch (configuration.getType()) { |
||||
|
case "BURST": |
||||
|
return new BurstTbRuleEngineSubmitStrategy(name); |
||||
|
case "BATCH": |
||||
|
return new BatchTbRuleEngineSubmitStrategy(name, configuration.getBatchSize()); |
||||
|
case "SEQUENTIAL_WITHIN_ORIGINATOR": |
||||
|
return new SequentialByOriginatorIdTbRuleEngineSubmitStrategy(name); |
||||
|
case "SEQUENTIAL_WITHIN_TENANT": |
||||
|
return new SequentialByTenantIdTbRuleEngineSubmitStrategy(name); |
||||
|
case "SEQUENTIAL": |
||||
|
return new SequentialTbRuleEngineSubmitStrategy(name); |
||||
|
default: |
||||
|
throw new RuntimeException("TbRuleEngineProcessingStrategy with type " + configuration.getType() + " is not supported!"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2020 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.queue.settings; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
public class TbRuleEngineQueueSubmitStrategyConfiguration { |
||||
|
|
||||
|
private String type; |
||||
|
private int batchSize; |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue