All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.commercetools.queue.gcp.pubsub.PubSubStatsFetcher.scala Maven / Gradle / Ivy

/*
 * Copyright 2024 Commercetools GmbH
 *
 * 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 com.commercetools.queue.gcp.pubsub

import cats.effect.Async
import cats.syntax.flatMap._
import com.commercetools.queue.{MalformedQueueConfigurationException, QueueStats, UnsealedQueueStatsFetcher}
import com.google.cloud.monitoring.v3.stub.MetricServiceStub
import com.google.monitoring.v3.{ListTimeSeriesRequest, Point, TimeInterval}
import com.google.protobuf.Timestamp
import com.google.pubsub.v1.SubscriptionName

import scala.jdk.CollectionConverters._

private class PubSubStatsFetcher[F[_]](
  val queueName: String,
  subscriptionName: SubscriptionName,
  client: MetricServiceStub
)(implicit F: Async[F])
  extends UnsealedQueueStatsFetcher[F] {

  override def fetch: F[QueueStats] =
    F.realTime
      .flatMap { now =>
        wrapFuture(F.delay {
          client
            .listTimeSeriesCallable()
            .futureCall(
              ListTimeSeriesRequest
                .newBuilder()
                .setName(s"projects/${subscriptionName.getProject()}")
                // we need to query at least one minute
                // https://stackoverflow.com/questions/68546947/google-cloud-metrics-get-pub-sub-metric-filtered-by-subscription-id
                .setInterval(
                  TimeInterval
                    .newBuilder()
                    .setStartTime(Timestamp.newBuilder().setSeconds(now.toSeconds - 61).build())
                    .setEndTime(Timestamp.newBuilder().setSeconds(now.toSeconds).build())
                    .build())
                .setFilter(
                  s"""metric.type="pubsub.googleapis.com/subscription/num_undelivered_messages" AND resource.label.subscription_id = "${subscriptionName
                      .getSubscription()}"""")
                .build())

        })
      }
      .flatMap { response =>
        if (response.getTimeSeriesCount == 0) F.pure(QueueStats(0, None, None))
        else {
          val datapoints: List[Point] = response.getTimeSeries(0).getPointsList().asScala.toList
          datapoints.sortBy(-_.getInterval().getEndTime().getSeconds()).headOption match {
            case Some(value) =>
              F.pure(QueueStats(value.getValue().getInt64Value().toInt, None, None))
            case None =>
              F.raiseError(MalformedQueueConfigurationException(queueName, "messages", ""))
          }
        }
      }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy