Last active
July 19, 2025 07:44
-
-
Save unclebean/8369123892c7689dd8b312771ecb3a1d to your computer and use it in GitHub Desktop.
AzurePemAuth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Resolve script location and app folder | |
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | |
| APP_ROOT="$(dirname "$SCRIPT_DIR")" | |
| JAR_FILE="$APP_ROOT/jar/"*.jar | |
| PID_FILE="$APP_ROOT/app.pid" | |
| start_app() { | |
| if [[ -f "$PID_FILE" && -e "/proc/$(cat "$PID_FILE")" ]]; then | |
| echo "App is already running with PID $(cat "$PID_FILE")" | |
| exit 1 | |
| fi | |
| echo "Starting app..." | |
| nohup "$JAR_FILE" > "$APP_ROOT/app.log" 2>&1 & | |
| echo $! > "$PID_FILE" | |
| echo "Started with PID $(cat "$PID_FILE")" | |
| } | |
| stop_app() { | |
| if [[ -f "$PID_FILE" ]]; then | |
| PID=$(cat "$PID_FILE") | |
| echo "Stopping app with PID $PID..." | |
| kill "$PID" | |
| rm -f "$PID_FILE" | |
| echo "App stopped." | |
| else | |
| echo "No PID file found. App may not be running." | |
| fi | |
| } | |
| status_app() { | |
| if [[ -f "$PID_FILE" && -e "/proc/$(cat "$PID_FILE")" ]]; then | |
| echo "App is running with PID $(cat "$PID_FILE")" | |
| else | |
| echo "App is not running." | |
| fi | |
| } | |
| case "$1" in | |
| start) | |
| start_app | |
| ;; | |
| stop) | |
| stop_app | |
| ;; | |
| restart) | |
| stop_app | |
| sleep 1 | |
| start_app | |
| ;; | |
| status) | |
| status_app | |
| ;; | |
| *) | |
| echo "Usage: $0 {start|stop|restart|status}" | |
| exit 1 | |
| ;; | |
| esac |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.microsoft.aad.msal4j.*; | |
| import java.io.*; | |
| import java.nio.file.*; | |
| import java.security.*; | |
| import java.security.cert.CertificateFactory; | |
| import java.security.cert.X509Certificate; | |
| import java.util.*; | |
| import java.util.concurrent.*; | |
| public class AzureCertAuth { | |
| public static void main(String[] args) throws Exception { | |
| String clientId = "<YOUR_CLIENT_ID>"; | |
| String tenantId = "<YOUR_TENANT_ID>"; | |
| String scope = "https://graph.microsoft.com/.default"; // or your resource | |
| String authority = "https://login.microsoftonline.com/" + tenantId; | |
| String certPath = "cert.pem"; | |
| String keyPath = "key.pem"; | |
| // Load certificate | |
| CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); | |
| X509Certificate cert = (X509Certificate) certFactory.generateCertificate( | |
| new FileInputStream(certPath)); | |
| // Load private key | |
| PrivateKey privateKey = loadPrivateKey(Files.readString(Paths.get(keyPath))); | |
| IClientCredential credential = ClientCredentialFactory.createFromCertificate(privateKey, cert); | |
| ConfidentialClientApplication app = ConfidentialClientApplication.builder(clientId, credential) | |
| .authority(authority) | |
| .build(); | |
| ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton(scope)).build(); | |
| CompletableFuture<IAuthenticationResult> future = app.acquireToken(parameters); | |
| String token = future.get().accessToken(); | |
| System.out.println("Access Token: " + token); | |
| } | |
| private static PrivateKey loadPrivateKey(String keyPem) throws Exception { | |
| String privKeyPEM = keyPem | |
| .replace("-----BEGIN PRIVATE KEY-----", "") | |
| .replace("-----END PRIVATE KEY-----", "") | |
| .replaceAll("\\s+", ""); | |
| byte[] decoded = Base64.getDecoder().decode(privKeyPEM); | |
| PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded); | |
| KeyFactory kf = KeyFactory.getInstance("RSA"); | |
| return kf.generatePrivate(keySpec); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.microsoft.aad.msal4j.*; | |
| import java.io.FileInputStream; | |
| import java.io.FileReader; | |
| import java.security.PrivateKey; | |
| import java.security.Security; | |
| import java.security.cert.CertificateFactory; | |
| import java.security.cert.X509Certificate; | |
| import java.util.Collections; | |
| import java.util.Set; | |
| import java.util.concurrent.CompletableFuture; | |
| import org.bouncycastle.jce.provider.BouncyCastleProvider; | |
| import org.bouncycastle.openssl.PEMKeyPair; | |
| import org.bouncycastle.openssl.PEMParser; | |
| import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; | |
| public class AzurePemAuth { | |
| public static void main(String[] args) throws Exception { | |
| String clientId = "<your-client-id>"; | |
| String tenantId = "<your-tenant-id>"; | |
| String authority = "https://login.microsoftonline.com/" + tenantId; | |
| String pemCertPath = "path/to/certificate.pem"; | |
| String pemKeyPath = "path/to/privatekey.key"; | |
| Security.addProvider(new BouncyCastleProvider()); | |
| // Load certificate (.pem) | |
| FileInputStream certInputStream = new FileInputStream(pemCertPath); | |
| CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); | |
| X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(certInputStream); | |
| // Load private key (.key) | |
| PEMParser pemParser = new PEMParser(new FileReader(pemKeyPath)); | |
| Object object = pemParser.readObject(); | |
| pemParser.close(); | |
| JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); | |
| PrivateKey privateKey; | |
| if (object instanceof PEMKeyPair) { | |
| privateKey = converter.getPrivateKey(((PEMKeyPair) object).getPrivateKeyInfo()); | |
| } else { | |
| throw new IllegalStateException("Unexpected object in PEM file: " + object.getClass().getName()); | |
| } | |
| // Create credential | |
| IClientCredential credential = ClientCredentialFactory.createFromCertificate(privateKey, certificate); | |
| // Configure MSAL client | |
| ConfidentialClientApplication app = ConfidentialClientApplication.builder(clientId, credential) | |
| .authority(authority) | |
| .build(); | |
| // Define the scopes | |
| Set<String> scopes = Collections.singleton("https://graph.microsoft.com/.default"); | |
| // Acquire token | |
| ClientCredentialParameters parameters = ClientCredentialParameters.builder(scopes).build(); | |
| CompletableFuture<IAuthenticationResult> future = app.acquireToken(parameters); | |
| IAuthenticationResult result = future.get(); | |
| System.out.println("Access Token: " + result.accessToken()); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static String convertToJson(String input) { | |
| input = input.substring(1, input.length() - 1).replace('“', '"').replace('”', '"'); | |
| StringBuilder json = new StringBuilder("{"); | |
| String[] parts = input.split(",\\s*"); | |
| for (int i = 0; i < parts.length; i++) { | |
| String[] kv = parts[i].split("="); | |
| if (kv.length != 2) continue; | |
| String key = kv[0].replace("\"", "").trim(); | |
| String value = kv[1].trim(); | |
| json.append("\"").append(key).append("\":"); | |
| // Detect number or keep as string | |
| if (value.matches("-?\\d+(\\.\\d+)?")) { | |
| json.append(value); | |
| } else { | |
| json.append("\"").append(value).append("\""); | |
| } | |
| if (i < parts.length - 1) { | |
| json.append(","); | |
| } | |
| } | |
| json.append("}"); | |
| return json.toString(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| task processShellScript(type: Copy) { | |
| from 'src/main/scripts' | |
| into "$buildDir/processed-scripts" | |
| include '*.sh' // include all shell scripts | |
| expand([ | |
| appName : 'myApp', | |
| appVersion : project.version, | |
| runUser : 'myuser' | |
| ]) | |
| filteringCharset = 'UTF-8' | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const axios = require('axios'); | |
| const AZURE_ENDPOINT = 'https://<your-resource>.openai.azure.com'; | |
| const DEPLOYMENT = 'gpt35'; // or gpt4 | |
| const API_KEY = '<your-api-key>'; | |
| const API_VERSION = '2024-02-15-preview'; | |
| async function extractFeePayload(userMessage) { | |
| const prompt = ` | |
| Extract a JSON object with these fields: | |
| - distributor_id: string (e.g., "distributor 1") | |
| - start_month: string in "YYYY-MM" format | |
| - end_month: string in "YYYY-MM" format | |
| Supported time inputs: | |
| - Specific month: "May 2024" → "start_month": "2024-05", "end_month": "2024-05" | |
| - Quarter: "first quarter of 2025" → "start_month": "2025-01", "end_month": "2025-03" | |
| - "Q3 2023" → "start_month": "2023-07", "end_month": "2023-09" | |
| Only return valid JSON. No markdown, explanation, or extra text. | |
| Instruction: "{user_input}" | |
| `; | |
| try { | |
| const response = await axios.post( | |
| `${AZURE_ENDPOINT}/openai/deployments/${DEPLOYMENT}/chat/completions?api-version=${API_VERSION}`, | |
| { | |
| messages: [{ role: 'user', content: prompt }], | |
| temperature: 0, | |
| max_tokens: 100 | |
| }, | |
| { | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'api-key': API_KEY | |
| } | |
| } | |
| ); | |
| const content = response.data.choices[0].message.content.trim(); | |
| // Try to parse the JSON response | |
| const json = JSON.parse(content); | |
| console.log('Parsed JSON:', json); | |
| return json; | |
| } catch (err) { | |
| console.error('Error:', err.response?.data || err.message); | |
| } | |
| } | |
| // Example usage | |
| extractFeePayload("Calculate trailer fee for distributor 1 in May 2024"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| JAR_DIR="$APP_ROOT/jar" | |
| JAR_FILE=$(find "$JAR_DIR" -maxdepth 1 -name "*.jar" | head -n 1) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| plugins { | |
| id 'java' | |
| id 'me.champeau.jmh' version '0.7.2' // or latest | |
| } | |
| dependencies { | |
| jmh 'org.openjdk.jmh:jmh-core:1.37' | |
| jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.37' | |
| } | |
| @Test | |
| public void testManualParserPerformance() { | |
| String input = "[“field1”=value1, “field2”=123]"; | |
| int iterations = 100_000; | |
| long start = System.nanoTime(); | |
| for (int i = 0; i < iterations; i++) { | |
| JsonConversionBenchmark bench = new JsonConversionBenchmark(); | |
| bench.convertToJson(input); | |
| } | |
| long end = System.nanoTime(); | |
| long durationMs = (end - start) / 1_000_000; | |
| System.out.println("Manual parser took: " + durationMs + " ms for " + iterations + " iterations"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static String regexToJson(String input) { | |
| "{" + | |
| input | |
| .substring(1, input.length() - 1) // remove [ ] | |
| .replaceAll("\"([^\"]+)\"=([^,\\]]+)", "\"$1\":\"$2\"") // wrap values in quotes | |
| + "}"; | |
| return "{" + | |
| input | |
| .substring(1, input.length() - 1) // Remove [] | |
| .replaceAll("\"([^\"]+)\"=([a-zA-Z_]+)", "\"$1\":\"$2\"") // String values | |
| .replaceAll("\"([^\"]+)\"=(\\d+(\\.\\d+)?)", "\"$1\":$2") // Numeric values | |
| + "}"; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| buildscript { | |
| dependencies { | |
| classpath "com.netflix.nebula:gradle-ospackage-plugin:9.4.0" | |
| } | |
| } | |
| subprojects { | |
| apply plugin: 'java' | |
| } | |
| plugins { | |
| id 'org.springframework.boot' version '3.2.4' | |
| id 'io.spring.dependency-management' version '1.1.4' | |
| id 'nebula.ospackage' version '9.4.0' | |
| } | |
| bootJar { | |
| archiveFileName = 'myapp.jar' | |
| launchScript() // Optional: adds a Linux-friendly startup script to the jar | |
| } | |
| ospackage { | |
| packageName = 'myapp' | |
| version = '1.0.0' | |
| release = '1' | |
| arch = NOARCH | |
| os = LINUX | |
| summary = 'My Spring Boot App' | |
| description = 'A sample Spring Boot app packaged as an RPM' | |
| // Target installation location | |
| into '/opt/myapp' | |
| // Use the fat JAR output | |
| from(bootJar) { | |
| into '' | |
| fileMode = 0755 | |
| } | |
| // Optional: external config | |
| from('src/main/resources/application.yml') { | |
| into 'config' | |
| } | |
| } | |
| ospackage { | |
| packageName = 'myapp' | |
| version = '1.0.0' | |
| release = '1' | |
| arch = NOARCH | |
| os = LINUX | |
| type = Rpm | |
| summary = 'My Spring Boot App' | |
| description = 'Spring Boot application packaged as an RPM' | |
| license = 'MIT' | |
| requires('java-17-openjdk') // or your required JDK | |
| into '/opt/myapp' | |
| from(bootJar.outputs.files) { | |
| into 'lib' | |
| } | |
| postInstall 'echo "Installation complete."' | |
| postUninstall 'echo "Uninstalled."' | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| sudo useradd --system --shell /bin/false --comment 'GitLab Runner' --create-home gitlab-runner | |
| gitlab-runner ALL=(ALL) NOPASSWD: ALL | |
| gitlab-runner ALL=(ALL) NOPASSWD: /bin/rpm, /usr/bin/yum, /usr/bin/dnf |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Delay access to ospackage extension until after evaluation | |
| gradle.projectsEvaluated { | |
| def rpmType = project.extensions.findByName("ospackage")?.rpmClass | |
| if (rpmType == null) { | |
| throw new GradleException("Cannot find ospackage.rpmClass. Make sure 'nebula.ospackage' plugin is applied.") | |
| } | |
| tasks.register("buildRpmApp", rpmType) { | |
| packageName = 'archive-auth-app' | |
| version = project.findProperty('rpmVersion') ?: '1.0.0' | |
| release = project.findProperty('rpmRelease') ?: '1' | |
| arch = NOARCH | |
| dependsOn project(':archive-auth').tasks.named('bootJar') | |
| from(project(':archive-auth').tasks.named('bootJar').get().outputs.files) { | |
| into '/app/archive-auth' | |
| } | |
| from('rpm/systemd') { | |
| include 'archive-auth-app.service' | |
| into '/usr/lib/systemd/system' | |
| fileMode = 0644 | |
| } | |
| preInstall file('scripts/preinstall.sh').text | |
| postInstall file('scripts/postinstall.sh').text | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| jacocoTestReport { | |
| dependsOn test | |
| reports { | |
| xml.required = true | |
| html.required = true | |
| } | |
| // Exclude data model or DTO classes from coverage | |
| classDirectories.setFrom( | |
| files(classDirectories.files.collect { fileTree(dir: it, exclude: [ | |
| '**/model/**', // Exclude entire model package | |
| '**/dto/**', // Exclude dto package | |
| '**/entity/**' // Exclude entity package | |
| ])}) | |
| ) | |
| } | |
| sonarqube { | |
| properties { | |
| // Example for 2 submodules: module-a and module-b | |
| property "sonar.coverage.jacoco.xmlReportPaths", | |
| "${projectDir}/module-a/build/reports/jacoco/test/jacocoTestReport.xml," + | |
| "${projectDir}/module-b/build/reports/jacoco/test/jacocoTestReport.xml" | |
| } | |
| } | |
| ext { | |
| jacocoExcludes = [ | |
| '**/model/**', | |
| '**/dto/**', | |
| '**/entity/**', | |
| '**/config/**' // Add more if needed | |
| ] | |
| } | |
| jacocoTestReport { | |
| dependsOn test | |
| reports { | |
| xml.required = true | |
| html.required = true | |
| } | |
| classDirectories.setFrom( | |
| files(classDirectories.files.collect { | |
| fileTree(dir: it, exclude: rootProject.jacocoExcludes) | |
| }) | |
| ) | |
| } | |
| jacocoRootReport { | |
| dependsOn jacocoMerge | |
| executionData.from = jacocoMerge.destinationFile | |
| classDirectories.setFrom( | |
| files(subprojects.collect { project -> | |
| fileTree(dir: "${project.buildDir}/classes/java/main", exclude: jacocoExcludes) | |
| }) | |
| ) | |
| sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs) | |
| additionalSourceDirs.from = files(subprojects.sourceSets.main.allSource.srcDirs) | |
| reports { | |
| xml.required = true | |
| html.required = true | |
| } | |
| } | |
| ------ | |
| task jacocoMerge(type: JacocoMerge) { | |
| dependsOn subprojects.test | |
| executionData fileTree(dir: '.', include: '**/build/jacoco/*.exec') | |
| } | |
| task jacocoRootReport(type: JacocoReport) { | |
| dependsOn jacocoMerge | |
| additionalSourceDirs.from = files(subprojects.sourceSets.main.allSource.srcDirs) | |
| sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs) | |
| classDirectories.from = files(subprojects.sourceSets.main.output) | |
| executionData.from = jacocoMerge.destinationFile | |
| reports { | |
| xml.required = true | |
| html.required = true | |
| } | |
| } | |
| sonarqube { | |
| properties { | |
| property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacocoRootReport/jacocoRootReport.xml" | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <configuration> | |
| <!-- Shared config (for all profiles) --> | |
| <include resource="org/springframework/boot/logging/logback/defaults.xml"/> | |
| <springProfile name="prod"> | |
| <property name="LOG_PATH" value="/var/log/myapp"/> | |
| <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |
| <file>${LOG_PATH}/myapp.log</file> | |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |
| <fileNamePattern>${LOG_PATH}/myapp.%d{yyyy-MM-dd}.log</fileNamePattern> | |
| <maxHistory>30</maxHistory> | |
| </rollingPolicy> | |
| <encoder> | |
| <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern> | |
| </encoder> | |
| </appender> | |
| <root level="INFO"> | |
| <appender-ref ref="FILE"/> | |
| </root> | |
| </springProfile> | |
| <springProfile name="!prod"> | |
| <root level="INFO"> | |
| <appender-ref ref="CONSOLE"/> | |
| </root> | |
| </springProfile> | |
| </configuration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| buildscript { | |
| repositories { | |
| mavenCentral() | |
| } | |
| dependencies { | |
| classpath("com.netflix.nebula:gradle-ospackage-plugin:11.4.0") | |
| } | |
| } | |
| apply(plugin = "com.netflix.nebula.ospackage") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| if [ "$(id -u)" -eq 0 ]; then | |
| echo "Stopping myapp.service as part of post-uninstall..." | |
| systemctl stop myapp.service || true | |
| else | |
| echo "Not root. Skipping systemctl stop in postuninstall." | |
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| SERVICE_NAME=your-app | |
| echo "Stopping $SERVICE_NAME if running..." | |
| if systemctl is-active --quiet "$SERVICE_NAME"; then | |
| systemctl stop "$SERVICE_NAME" | |
| fi | |
| #!/bin/bash | |
| SERVICE_NAME=your-app | |
| echo "Reloading systemd daemon..." | |
| systemctl daemon-reload | |
| echo "Enabling $SERVICE_NAME to start on boot..." | |
| systemctl enable "$SERVICE_NAME" | |
| echo "Starting $SERVICE_NAME..." | |
| systemctl start "$SERVICE_NAME" | |
| #!/bin/bash | |
| SERVICE_NAME=your-app | |
| echo "Stopping $SERVICE_NAME if it's running..." | |
| if systemctl is-active --quiet "$SERVICE_NAME"; then | |
| systemctl stop "$SERVICE_NAME" | |
| fi | |
| echo "Disabling $SERVICE_NAME..." | |
| systemctl disable "$SERVICE_NAME" || true | |
| echo "Reloading systemd to remove the unit..." | |
| systemctl daemon-reload | |
| preInstall = file("scripts/preinstall.sh") | |
| postInstall = file("scripts/postinstall.sh") | |
| postUninstall = file("scripts/postuninstall.sh") | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if systemctl list-units --full -all | grep -q 'myapp.service'; then | |
| echo "Service exists. Stopping..." | |
| sudo systemctl stop myapp.service | |
| else | |
| echo "Service myapp.service does not exist. Skipping stop." | |
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Unit] | |
| Description=My Spring Boot App | |
| After=network.target | |
| [Service] | |
| Type=simple | |
| User=myappuser | |
| Group=myappgroup | |
| WorkingDirectory=/opt/myapp | |
| ExecStart=/opt/myapp/myapp-1.0.0.jar --spring.config.additional-location=file:/etc/myapp/ --spring.profiles.active=prod | |
| SuccessExitStatus=143 | |
| Restart=on-failure | |
| RestartSec=5 | |
| [Install] | |
| WantedBy=multi-user.target | |
| ------ | |
| ospackage { | |
| ... | |
| from('src/rpm/systemd/myapp.service') { | |
| into '/etc/systemd/system' | |
| fileMode = 0644 | |
| } | |
| } | |
| -------- | |
| ospackage { | |
| ... | |
| postInstall """ | |
| systemctl daemon-reexec || true | |
| systemctl daemon-reload || true | |
| systemctl enable myapp || true | |
| """ | |
| postUninstall """ | |
| systemctl stop myapp || true | |
| systemctl disable myapp || true | |
| systemctl daemon-reload || true | |
| """ | |
| } | |
| ---- | |
| logging: | |
| file: | |
| name: /var/log/myapp/myapp.log | |
| ----- | |
| ospackage { | |
| ... | |
| from('src/rpm/logs') { | |
| into '/var/log/myapp' | |
| fileMode = 0755 | |
| user = 'myappuser' | |
| permissionGroup = 'myappgroup' | |
| } | |
| } | |
| ----- | |
| [Service] | |
| StandardOutput=append:/var/log/myapp/stdout.log | |
| StandardError=append:/var/log/myapp/stderr.log | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Unit] | |
| Description=Your Spring Boot App | |
| After=network.target | |
| [Service] | |
| Type=forking | |
| ExecStart=/opt/app/latest/bin/start-app.sh start | |
| ExecStop=/opt/app/latest/bin/start-app.sh stop | |
| ExecReload=/opt/app/latest/bin/start-app.sh restart | |
| PIDFile=/opt/app/latest/app.pid | |
| User=your-linux-user | |
| Group=your-linux-group | |
| Restart=on-failure | |
| [Install] | |
| WantedBy=multi-user.target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Dspring.profiles.active=prod" | |
| exec ./myapp.jar $JAVA_OPTS | |
| ExecStartPre=/bin/sleep 10 | |
| ConditionPathExists=/app/myapp.jar | |
| sudo useradd \ | |
| --system \ | |
| --home /home/gitlab-runner \ | |
| --shell /usr/sbin/nologin \ | |
| gitlab-runner | |
| ConditionUser=myappuser |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Bean | |
| public WebMvcConfigurer corsConfigurer() { | |
| return new WebMvcConfigurer() { | |
| @Override | |
| public void addCorsMappings(CorsRegistry registry) { | |
| registry.addMapping("/**") // Allow all paths | |
| .allowedOrigins("http://localhost:3000") // frontend origin | |
| .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") | |
| .allowedHeaders("*") | |
| .allowCredentials(true); // if using cookies or auth headers | |
| } | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment