diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java new file mode 100644 index 00000000..e20bdafc --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java @@ -0,0 +1,84 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2023. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.actions.queues; + + +import java.util.List; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.sqs.AmazonSQS; +import com.amazonaws.services.sqs.AmazonSQSClientBuilder; +import com.amazonaws.services.sqs.model.GetQueueAttributesResult; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.logging.QLogger; +import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.queues.SQSQueueProviderMetaData; +import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class GetQueueSize +{ + private static final QLogger LOG = QLogger.getLogger(GetQueueSize.class); + + + + /******************************************************************************* + ** + *******************************************************************************/ + public Integer getQueueSize(QQueueProviderMetaData queueProviderMetaData, QQueueMetaData queueMetaData) throws QException + { + try + { + ////////////////////////////////////////////////////////////////// + // todo - handle other queue provider types, somewhere, somehow // + ////////////////////////////////////////////////////////////////// + SQSQueueProviderMetaData queueProvider = (SQSQueueProviderMetaData) queueProviderMetaData; + + BasicAWSCredentials credentials = new BasicAWSCredentials(queueProvider.getAccessKey(), queueProvider.getSecretKey()); + final AmazonSQS sqs = AmazonSQSClientBuilder.standard() + .withRegion(queueProvider.getRegion()) + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .build(); + + String queueUrl = queueProvider.getBaseURL(); + if(!queueUrl.endsWith("/")) + { + queueUrl += "/"; + } + queueUrl += queueMetaData.getQueueName(); + + GetQueueAttributesResult queueAttributes = sqs.getQueueAttributes(queueUrl, List.of("ApproximateNumberOfMessages")); + String approximateNumberOfMessages = queueAttributes.getAttributes().get("ApproximateNumberOfMessages"); + return (Integer.parseInt(approximateNumberOfMessages)); + } + catch(Exception e) + { + LOG.warn("Error getting queue size", e, logPair("queueName", queueMetaData == null ? "null" : queueMetaData.getName())); + throw (new QException("Error getting queue size", e)); + } + } + +} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java index f3ab6ab2..f6b065fc 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java @@ -22,6 +22,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode; +import java.io.Serializable; import java.util.Map; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; @@ -35,6 +36,8 @@ public abstract class AbstractWidgetValueSource protected String name; protected String type; + protected Map inputValues; + /******************************************************************************* @@ -116,4 +119,35 @@ public abstract class AbstractWidgetValueSource //////////////////////// } + + + /******************************************************************************* + ** Getter for inputValues + *******************************************************************************/ + public Map getInputValues() + { + return (this.inputValues); + } + + + + /******************************************************************************* + ** Setter for inputValues + *******************************************************************************/ + public void setInputValues(Map inputValues) + { + this.inputValues = inputValues; + } + + + + /******************************************************************************* + ** Fluent setter for inputValues + *******************************************************************************/ + public AbstractWidgetValueSource withInputValues(Map inputValues) + { + this.inputValues = inputValues; + return (this); + } + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java new file mode 100644 index 00000000..3e354936 --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java @@ -0,0 +1,100 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2023. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode; + + +import java.util.Map; +import com.kingsrook.qqq.backend.core.actions.queues.GetQueueSize; +import com.kingsrook.qqq.backend.core.context.QContext; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.logging.QLogger; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; +import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaData; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class QueueSizeWidgetValue extends AbstractWidgetValueSource +{ + private static final QLogger LOG = QLogger.getLogger(QueueSizeWidgetValue.class); + + private String queueName; + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public Object evaluate(Map context, RenderWidgetInput input) throws QException + { + QQueueMetaData queue = QContext.getQInstance().getQueue(queueName); + QQueueProviderMetaData queueProvider = QContext.getQInstance().getQueueProvider(queue.getProviderName()); + return (new GetQueueSize().getQueueSize(queueProvider, queue)); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public QueueSizeWidgetValue withName(String name) + { + setName(name); + return (this); + } + + + + /******************************************************************************* + ** Getter for queueName + *******************************************************************************/ + public String getQueueName() + { + return (this.queueName); + } + + + + /******************************************************************************* + ** Setter for queueName + *******************************************************************************/ + public void setQueueName(String queueName) + { + this.queueName = queueName; + } + + + + /******************************************************************************* + ** Fluent setter for queueName + *******************************************************************************/ + public QueueSizeWidgetValue withQueueName(String queueName) + { + this.queueName = queueName; + return (this); + } + +} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java new file mode 100644 index 00000000..384dd684 --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java @@ -0,0 +1,125 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2023. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode; + + +import java.io.Serializable; +import java.util.Map; +import java.util.function.Function; +import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class WidgetAdHocValue extends AbstractWidgetValueSource +{ + private QCodeReference codeReference; + + + + /******************************************************************************* + ** Constructor + ** + *******************************************************************************/ + public WidgetAdHocValue() + { + setType(getClass().getSimpleName()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public Object evaluate(Map context, RenderWidgetInput input) throws QException + { + if(inputValues != null) + { + context.putAll(inputValues); + } + + Function function = QCodeLoader.getFunction(codeReference); + Object result = function.apply(context); + return (result); + } + + + + /******************************************************************************* + ** Fluent setter for name + *******************************************************************************/ + @Override + public WidgetAdHocValue withName(String name) + { + setName(name); + return (this); + } + + + + /******************************************************************************* + ** Getter for codeReference + *******************************************************************************/ + public QCodeReference getCodeReference() + { + return (this.codeReference); + } + + + + /******************************************************************************* + ** Setter for codeReference + *******************************************************************************/ + public void setCodeReference(QCodeReference codeReference) + { + this.codeReference = codeReference; + } + + + + /******************************************************************************* + ** Fluent setter for codeReference + *******************************************************************************/ + public WidgetAdHocValue withCodeReference(QCodeReference codeReference) + { + this.codeReference = codeReference; + return (this); + } + + + + /******************************************************************************* + ** Fluent setter for inputValues + *******************************************************************************/ + @Override + public WidgetAdHocValue withInputValues(Map inputValues) + { + this.inputValues = inputValues; + return (this); + } + +} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetCalculation.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetCalculation.java index 56df2403..66650057 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetCalculation.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetCalculation.java @@ -74,14 +74,14 @@ public class WidgetCalculation extends AbstractWidgetValueSource { Instant now = Instant.now(); Instant then = ValueUtils.getValueAsInstant(context.get(valueNames.get(0))); - return (then.until(now, ChronoUnit.MINUTES)); + return (then == null ? null : then.until(now, ChronoUnit.MINUTES)); }), AGE_SECONDS((List valueNames, Map context) -> { Instant now = Instant.now(); Instant then = ValueUtils.getValueAsInstant(context.get(valueNames.get(0))); - return (then.until(now, ChronoUnit.SECONDS)); + return (then == null ? null : then.until(now, ChronoUnit.SECONDS)); }), PERCENT_CHANGE((List valueNames, Map context) -> @@ -92,8 +92,8 @@ public class WidgetCalculation extends AbstractWidgetValueSource /////////////////////////////////////////////// // 100 * ( (current - previous) / previous ) // /////////////////////////////////////////////// - BigDecimal difference = current.subtract(previous); - if(BigDecimal.ZERO.equals(previous)) + BigDecimal difference = current == null ? null : current.subtract(previous); + if(BigDecimal.ZERO.equals(previous) || difference == null) { return (null); }