bosun lookup using multiple tags - bosun

I want notifications to be selected depending on tags. So I am using lookup.
notification default {
email = mailid-1
next = default
timeout = 1m
}
notification nondefault {
email = mailid-2
next = nondefault
timeout = 1m
}
lookup notif {
entry some_tag=value {
mail = nondefault
}
entry some_tag=* {
mail = default
}
}
And in alert I am giving
critNotification = lookup("notif", "email")
My question is it possible to use multiple tags in
lookup(I am using some_tag=value) ?
eg. something like
lookup notif {
entry some_tag=value,some_other_tag=value {
mail = nondefault
}
entry some_tag=* {
mail = default
}
}

Yes, there is an example in the documentation (kind of hard to find):
lookup cpu {
entry host=web-*,dc=eu {
high = 0.5
}
entry host=sql-*,dc=us {
high = 0.8
}
entry host=*,dc=us {
high = 0.3
}
entry host=*,dc=* {
high = 0.4
}
}
alert cpu {
crit = avg(q("avg:rate:os.cpu{host=*,dc=*}", "5m", "")) > lookup("cpu", "high")
}

Related

RxAndroidBle can't disconnect

I encountered a situation
When I connect 2 devices at once
When the connection is successful, the notification subcribe is listened to
When one is off and the other is in use
The program keeps trying to connect the two devices every 5 seconds
but because the connection is not disconnected
so it has to wait until the one that is switched off GATT ERROR
The one that is in use will not successfully connect to receive data
This is a bit of a long wait.
I want to disconnect manually after receiving the data
So that the next time I connect, I don't have to wait for GATT ERROR.
I don't know if this will improve the long waiting time of the one in use.
I have tried nRF connect
When I disconnected it manually
I can quickly connect with another
class BleDevice : BaseDevice() {
lateinit var context: Context
private var macAddress : String = "00:00:00:00:00:00"
//Search Device behavior
//If true, always search no interrupt
private var establishConnection = false
private var setupNotificationMap = arrayListOf<Disposable>()
private var connectionDisposable: Disposable? = null
private var sendDisposable: Disposable? = null
private var connection: RxBleConnection? = null
override fun work() {
if((strategy as BaseBleVariables).enableSetMTU()) {
connection?.requestMtu((strategy as BaseBleVariables).getMTUSize())
?.subscribe(
{ it ->
Log.d(logTag, "Set MTU = $it")
},
{ exception ->
exception.printStackTrace()
}
)?.let { disposable ->
setupNotificationMap.add(disposable)
}
}
(strategy as BaseBleVariables).getNotificationMap().forEach { uuid ->
Log.d(logTag, "getNotification")
connection?.setupNotification(UUID.fromString(uuid))
?.subscribe(
{
it.subscribe(
{ receive ->
strategy.onRespond(
receive,
Bundle().apply { putString("Characteristic", uuid) }
)
},
{ exception ->
Log.d(logTag, "Receive Response Fail")
exception.printStackTrace()
disconnect(exception.message)
}
).let { disposable ->
setupNotificationMap.add(disposable)
}
},
{ exception ->
Log.d(logTag, "Setup Notification Fail")
exception.printStackTrace()
disconnect(exception.message)
}
)?.let { disposable ->
setupNotificationMap.add(disposable)
}
}
strategy.onSend(null)
}
override fun stopWork() {
setupNotificationMap.forEach {
if(!it.isDisposed) {
it.dispose()
}
}
sendDisposable?.let {
if(!it.isDisposed) {
Log.d(logTag, "SendDisposable dispose")
it.dispose()
}
}
setupNotificationMap.clear()
}
#ExperimentalStdlibApi
override fun connect() {
if(strategy !is BaseBleVariables) {
Log.d(logTag, "Strategy not impl ble variables")
returnConnectionStatus(false, "Strategy incorrectly implement")
return
}
RxJavaPlugins.setErrorHandler { throwable: Throwable ->
throwable.printStackTrace()
}
connectionDisposable = RxBleClient.create(context)
.getBleDevice(macAddress)
.establishConnection(establishConnection)
.subscribe(
{
connection = it
returnConnectionStatus(true)
},
{
Log.d(logTag, "Client Disconnected")
it.printStackTrace()
disconnect(it.message)
}
)
}
override fun disconnect(message: String?) {
runCatching {
stopWork()
connectionDisposable?.let {
if(!it.isDisposed) {
Log.d(logTag, "ConnectionDisposable dispose")
it.dispose()
}
}
connection = null
returnConnectionStatus(false, message)
}.onFailure {
returnConnectionStatus(false, message)
}
}
override fun receive(): Result<ByteArray> {
return Result.success(byteArrayOf())
}
override fun send(command: Any, extras: Bundle?): Result<Any> {
if(connection == null) {
return Result.failure(Exception("Connection is null"))
}
else {
return runCatching {
when(command) {
is ByteArray -> {
Log.d(logTag, "Delay : ${extras?.getLong("SendDelay", 0L)}")
Log.d(logTag, "Send : ${command.contentToString()}")
extras?.getString("Characteristic")?.let { characteristic ->
sendDisposable?.let {
if(!it.isDisposed) {
it.dispose()
}
}
sendDisposable = connection?.writeCharacteristic(
(UUID.fromString(characteristic)),
command
)?.delaySubscription(extras.getLong("SendDelay", 0L), TimeUnit.MILLISECONDS)
?.subscribe(
{
Log.d(logTag, "Write Characteristic($characteristic) = ${String(it)}")
},
{
Log.d(logTag, "Send Fail")
it.printStackTrace()
}
)
}
"Nothing"
}
else -> {
Log.d(logTag, "This command type not support now")
}
}
}
}
}
class Builder<T: BaseStrategy>(strategyClass: Class<T>, _context: Context): BaseDevice.Builder<BleDevice, T>(BleDevice::class.java, strategyClass){
private var logTag = "BleBuilder"
init {
device.context = _context
}
fun setMacAddress(address: String) : Builder<T> {
device.macAddress = address
Log.d(logTag, "Set MacAddress = ".plus(address))
return this
}
/**
* Search Device behavior
* If true, always search no interrupt
*/
fun setEstablishConnection(establish: Boolean) : Builder<T> {
device.establishConnection = establish
Log.d(logTag, "Set EstablishConnection = ".plus(establish))
return this
}
}
}
To use it, remember the mac address of the two Bluetooth devices
Then use the for loop to connect one device in 5 seconds
When the device is connected, dispose of it and connect to the other one which is not connected.
I have also tried for looping two units at a time in five seconds
When connecting
When both devices are on, the data can be transferred back quickly
When one of them is switched off
When one is switched off, the switched on device must wait for the switched off device to automatically Gatt ERROR
The one that is switched on will only connect and send data
But when using the nRF connect app
When I manually disconnect the one that is off
the other one can connect and send back data very quickly
RxAndroidBle Author's Response
RxAndroidBle was designed to not have any state management (i.e. disconnection function) — when the user is no longer interested in keeping the connection they just dispose the flow.
You should be able to dispose your connection when you receive the data

