Skip to content

Instantly share code, notes, and snippets.

@unclebean
Last active July 19, 2025 07:44
Show Gist options
  • Select an option

  • Save unclebean/8369123892c7689dd8b312771ecb3a1d to your computer and use it in GitHub Desktop.

Select an option

Save unclebean/8369123892c7689dd8b312771ecb3a1d to your computer and use it in GitHub Desktop.
AzurePemAuth
#!/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
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);
}
}
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());
}
}
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();
}
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'
}
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");
JAR_DIR="$APP_ROOT/jar"
JAR_FILE=$(find "$JAR_DIR" -maxdepth 1 -name "*.jar" | head -n 1)
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");
}
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
+ "}";
}
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."'
}
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
// 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
}
}
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"
}
}
<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>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.netflix.nebula:gradle-ospackage-plugin:11.4.0")
}
}
apply(plugin = "com.netflix.nebula.ospackage")
#!/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
#!/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")
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
[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
[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
#!/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
@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