Loading .gitlab-ci.yml 0 → 100644 +40 −0 Original line number Diff line number Diff line include: - project: osl/code/org.etsi.osl.main ref: main file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_NAME == "main"' - project: osl/code/org.etsi.osl.main ref: develop file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_NAME == "develop"' - project: osl/code/org.etsi.osl.main ref: $CI_COMMIT_REF_NAME file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_PROTECTED == "true" && $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "develop"' - project: osl/code/org.etsi.osl.main ref: develop file: - ci-templates/default.yml - ci-templates/build_unprotected.yml rules: - if: '$CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "develop" && $CI_COMMIT_REF_PROTECTED == "false"' maven_build: extends: .maven_build docker_build: extends: .docker_build needs: - maven_build Dockerfile +13 −13 Original line number Diff line number Diff line # Build stage # ---------- Stage 1: Build ---------- FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /app WORKDIR /build # Copy pom.xml and download dependencies # Copy pom.xml and download dependencies first (cache layer) COPY pom.xml . RUN mvn dependency:go-offline RUN mvn dependency:go-offline -B # Copy source code # Copy the rest of the source code COPY src ./src # Build application # Build the Spring Boot executable JAR RUN mvn clean package -DskipTests # Runtime stage # ---------- Stage 2: Runtime ---------- FROM eclipse-temurin:17-jre-alpine WORKDIR /app # Create application directory RUN mkdir -p /opt/openslice/lib/ # Copy built JAR from builder stage COPY --from=builder /build/target/org.etsi.osl.mcp.backend-0.0.1-SNAPSHOT.jar app.jar # Copy the built JAR from the builder stage COPY --from=builder /app/target/org.etsi.osl.mcp.backend-0.0.1-SNAPSHOT.jar /opt/openslice/lib/app.jar # Expose port EXPOSE 11880 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:11880/actuator/health || exit 1 # Run application ENTRYPOINT ["java", "-jar", "app.jar"] CMD ["java", "-jar", "/opt/openslice/lib/app.jar"] docker-compose.yml +32 −3 Original line number Diff line number Diff line Loading @@ -29,17 +29,46 @@ services: ports: - "11880:11880" environment: # Server Configuration SERVER_PORT: 11880 SPRING_APPLICATION_NAME: osl-mcp-backend # AI Configuration SPRING_AI_OLLAMA_BASE_URL: http://ollama:11434 SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL: http://mcp-server:13015 SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_AUTHSERVER_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_ACTIVEMQ_BROKERURL: tcp://activemq:61616 SPRING_AI_OLLAMA_CHAT_MODEL: gpt-oss:20b SPRING_AI_OLLAMA_CHAT_TEMPERATURE: 0.7 # MCP Client Configuration SPRING_AI_MCP_CLIENT_TYPE: SYNC SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL: http://openslice-mcp:13015/sse # OAuth2/Keycloak Configuration SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_KEYCLOAK_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_KEYCLOAK_CLIENT_ID: osapiWebClientId # ActiveMQ Configuration SPRING_ACTIVEMQ_BROKER_URL: tcp://anartemis:61616?jms.watchTopicAdvisories=false SPRING_ACTIVEMQ_USER: artemis SPRING_ACTIVEMQ_PASSWORD: artemis # Logging Configuration LOGGING_LEVEL_ROOT: INFO LOGGING_LEVEL_OSL: DEBUG LOGGING_LEVEL_SPRING_AI: DEBUG depends_on: - ollama healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11880/actuator/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s volumes: ollama_data: networks: default: name: compose_back external: true pom.xml +4 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,10 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- security --> <dependency> Loading src/main/resources/application.yaml +20 −26 Original line number Diff line number Diff line server: port: 11880 port: ${SERVER_PORT:11880} spring: application: name: osl-mcp-backend name: ${SPRING_APPLICATION_NAME:osl-mcp-backend} ai: ollama: base-url: http://localhost:11434 base-url: ${SPRING_AI_OLLAMA_BASE_URL:http://localhost:11434} chat: options: model: gpt-oss:20b xmodel: qwen3:8b temperature: 0.7 model: ${SPRING_AI_OLLAMA_CHAT_MODEL:gpt-oss:20b} temperature: ${SPRING_AI_OLLAMA_CHAT_TEMPERATURE:0.7} mcp: client: type: SYNC # or ASYNC type: ${SPRING_AI_MCP_CLIENT_TYPE:SYNC} # or ASYNC streamable-http: connections: openslice-server: url: http://localhost:13015 url: ${SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL:http://localhost:13015} security: oauth2: resourceserver: jwt: issuer-uri: http://keycloak:8080/auth/realms/openslice issuer-uri: ${SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI:http://keycloak:8080/auth/realms/openslice} client: registration: keycloak: client-id: osapiWebClientId authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/keycloak" client-id: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_KEYCLOAK_CLIENT_ID:osapiWebClientId} scope: - openid - profile provider: keycloak provider: keycloak: issuer-uri: http://keycloak:8080/auth/realms/openslice authorization-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/auth token-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/token user-info-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/userinfo jwk-set-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/certs issuer-uri: ${SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_KEYCLOAK_ISSUER_URI:http://keycloak:8080/auth/realms/openslice} activemq: brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false user: artemis password: artemis brokerUrl: ${SPRING_ACTIVEMQ_BROKER_URL:tcp://localhost:61616?jms.watchTopicAdvisories=false} user: ${SPRING_ACTIVEMQ_USER:artemis} password: ${SPRING_ACTIVEMQ_PASSWORD:artemis} pool: enabled: true max-connections: 100 enabled: ${SPRING_ACTIVEMQ_POOL_ENABLED:true} max-connections: ${SPRING_ACTIVEMQ_POOL_MAX_CONNECTIONS:100} packages: trust-all: true trust-all: ${SPRING_ACTIVEMQ_PACKAGES_TRUST_ALL:true} logging: level: root: INFO org.etsi.osl.*: DEBUG org.springframework.ai.chat.client.advisor: DEBUG No newline at end of file root: ${LOGGING_LEVEL_ROOT:INFO} org.etsi.osl.*: ${LOGGING_LEVEL_OSL:DEBUG} org.springframework.ai.chat.client.advisor: ${LOGGING_LEVEL_SPRING_AI:DEBUG} No newline at end of file Loading
.gitlab-ci.yml 0 → 100644 +40 −0 Original line number Diff line number Diff line include: - project: osl/code/org.etsi.osl.main ref: main file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_NAME == "main"' - project: osl/code/org.etsi.osl.main ref: develop file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_NAME == "develop"' - project: osl/code/org.etsi.osl.main ref: $CI_COMMIT_REF_NAME file: - ci-templates/default.yml - ci-templates/build.yml rules: - if: '$CI_COMMIT_REF_PROTECTED == "true" && $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "develop"' - project: osl/code/org.etsi.osl.main ref: develop file: - ci-templates/default.yml - ci-templates/build_unprotected.yml rules: - if: '$CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "develop" && $CI_COMMIT_REF_PROTECTED == "false"' maven_build: extends: .maven_build docker_build: extends: .docker_build needs: - maven_build
Dockerfile +13 −13 Original line number Diff line number Diff line # Build stage # ---------- Stage 1: Build ---------- FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /app WORKDIR /build # Copy pom.xml and download dependencies # Copy pom.xml and download dependencies first (cache layer) COPY pom.xml . RUN mvn dependency:go-offline RUN mvn dependency:go-offline -B # Copy source code # Copy the rest of the source code COPY src ./src # Build application # Build the Spring Boot executable JAR RUN mvn clean package -DskipTests # Runtime stage # ---------- Stage 2: Runtime ---------- FROM eclipse-temurin:17-jre-alpine WORKDIR /app # Create application directory RUN mkdir -p /opt/openslice/lib/ # Copy built JAR from builder stage COPY --from=builder /build/target/org.etsi.osl.mcp.backend-0.0.1-SNAPSHOT.jar app.jar # Copy the built JAR from the builder stage COPY --from=builder /app/target/org.etsi.osl.mcp.backend-0.0.1-SNAPSHOT.jar /opt/openslice/lib/app.jar # Expose port EXPOSE 11880 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:11880/actuator/health || exit 1 # Run application ENTRYPOINT ["java", "-jar", "app.jar"] CMD ["java", "-jar", "/opt/openslice/lib/app.jar"]
docker-compose.yml +32 −3 Original line number Diff line number Diff line Loading @@ -29,17 +29,46 @@ services: ports: - "11880:11880" environment: # Server Configuration SERVER_PORT: 11880 SPRING_APPLICATION_NAME: osl-mcp-backend # AI Configuration SPRING_AI_OLLAMA_BASE_URL: http://ollama:11434 SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL: http://mcp-server:13015 SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_AUTHSERVER_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_ACTIVEMQ_BROKERURL: tcp://activemq:61616 SPRING_AI_OLLAMA_CHAT_MODEL: gpt-oss:20b SPRING_AI_OLLAMA_CHAT_TEMPERATURE: 0.7 # MCP Client Configuration SPRING_AI_MCP_CLIENT_TYPE: SYNC SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL: http://openslice-mcp:13015/sse # OAuth2/Keycloak Configuration SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_KEYCLOAK_ISSUER_URI: http://keycloak:8080/auth/realms/openslice SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_KEYCLOAK_CLIENT_ID: osapiWebClientId # ActiveMQ Configuration SPRING_ACTIVEMQ_BROKER_URL: tcp://anartemis:61616?jms.watchTopicAdvisories=false SPRING_ACTIVEMQ_USER: artemis SPRING_ACTIVEMQ_PASSWORD: artemis # Logging Configuration LOGGING_LEVEL_ROOT: INFO LOGGING_LEVEL_OSL: DEBUG LOGGING_LEVEL_SPRING_AI: DEBUG depends_on: - ollama healthcheck: test: ["CMD", "curl", "-f", "http://localhost:11880/actuator/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s volumes: ollama_data: networks: default: name: compose_back external: true
pom.xml +4 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,10 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- security --> <dependency> Loading
src/main/resources/application.yaml +20 −26 Original line number Diff line number Diff line server: port: 11880 port: ${SERVER_PORT:11880} spring: application: name: osl-mcp-backend name: ${SPRING_APPLICATION_NAME:osl-mcp-backend} ai: ollama: base-url: http://localhost:11434 base-url: ${SPRING_AI_OLLAMA_BASE_URL:http://localhost:11434} chat: options: model: gpt-oss:20b xmodel: qwen3:8b temperature: 0.7 model: ${SPRING_AI_OLLAMA_CHAT_MODEL:gpt-oss:20b} temperature: ${SPRING_AI_OLLAMA_CHAT_TEMPERATURE:0.7} mcp: client: type: SYNC # or ASYNC type: ${SPRING_AI_MCP_CLIENT_TYPE:SYNC} # or ASYNC streamable-http: connections: openslice-server: url: http://localhost:13015 url: ${SPRING_AI_MCP_CLIENT_STREAMABLE_HTTP_CONNECTIONS_OPENSLICE_SERVER_URL:http://localhost:13015} security: oauth2: resourceserver: jwt: issuer-uri: http://keycloak:8080/auth/realms/openslice issuer-uri: ${SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI:http://keycloak:8080/auth/realms/openslice} client: registration: keycloak: client-id: osapiWebClientId authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/keycloak" client-id: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_KEYCLOAK_CLIENT_ID:osapiWebClientId} scope: - openid - profile provider: keycloak provider: keycloak: issuer-uri: http://keycloak:8080/auth/realms/openslice authorization-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/auth token-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/token user-info-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/userinfo jwk-set-uri: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/certs issuer-uri: ${SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_KEYCLOAK_ISSUER_URI:http://keycloak:8080/auth/realms/openslice} activemq: brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false user: artemis password: artemis brokerUrl: ${SPRING_ACTIVEMQ_BROKER_URL:tcp://localhost:61616?jms.watchTopicAdvisories=false} user: ${SPRING_ACTIVEMQ_USER:artemis} password: ${SPRING_ACTIVEMQ_PASSWORD:artemis} pool: enabled: true max-connections: 100 enabled: ${SPRING_ACTIVEMQ_POOL_ENABLED:true} max-connections: ${SPRING_ACTIVEMQ_POOL_MAX_CONNECTIONS:100} packages: trust-all: true trust-all: ${SPRING_ACTIVEMQ_PACKAGES_TRUST_ALL:true} logging: level: root: INFO org.etsi.osl.*: DEBUG org.springframework.ai.chat.client.advisor: DEBUG No newline at end of file root: ${LOGGING_LEVEL_ROOT:INFO} org.etsi.osl.*: ${LOGGING_LEVEL_OSL:DEBUG} org.springframework.ai.chat.client.advisor: ${LOGGING_LEVEL_SPRING_AI:DEBUG} No newline at end of file