How to retrieve data from firestore when the barcode reader scans the barcode

Based on : https://github.com/yuriy-budiyev/code-scanner
I would like to retrieve the data from firestore class when the barcode reader scans the barcode but I don't know how to do it. And also i want to proceed to the other page after scanned the barcode. Please help me to solve to it. Here is my code :
private fun codeScanner() {
codeScanner = CodeScanner(this, scanner_view)
codeScanner.apply {
camera = CodeScanner.CAMERA_BACK
formats = CodeScanner.ONE_DIMENSIONAL_FORMATS
autoFocusMode = AutoFocusMode.SAFE
isAutoFocusEnabled = true
isFlashEnabled = false
decodeCallback = DecodeCallback {
runOnUiThread {
tv_textView.text=it.text
}
}
errorCallback = ErrorCallback {
runOnUiThread {
Log.e("Scan", "Camera initialization error: ${it.message}")
}
}
}
scanner_view.setOnClickListener {
codeScanner.startPreview()
}
}
Here's how my data in firestore looks like:
Firestore

MutlicastSocket receive not always

I want to implement a "simple" SSDP discovering client. Means the client should send out a
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: ssdp:all
and afterwards listen to "the network"(?) to get the list of IP addresses.
To test the implementation I've written a unit test which creates a "fake" MulticastServer which simply hear to the SSDP IP&Port and, when receive something, send the same message back.
The problem is that this code works on my machine (macOS) most of the time but never on our CI Server (Linux). I (macOS) receive sometimes the same assertion failed error as on the CI. But as I said - only sometimes! Not always. And I don't know why.
This is the implementation on the client side:
interface GatewayDiscoverer {
companion object {
val instance: GatewayDiscoverer = DefaultGatewayDiscoverer()
}
suspend fun discoverGateways(timeoutMillis: Int = 1000): List<String>
}
internal class DefaultGatewayDiscoverer : GatewayDiscoverer {
override suspend fun discoverGateways(timeoutMillis: Int): List<String> {
require(timeoutMillis in 1000..5000) {
"timeoutMillis should be between 1000 (inclusive) and 5000 (inclusive)!"
}
val socket = DatagramSocket()
sendSsdpPacket(socket)
val gateways = receiveSsdpPacket(socket, timeoutMillis)
return gateways
}
private fun sendSsdpPacket(socket: DatagramSocket) {
val packetToSend =
"M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 1\r\nST: ssdp:all\r\n\r\n"
val packetToSendAsBytes = packetToSend.toByteArray()
val packet = DatagramPacket(
packetToSendAsBytes,
packetToSendAsBytes.size,
InetAddress.getByName("239.255.255.250"),
1900
)
socket.send(packet)
}
private fun receiveSsdpPacket(socket: DatagramSocket, timeoutInMillis: Int): List<String> {
val gatewayList = mutableListOf<String>()
while (true) {
val receivedData = ByteArray(12)
val packetToReceive = DatagramPacket(receivedData, receivedData.size)
socket.soTimeout = timeoutInMillis
try {
socket.receive(packetToReceive)
packetToReceive.address?.hostName?.let { gatewayList.add(it) }
} catch (socketTimeout: SocketTimeoutException) {
return gatewayList
}
}
}
}
And this the test (includes the MulticastServer):
class DefaultGatewayDiscovererTest {
#Test
fun `discover gateways should return a list of gateway IPs`() = with(MulticastServer()) {
start()
val list = runBlocking { GatewayDiscoverer.instance.discoverGateways(1000) }
close()
assertThat(list.size).isEqualTo(1)
assertThat(list).contains(InetAddress.getLocalHost().hostAddress)
Unit
}
}
/**
* A "MulticastServer" which will join the
* 239.255.255.250:1900 group to listen on SSDP events.
* They will report back with the same package
* it received.
*/
class MulticastServer : Thread(), Closeable {
private val group = InetAddress.getByName("239.255.255.250")
private val socket: MulticastSocket = MulticastSocket(1900)
init {
// This force to use IPv4...
var netinterface: NetworkInterface? = null
// Otherwise it will (at least on macOS) use IPv6 which leads to issues
// while joining the group...
val networkInterfaces = NetworkInterface.getNetworkInterfaces()
while (networkInterfaces.hasMoreElements()) {
val networkInterface = networkInterfaces.nextElement()
val addressesFromNetworkInterface = networkInterface.inetAddresses
while (addressesFromNetworkInterface.hasMoreElements()) {
val inetAddress = addressesFromNetworkInterface.nextElement()
if (inetAddress.isSiteLocalAddress
&& !inetAddress.isAnyLocalAddress
&& !inetAddress.isLinkLocalAddress
&& !inetAddress.isLoopbackAddress
&& !inetAddress.isMulticastAddress
) {
netinterface = NetworkInterface.getByName(networkInterface.name)
}
}
}
socket.joinGroup(InetSocketAddress("239.255.255.250", 1900), netinterface!!)
}
override fun run() {
while (true) {
val buf = ByteArray(256)
val packet = DatagramPacket(buf, buf.size)
try {
socket.receive(packet)
} catch (socketEx: SocketException) {
break
}
// Print for debugging
val message = String(packet.data, 0, packet.length)
println(message)
socket.send(packet)
}
}
override fun close() = with(socket) {
leaveGroup(group)
close()
}
}
When the test fails it fails on that line:
assertThat(list.size).isEqualTo(1)
The list is empty.
After some debugging I found out that the MulticastServer don't receive the message. Therefore the client don't get the response and add the IP address to the list.
I would expect that the MulticastServer will always work without that "flakiness". Do I something wrong with the implementation?

