diff --git a/hello-world-microservice/pom.xml b/hello-world-microservice/pom.xml index 4275338933..58ce746c34 100644 --- a/hello-world-microservice/pom.xml +++ b/hello-world-microservice/pom.xml @@ -30,6 +30,11 @@ pom import + + c8y.agents.lpwan.backend + lpwan-backend + ${c8y.version} + @@ -39,11 +44,27 @@ microservice-autoconfigure + + com.nsn.cumulocity.clients-java + java-client-model + + + + org.projectlombok + lombok + + org.springframework.boot spring-boot-starter-test test + + + c8y.opentelemetry.exporters + opentelemetry-metrics-exporters + ${c8y.version} + diff --git a/hello-world-microservice/src/main/configuration/cumulocity.json b/hello-world-microservice/src/main/configuration/cumulocity.json index 0ef08abd9a..bf7f1c5837 100644 --- a/hello-world-microservice/src/main/configuration/cumulocity.json +++ b/hello-world-microservice/src/main/configuration/cumulocity.json @@ -9,6 +9,28 @@ ], "roles":[ ], + "resources": { + "cpu": "1000m", + "memory": "1Gi" + }, + "billing" : { + "metrics" : [ + { + "name": "hwGaugeMetricStSt", + "type": "NUMBER", + "aggregation": { + "function": "LATEST" + } + }, + { + "name": "hwSumMetricStSt", + "type": "NUMBER", + "aggregation": { + "function": "SUM" + } + } + ] + }, "livenessProbe":{ "httpGet":{ "path": "/health", diff --git a/hello-world-microservice/src/main/java/c8y/example/helloworld/GaugeStorage.java b/hello-world-microservice/src/main/java/c8y/example/helloworld/GaugeStorage.java new file mode 100644 index 0000000000..d113241323 --- /dev/null +++ b/hello-world-microservice/src/main/java/c8y/example/helloworld/GaugeStorage.java @@ -0,0 +1,22 @@ +package c8y.example.helloworld; + +import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import lombok.Getter; +import lombok.Setter; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class GaugeStorage { + private List observableDoubleGaugeList = new ArrayList<>(); + + public List getObservableDoubleGaugeList() { + return observableDoubleGaugeList; + } + + public void addObservableGauge(ObservableDoubleGauge doubleGauge) { + observableDoubleGaugeList.add(doubleGauge); + } +} diff --git a/hello-world-microservice/src/main/java/c8y/example/helloworld/HelloWorldMain.java b/hello-world-microservice/src/main/java/c8y/example/helloworld/HelloWorldMain.java index 095319a9d7..7a9f8ea443 100644 --- a/hello-world-microservice/src/main/java/c8y/example/helloworld/HelloWorldMain.java +++ b/hello-world-microservice/src/main/java/c8y/example/helloworld/HelloWorldMain.java @@ -2,12 +2,18 @@ import com.cumulocity.microservice.autoconfigure.MicroserviceApplication; import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @MicroserviceApplication -@RestController +@ComponentScan(basePackages = { + "c8y.example.helloworld", + "com.cumulocity.exporters.platform", + "com.cumulocity.exporters.common" +}) public class HelloWorldMain { public static void main(String[] args) { diff --git a/hello-world-microservice/src/main/java/c8y/example/helloworld/InventoryController.java b/hello-world-microservice/src/main/java/c8y/example/helloworld/InventoryController.java new file mode 100644 index 0000000000..dd4d444220 --- /dev/null +++ b/hello-world-microservice/src/main/java/c8y/example/helloworld/InventoryController.java @@ -0,0 +1,86 @@ +package c8y.example.helloworld; + +import com.cumulocity.exporters.common.OpenTelemetryExporterStrategy; +import com.cumulocity.exporters.common.OpenTelemetryExporterStrategyEnum; +import com.cumulocity.exporters.common.OpenTelemetryExporterStrategyFactory; +import com.cumulocity.exporters.platform.ExportCompletedEvent; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; +import lombok.extern.slf4j.Slf4j; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Random; +import java.util.function.Consumer; + +@RestController +@Slf4j +public class InventoryController implements ApplicationListener { + private static String INSTRUMENTATION_SCOPE_NAME = HelloWorldMain.class.getName(); + + @Autowired + private OpenTelemetryExporterStrategyFactory exporterStrategyFactory; + +// @Autowired +// private OpenTelemetry openTelemetry; + + @Autowired + private GaugeStorage gaugeStorage; + + private Meter meter; + + @GetMapping("/gaugeMetric") + public String gaugeMetric() { + OpenTelemetryExporterStrategy openTelemetryExporterStrategy = exporterStrategyFactory.findStrategy(OpenTelemetryExporterStrategyEnum.PLATFORM); + OpenTelemetry openTelemetry = openTelemetryExporterStrategy.getOpenTelemetry(); + meter = openTelemetry.getMeter(INSTRUMENTATION_SCOPE_NAME); + Random random = new Random(); + int value = random.nextInt(20); + DateTime recordedTime = DateTime.now(); + log.info("Sending gaugeMetric with value {}", value); + ObservableDoubleGauge gauge = meter + .gaugeBuilder("hwGaugeMetricStSt") + .buildWithCallback( + getObservableDoubleMeasurementConsumer(value, recordedTime)); + gaugeStorage.addObservableGauge(gauge); + return "test"; + } + + private Consumer getObservableDoubleMeasurementConsumer(int value, DateTime recordedTime) { + return result -> result.record(value, Attributes.of(AttributeKey.stringKey(recordedTime.toString()), recordedTime.toString())); + } + + @GetMapping("/sumMetric") + public String sumMetric() { + OpenTelemetryExporterStrategy openTelemetryExporterStrategy = exporterStrategyFactory.findStrategy(OpenTelemetryExporterStrategyEnum.PLATFORM); + OpenTelemetry openTelemetry = openTelemetryExporterStrategy.getOpenTelemetry(); + meter = openTelemetry.getMeter(INSTRUMENTATION_SCOPE_NAME); + log.info("Sending sumMetric at {}", LocalDateTime.now()); + Random random = new Random(); + LongCounter sumCounter = meter.counterBuilder("hwSumMetricStSt") + .setUnit("units") + .build(); + sumCounter.add(10); + return "test"; + } + + @Override + public void onApplicationEvent(ExportCompletedEvent event) { + int metricCollectionSize = event.getMetricCollectionSize(); + List gaugeList = gaugeStorage.getObservableDoubleGaugeList(); + for(int metricIndex = 0; metricIndex < metricCollectionSize; metricIndex++) { + gaugeList.get(metricIndex).close(); + } + gaugeList.subList(0, metricCollectionSize).clear(); + } +} diff --git a/hello-world-microservice/src/main/resources/application.properties b/hello-world-microservice/src/main/resources/application.properties index e0d8b1b60c..45bba1ce64 100644 --- a/hello-world-microservice/src/main/resources/application.properties +++ b/hello-world-microservice/src/main/resources/application.properties @@ -1,6 +1,7 @@ application.name=hello-world -server.port=80 +server.port=12320 # This parameter is provided by platform for microservice deployed in cumulocity. # You can set it up to your dedicated cumulocity address. You can get one by trying free trial on www.cumulocity.com -C8Y.baseURL= +C8Y.baseURL=http://localhost:30080 +spring.main.allow-bean-definition-overriding=true