Menggunakan tombol fitur App Lifecycle Manager dengan Java

Panduan ini menjelaskan cara mengintegrasikan aplikasi Java Anda dengan flag fitur App Lifecycle Manager. Anda akan mempelajari cara menggunakan OpenFeature SDK dengan penyedia flagd untuk mengevaluasi flag yang dikelola oleh App Lifecycle Manager, sehingga Anda dapat mengontrol ketersediaan dan perilaku fitur secara dinamis di layanan Java Anda.

Panduan ini mengasumsikan Anda telah menyiapkan resource App Lifecycle Manager yang diperlukan (seperti penawaran SaaS, jenis unit, unit, flag, dan peluncuran) dengan menyelesaikan salah satu panduan memulai cepat berikut:

Prasyarat

Sebelum memulai, pastikan Anda memiliki hal-hal berikut:

  1. Java yang diinstal: JDK 17 atau yang lebih baru.
  2. Menyelesaikan Panduan memulai flag fitur App Lifecycle Manager:
    • Berhasil menyelesaikan panduan memulai flag fitur terintegrasi atau mandiri untuk menyediakan unit target Anda.
    • Anda harus memiliki variabel atau nilai lingkungan dari panduan memulai cepat tersebut, seperti PROJECT_ID, LOCATION_1 (wilayah Unit Anda), UNIT_ID, dan FLAG_KEY.
  3. Mengautentikasi gcloud untuk Kredensial Default Aplikasi (ADC): Aplikasi Java menggunakan ADC untuk mengautentikasi dengan layanan Google Cloud . Pastikan Anda telah melakukan autentikasi di lingkungan Anda:

    gcloud auth application-default login
    
  4. Izin IAM: Identitas yang menjalankan aplikasi Java Anda memerlukan peran Identity and Access Management roles/saasconfig.viewer di project Google Cloud Anda untuk membaca konfigurasi flag:

    gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
        --member="user:YOUR_EMAIL_ADDRESS" \
        --role="roles/saasconfig.viewer"
    

    Ganti YOUR_PROJECT_ID dan YOUR_EMAIL_ADDRESS yang sesuai.

Memahami variabel lingkungan utama

Aplikasi Java Anda mengandalkan variabel lingkungan untuk terhubung ke konfigurasi flag yang benar.

  • FLAGD_SOURCE_PROVIDER_ID: Menentukan konfigurasi tombol fitur mana yang akan diambil dari layanan App Lifecycle Manager. Nilai ini harus berupa nama resource lengkap dari FeatureFlagConfig yang terkait dengan unit Anda.
    • Format: projects/PROJECT_ID/locations/LOCATION/featureFlagsConfigs/UNIT_ID
    • Contoh: projects/my-gcp-project/locations/us-central1/featureFlagsConfigs/my-app-instance-01

Menyiapkan project Java