Fixed a bug that KAA-1594: error after attaching endpoint to user

The bug in kaa 0.10 have Influenced my application development. So I try to fix it.Then I Compared the code of the kaa 0.9 and kaa 0.10. I have found the differences in class EndpointServiceImpl of Kaa DAO interface modular:there are two methods of attachEndpointToUser in it
1,
public EndpointProfileDto attachEndpointToUser(String endpointUserId, String
endpointAccessToken) throws KaaOptimisticLockingFailureException {
LOG.info("Try to attach endpoint with access token {} to user with {}", endpointAccessToken,
endpointUserId);
validateString(endpointUserId, "Incorrect endpointUserId "
+ endpointUserId);
EndpointUser endpointUser = endpointUserDao.findById(endpointUserId);
LOG.trace("[{}] Found endpoint user with id {} ", endpointUserId, endpointUser);
if (endpointUser
!= null) {
EndpointProfile endpoint = endpointProfileDao.findByAccessToken(endpointAccessToken);
LOG.trace("[{}] Found endpoint profile by with access token {} ", endpointAccessToken,
endpoint);
if (endpoint
!= null) {
if (endpoint.getEndpointUserId()
== null
|| endpointUserId.equals(endpoint.getEndpointUserId())) {
LOG.debug("Attach endpoint profile with id {} to endpoint user with id {} ", endpoint
.getId(), endpointUser.getId());
List<String> endpointIds = endpointUser.getEndpointIds();
**/*if (endpointIds
!= null
&& endpointIds.contains(endpoint.getId())) {
LOG.warn("Endpoint is already assigned to current user {}.", endpoint
.getEndpointUserId());
return getDto(endpoint);
}*/**
if (endpointIds
== null) {
endpointIds = new ArrayList<>();
endpointUser.setEndpointIds(endpointIds);
}
endpointIds.add(endpoint.getId());
endpointUser = endpointUserDao.save(endpointUser);
while (true) {
try {
endpoint.setEndpointUserId(endpointUser.getId());
LOG.trace("Save endpoint user {} and endpoint profile {}", endpointUser, endpoint);
endpoint = endpointProfileDao.save(endpoint);
break;
} catch (KaaOptimisticLockingFailureException ex) {
LOG.warn("Optimistic lock detected in endpoint profile ", Arrays.toString(endpoint
.getEndpointKey()), ex);
endpoint = endpointProfileDao.findByKeyHash(Sha1HashUtils.hashToBytes(endpoint
.getEndpointKey()));
}
}
return getDto(endpoint);
} else {
LOG.warn("Endpoint is already assigned to different user {}. Unassign it first!.",
endpoint.getEndpointUserId());
throw new DatabaseProcessingException("Endpoint is already assigned to different user.");
}
} else {
LOG.warn("Endpoint with accessToken {} is not present in db.", endpointAccessToken);
throw new DatabaseProcessingException("No endpoint found for specified accessToken.");
}
} else {
LOG.warn("Endpoint user with id {} is not present in db.", endpointUserId);
throw new DatabaseProcessingException("Endpoint user is not present in db.");
}
}
2,
public EndpointProfileDto attachEndpointToUser(String userExternalId, String tenantId,
EndpointProfileDto profile) {
validateString(userExternalId, "Incorrect userExternalId "
+ userExternalId);
EndpointUser endpointUser = endpointUserDao.findByExternalIdAndTenantId(userExternalId,
tenantId);
if (endpointUser
== null) {
LOG.info("Creating new endpoint user with external id: [{}] in context of [{}] tenant",
userExternalId, tenantId);
EndpointUserDto endpointUserDto = new EndpointUserDto();
endpointUserDto.setTenantId(tenantId);
endpointUserDto.setExternalId(userExternalId);
endpointUserDto.setUsername(userExternalId);
endpointUser = endpointUserDao.save(endpointUserDto);
}
List<String> endpointIds = endpointUser.getEndpointIds();
if (endpointIds
== null) {
endpointIds = new ArrayList<>();
endpointUser.setEndpointIds(endpointIds);
} **/*else if (endpointIds
!= null
&& endpointIds.contains(profile.getId())) {
LOG.warn("Endpoint is already assigned to current user {}.", profile.getEndpointUserId());
return profile;
}*/**
endpointIds.add(profile.getId());
endpointUser = endpointUserDao.save(endpointUser);
profile.setEndpointUserId(endpointUser.getId());
while (true) {
try {
LOG.trace("Save endpoint user {} and endpoint profile {}", endpointUser, profile);
return saveEndpointProfile(profile);
} catch (KaaOptimisticLockingFailureException ex) {
LOG.warn("Optimistic lock detected in endpoint profile ", Arrays.toString(profile
.getEndpointKey()), ex);
profile = findEndpointProfileByKeyHash(profile.getEndpointKeyHash());
profile.setEndpointUserId(endpointUser.getId());
}
}
}
The code above is in kaa 0.10 .Compared with the Kaa 0.9, it Added a judgment condition that in Bold code above:(
if(endpointIds!=null&&endpointIds.contains(endpoint.getId())) )
and
else if (endpointIds
!= null
&& endpointIds.contains(profile.getId())).
I have made a test that Commented the judgment condition codes. The result is OK. I want to know that the fix method is available .
You can contribute to kaa.
Description on this procedure you can find here.
In few words about it:
fork kaa repository here.
crete new branch with the content of branch you want to fix(release-0.10)
commit (commit message must begin with "KAA-1594:") and push changes into your fork.
create a pull request on kaa page (compare original kaa branch release-0.10 and your new edited branch)
allow changes from owners
you are done!
UPD: would be great if you describe the problem and your solution in issue on github it will help us to make official fix faster.

Lock out users after three unsuccessful attempts without using a database

I want to lock out my users after three unsuccessfull attempts without using a database.
I was trying:
public int loginAttempts()
{
if (!(ViewData["loginAttempts"] == null))
{
ViewData["loginAttempts"] = int.Parse(ViewData["loginAttempts"].ToString()) + 1;
return int.Parse(ViewData["loginAttempts"].ToString());
}
else
{
ViewData["loginAttempts"] = 1;
return 1;
}
}
But it always returns 1. What modifications do I need to make?
You'd need to store this in the session, not view data. View data is sent to the view and is not persisted between requests.
public int loginAttempts()
{
if (!(Session["loginAttempts"] == null))
{
Session["loginAttempts"] = int.Parse(Session["loginAttempts"].ToString()) + 1;
return int.Parse(Session["loginAttempts"].ToString());
}
else
{
Session["loginAttempts"] = 1;
return 1;
}
}
Use Session state variables.

Resources