Added MCSLA M24

parent 03230f60
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
*.iml
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
### Eclipse template
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
stages:
- build
- deploy
build:
stage: build
tags:
- docker
image: maven:3.6.0-jdk-10
script:
- "mvn clean package -U -B -DskipTests"
only:
- master
artifacts:
paths:
- target
register:
stage: deploy
tags:
- docker
image: docker:latest
variables:
DOCKER_DRIVER: overlay2
services:
- docker:dind
only:
- master
script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
FROM openjdk:8-jre
ENV VERTICLE_FILE mcsla-service-fat.jar
# Set the location of the verticles
ENV VERTICLE_HOME /usr/verticles
EXPOSE 8080
RUN addgroup --system vertx && adduser --system --group vertx
# Copy your fat jar to the container
COPY target/$VERTICLE_FILE $VERTICLE_HOME/
RUN chown -R vertx $VERTICLE_HOME
RUN chmod -R g+w $VERTICLE_HOME
USER vertx
# Launch the verticle
WORKDIR $VERTICLE_HOME
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -Xmx2048m -jar $VERTICLE_FILE -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory -Dvertx.metrics.options.enabled=true"]
This diff is collapsed.
# DECIDE MCSLA Service
## Build
Clone repo and build with maven.
```bash
$ git clone https://gitlab.fokus.fraunhofer.de/DECIDE/mcsla-service.git
$ cd mcsla-service
$ mvn clean package
```
You will find the built artifacts in the `target` directory.
## Install
No installation required. To run the service, do:
```bash
$ java -jar target/mcsla-service
```
## Configuration
The following environment variables are read:
* DECIDE_REPOS_BASE_DIR
The path to the base for cloning remote repositories
* DECIDE_ACSMI_DISCOVERY_SERVICE_URI
The address of the ACSmI discovery service
## Docker
```bash
$ docker build -t decide/mcsla-service .
$ docker run -it -p 8080:8080 decide/mcsla-service
```
## Interface
The root context shows the OpenAPI documentation.
## License
[GNU Affero General Public License Version 3](LICENSE.txt)
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.DECIDEh2020</groupId>
<artifactId>mcsla-service</artifactId>
<version>0.0.5-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<vertx.version>3.5.4</vertx.version>
<main.verticle>eu.DECIDEh2020.mcsla.service.MainVerticle</main.verticle>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-dependencies</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-api-contract</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-health-check</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-dropwizard-metrics</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-rx-java2</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>eu.DECIDEh2020</groupId>
<artifactId>app-controller</artifactId>
<version>0.0.16-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.DECIDEh2020</groupId>
<artifactId>mcsla-core</artifactId>
<version>0.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
<useIncrementalCompilation>false</useIncrementalCompilation>
<annotationProcessors>
<annotationProcessor>io.vertx.codegen.CodeGenProcessor</annotationProcessor>
</annotationProcessors>
<generatedSourcesDirectory>${project.basedir}/src/main/generated</generatedSourcesDirectory>
<compilerArgs>
<arg>-Acodegen.output=${project.basedir}/src/main</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>${project.basedir}/src/main/generated</directory>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource>
</transformer>
</transformers>
<outputFile>${project.build.directory}/${project.artifactId}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
/*
* Copyright (c) 2017 Fraunhofer FOKUS.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the
* GNU AGPL v3 which accompanies
* this distribution, and is available at
* http://www.gnu.org/licenses/agpl.txt
*
* Contributors:
* Simon Dutkowski Fraunhofer FOKUS
*
* Initially developed in the context of DECIDE EU project www.DECIDE-h2020.eu
*/
package eu.DECIDEh2020.mcsla.service.repositories;
import io.vertx.codegen.annotations.Fluent;
import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpRequest;
import java.nio.file.Path;
import java.util.List;
@ProxyGen
public interface RepositoriesService {
static RepositoriesService create(Path base, HttpRequest<Buffer> acsmiRequest, Handler<AsyncResult<RepositoriesService>> readyHandler) {
return new RepositoriesServiceImpl(base, acsmiRequest, readyHandler);
}
static RepositoriesService createProxy(Vertx vertx, String address) {
return new RepositoriesServiceVertxEBProxy(vertx, address);
}
@Fluent
RepositoriesService isLocal(String appName, Handler<AsyncResult<Boolean>> handler);
@Fluent
RepositoriesService initRepository(String ref, String token, String username, String password, Handler<AsyncResult<JsonObject>> handler);
@Fluent
RepositoriesService getApplication(String AppName, Handler<AsyncResult<JsonObject>> handler);
@Fluent
RepositoriesService resetApplication(String AppName, Handler<AsyncResult<JsonObject>> handler);
@Fluent
RepositoriesService updateMcsla(String appName, JsonObject mcsla, Handler<AsyncResult<JsonObject>> handler);
@Fluent
RepositoriesService aggregateServiceObjectives(String name, String termName, String predefined, Handler<AsyncResult<JsonObject>> handler);
}
/*
* Copyright (c) 2017 Fraunhofer FOKUS.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the
* GNU AGPL v3 which accompanies
* this distribution, and is available at
* http://www.gnu.org/licenses/agpl.txt
*
* Contributors:
* Simon Dutkowski Fraunhofer FOKUS
*
* Initially developed in the context of DECIDE EU project www.DECIDE-h2020.eu
*/
package eu.DECIDEh2020.mcsla.service.repositories;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.WebClient;
import io.vertx.serviceproxy.ServiceBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.*;
public class RepositoriesVerticle extends AbstractVerticle {
private Logger log = LoggerFactory.getLogger(getClass());
@Override
public void start(Future<Void> startFuture) {
String baseDir = config().getString("DECIDE_REPOS_BASE_DIR");
String acsmiUri = config().getString("DECIDE_ACSMI_DISCOVERY_SERVICE_URI");
Path base = null;
try {
base = baseDir != null ? Paths.get(baseDir) : Files.createTempDirectory("mcsla_");
} catch (IOException e) {
log.error("creating temp base directory", e);
}
HttpRequest<Buffer> acsmiRequest = null;
if (acsmiUri != null && !acsmiUri.isEmpty()) {
WebClient acsmiClient = WebClient.create(vertx);
acsmiRequest = acsmiClient.getAbs(acsmiUri + "/acsmiservices/api/services/nfr");
}
RepositoriesService.create(base, acsmiRequest, ready -> {
if (ready.succeeded()) {
new ServiceBinder(vertx).setAddress("decide.mcsla.service.repositories.queue").register(RepositoriesService.class, ready.result());
log.debug("repositories service bound");
startFuture.complete();
} else {
startFuture.fail(ready.cause());
}
});
log.debug("repositories verticle started");
}
}
/*
* Copyright (c) 2017 Fraunhofer FOKUS.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the
* GNU AGPL v3 which accompanies
* this distribution, and is available at
* http://www.gnu.org/licenses/agpl.txt
*
* Contributors:
* Simon Dutkowski Fraunhofer FOKUS
*
* Initially developed in the context of DECIDE EU project www.DECIDE-h2020.eu
*/
package eu.DECIDEh2020.mcsla.service.repositories;
import eu.DECIDEh2020.appManager.models.*;
import eu.DECIDEh2020.mcsla.core.metrics.Expressions;
import eu.DECIDEh2020.mcsla.core.metrics.Predefined;
import eu.DECIDEh2020.mcsla.core.metrics.Statement;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
public class SlaFactory {
static SlaFactory getInstance() {
return new SlaFactory();
}
public Sla createFromNfrs(List<Nfr> nfrs, List<Microservice> microservices) {
Sla sla = new Sla();
sla.getObjectives().addAll(nfrs.stream().map(nfr -> toServiceObjective(nfr, microservices)).collect(Collectors.toList()));
return sla;
}
private ServiceObjective toServiceObjective(Nfr nfr, List<Microservice> microservices) {
ServiceObjective objective = new ServiceObjective();
objective.setTermName(nfr.getType());
if (nfr instanceof AvailabilityNfr) {
AvailabilityNfr availability = (AvailabilityNfr)nfr;
objective.setType("slo");
objective.setValue(String.valueOf(availability.getValue()));
objective.setUnit(availability.getUnit());
objective.setConditionStatement(Statement.greaterOrEqual.name());
Metric metric = new Metric();
metric.setId("CSA_AV_001");
metric.setScale("ratio");
metric.setDescriptor("Aggregation of microservices");
Expression expression = new Expression();
expression.setExpression(Predefined.AVAILABILITY_AGGREGATION_SUMTYPE.name());
expression.setExpressionLanguage(Expressions.LANGUAGE_PREDEFINED);
expression.setNote(Predefined.AVAILABILITY_AGGREGATION_SUMTYPE.note());
expression.setUnit(availability.getUnit());
metric.setExpression(expression);
for (Microservice microservice : microservices) {
Metric msMetric = new Metric();
msMetric.setId(microservice.getId());
msMetric.setNote(microservice.getName());
msMetric.setDescriptor("Availability based on meantime between failure and meantime between recovery");
msMetric.setScale("ratio");
msMetric.setExpression(new Expression());
msMetric.getExpression().setExpressionLanguage(Expressions.LANGUAGE_PREDEFINED);
msMetric.getExpression().setExpression(Predefined.AVAILABILITY_MTBFMTTR.name());
msMetric.getExpression().setUnit("percentage");
msMetric.getExpression().setNote(Predefined.AVAILABILITY_MTBFMTTR.note());
metric.getUnderlyingMetrics().add(msMetric);
}
objective.getMetrics().add(metric);
} else if (nfr instanceof PerformanceNfr) {
PerformanceNfr performance = (PerformanceNfr)nfr;
objective.setType("slo");
objective.setValue(String.valueOf(performance.getValue()));
objective.setUnit(performance.getUnit());
objective.setConditionStatement(Statement.lessOrEqual.name());
Metric metric = new Metric();
metric.setId("CSA_PE_001");
metric.setDescriptor("Maximum response time for a request");
metric.setScale("ratio");
Expression expression = new Expression();
expression.setExpression(Predefined.AGGREGATION_MAXTYPE.name());
expression.setExpressionLanguage(Expressions.LANGUAGE_PREDEFINED);
expression.setNote(Predefined.AGGREGATION_MAXTYPE.note());
expression.setUnit(performance.getUnit());
metric.setExpression(expression);
for (Microservice microservice : microservices) {
Metric msMetric = new Metric();
msMetric.setId(microservice.getId());
msMetric.setNote(microservice.getName());
msMetric.setScale("ratio");
msMetric.setExpression(new Expression());
msMetric.getExpression().setExpressionLanguage(Expressions.LANGUAGE_PREDEFINED);
msMetric.getExpression().setExpression(Predefined.EMPTY.name());
msMetric.getExpression().setNote(Predefined.EMPTY.note());
msMetric.getExpression().setUnit("millisecond");
metric.getUnderlyingMetrics().add(msMetric);
}
objective.getMetrics().add(metric);
} else if (nfr instanceof ScalabilityNfr) {
ScalabilityNfr scalability = (ScalabilityNfr)nfr;
objective.setType("sqo");
objective.setValue(String.valueOf(scalability.getValue()));
objective.setConditionStatement(Statement.equal.name());
} else if (nfr instanceof LocationNfr) {
LocationNfr location = (LocationNfr)nfr;
objective.setType("sqo");
objective.setValue(location.getValue().get(0));
objective.setConditionStatement(Statement.equal.name());
} else if (nfr instanceof CostNfr) {
CostNfr cost = (CostNfr)nfr;
objective.setType("slo");
objective.setValue(String.valueOf(cost.getValue()));
objective.setUnit(cost.getUnit());
objective.setConditionStatement(Statement.less.name());
Metric metric = new Metric();
metric.setId("CSA_CO_001");
metric.setDescriptor("Sum of all costs");
metric.setScale("ratio");
Expression expression = new Expression();
expression.setExpression(Predefined.AGGREGATION_SUMTYPE.name());
expression.setNote(Predefined.AGGREGATION_SUMTYPE.note());
expression.setExpressionLanguage(Expressions.LANGUAGE_PREDEFINED);
expression.setUnit(cost.getUnit());
metric.setExpression(expression);
objective.getMetrics().add(metric);
}
return objective;
}
}
/*
* Copyright (c) 2017 Fraunhofer FOKUS.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the
* GNU AGPL v3 which accompanies
* this distribution, and is available at
* http://www.gnu.org/licenses/agpl.txt
*
* Contributors:
* Simon Dutkowski Fraunhofer FOKUS
*
* Initially developed in the context of DECIDE EU project www.DECIDE-h2020.eu
*/
package eu.DECIDEh2020.mcsla.service.repositories;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.DECIDEh2020.appManager.models.Expression;
import eu.DECIDEh2020.appManager.models.Metric;
import eu.DECIDEh2020.appManager.models.ServiceObjective;
import eu.DECIDEh2020.appManager.models.Sla;
import eu.DECIDEh2020.mcsla.core.metrics.Expressions;
import eu.DECIDEh2020.mcsla.core.metrics.Predefined;
import eu.DECIDEh2020.mcsla.core.metrics.Statement;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;