Sebelum dapat menjalankan aplikasi, Anda harus melakukan inisialisasi project dan mengonfigurasi dependensi yang diperlukan.

  1. Buat direktori project:

    mkdir java-featureflag-app
    cd java-featureflag-app
    
  2. Tambahkan dependensi: Konfigurasi sistem build Anda (Maven atau Gradle) untuk menyertakan library berikut. Pastikan kompatibilitas dengan menggunakan versi yang lebih tinggi dari OpenFeature 1.14.1, flagd 0.11.5, dan gRPC 1.71.0.

    • dev.openfeature:javasdk:1.14.1+
    • dev.openfeature.contrib.providers:flagd:0.11.5+
    • io.grpc:grpc-netty-shaded:1.71.0+
    • io.grpc:grpc-auth:1.71.0+
    • com.google.auth:google-auth-library-oauth2-http
  3. Buat kode inisialisasi: Tambahkan file bernama FeatureManagement.java dengan konten berikut. Class ini menyiapkan interseptor gRPC untuk melampirkan header ADC dan perutean regional, serta menginisialisasi FlagdProvider menggunakan resolusi dalam proses.

    import com.google.auth.oauth2.GoogleCredentials;
    import dev.openfeature.contrib.providers.flagd.Config;
    import dev.openfeature.contrib.providers.flagd.FlagdOptions;
    import dev.openfeature.contrib.providers.flagd.FlagdProvider;
    import dev.openfeature.sdk.OpenFeatureAPI;
    import io.grpc.*;
    import io.grpc.auth.MoreCallCredentials;
    import java.util.ArrayList;
    import java.util.List;
    
    public class FeatureManagement {
        public static void initialize() throws Exception {
            // Read the full Unit resource name
            String flagConfigId = System.getenv("FLAGD_SOURCE_PROVIDER_ID");
            if (flagConfigId == null || flagConfigId.isEmpty()) {
                throw new IllegalStateException("FLAGD_SOURCE_PROVIDER_ID environment variable is not set.");
            }
    
            // Configure gRPC Security and Routing
            GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
            CallCredentials callCredentials = MoreCallCredentials.from(credentials);
    
            List<ClientInterceptor> interceptors = new ArrayList<>();
    
            // Interceptor to inject the Unit name into headers for regional routing
            interceptors.add(new ClientInterceptor() {
                @Override
                public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
                    return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
                        @Override
                        public void start(Listener<RespT> responseListener, Metadata headers) {
                            headers.put(Metadata.Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER), "name=" + flagConfigId);
                            super.start(responseListener, headers);
                        }
                    };
                }
            });
    
            // Interceptor to attach ADC to the gRPC calls
            interceptors.add(new ClientInterceptor() {
                @Override
                public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
                    return next.newCall(method, callOptions.withCallCredentials(callCredentials));
                }
            });
    
            // Initialize the flagd provider with In-Process resolution
            FlagdProvider provider = new FlagdProvider(
                FlagdOptions.builder()
                    .resolverType(Config.Resolver.IN_PROCESS)
                    .host("saasconfig.googleapis.com").port(443)
                    .tls(true)
                    .providerId(flagConfigId)
                    .clientInterceptors(interceptors)
                    .syncMetadataDisabled(true)
                    .deadline(10000)
                    .build()
            );
    
            // Set the global provider
            OpenFeatureAPI.getInstance().setProviderAndWait(provider);
        }
    }
    
  4. Buat logika aplikasi: Tambahkan file bernama Main.java dengan konten berikut untuk mengeksekusi evaluasi flag.

    import dev.openfeature.sdk.OpenFeatureAPI;
    import dev.openfeature.sdk.MutableContext;
    
    public class Main {
        public static void main(String[] args) throws Exception {
    
        // 1. Get Client
        var client = OpenFeatureAPI.getInstance().getClient("simple-api");
    
        // 2. Create Evaluation Context 
        var context = new dev.openfeature.sdk.MutableContext();
    
        // 3. Evaluate Flag
        // Default to false if evaluation fails or service is unreachable
        boolean isEnhanced = client.getBooleanValue("enhanced-search", false, context);
    
        // 4. Execute business logic based on result
        if (isEnhanced) {
            System.out.println("Executing enhanced search algorithm...");
        } else {
            System.out.println("Standard search algorithm...");
        }
    
        }
    }
    

Jalankan aplikasi Java

Anda dapat menjalankan aplikasi secara lokal menggunakan konfigurasi mandiri atau di-deploy sebagai container.

Menjalankan secara mandiri (secara lokal)

  1. Tetapkan variabel lingkungan:

    export PROJECT_ID="your-gcp-project-id"
    export LOCATION_1="us-central1"
    export UNIT_ID="my-app-instance-01"
    export FLAGD_SOURCE_PROVIDER_ID="projects/${PROJECT_ID}/locations/${LOCATION_1}/featureFlagsConfigs/${UNIT_ID}"
    
  2. Jalankan aplikasi: Jalankan project menggunakan perintah alat build pilihan Anda (misalnya, mvn compile exec:java atau ./gradlew run).

Menjalankan aplikasi terintegrasi (dalam container)

  1. Buat Dockerfile: Tentukan build container yang mengemas biner Java.

    FROM maven:3.9-eclipse-temurin-17 AS builder
    WORKDIR /app
    COPY pom.xml .
    COPY src ./src
    RUN mvn clean package
    
    FROM eclipse-temurin:17-jre
    WORKDIR /app
    COPY --from=builder /app/target/java-featureflag-app.jar app.jar
    ENTRYPOINT ["java", "-jar", "app.jar"]
    
  2. Bangun dan kirim image:

    export PROJECT_ID="your-gcp-project-id"
    docker build -t gcr.io/${PROJECT_ID}/my-java-app:latest .
    docker push gcr.io/${PROJECT_ID}/my-java-app:latest
    
  3. Deploy layanan: Perbarui cetak biru unit Anda untuk mereferensikan gcr.io/${PROJECT_ID}/my-java-app:latest dan deploy rilis baru menggunakan peluncuran App Lifecycle Manager.

Memverifikasi perubahan tanda

Setelah aplikasi Anda berjalan, pastikan aplikasi mengevaluasi flag dengan benar.

  1. Amati nilai awal: Verifikasi bahwa output konsol mencatat nilai yang dievaluasi sesuai dengan status konfigurasi awal.
  2. Perbarui tanda di Pengelola Siklus Proses Aplikasi: Ubah payload tanda atau aturan penargetan menggunakan konsol Google Cloud atau gcloud.
  3. Verifikasi nilai yang diperbarui: Jalankan kembali eksekusi lokal atau amati log penampung untuk mengonfirmasi status evaluasi baru.

Langkah berikutnya