001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2026 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.test.util; 011 012import jakarta.annotation.Nonnull; 013import jakarta.annotation.Nullable; 014 015import java.io.FileInputStream; 016import java.io.IOException; 017import java.io.InputStream; 018import java.util.HashMap; 019import java.util.Map; 020import java.util.Properties; 021 022/** 023 * Utility class for handling properties file operations in tests. 024 */ 025// Created by Claude Sonnet 4 026public class PropertiesTestUtil { 027 028 /** 029 * Loads a properties file and extracts port configurations organized by module type and module ID. 030 * 031 * @param thePropertiesLocation the path to the properties file. Can be a regular file path or a classpath resource prefixed with "classpath:" 032 * @return a map where the key is module type and the value is a map of module ID to port number 033 * @throws RuntimeException if the properties file cannot be read 034 */ 035 public static Map<String, Map<String, Integer>> loadPortsFromPropertiesFile(String thePropertiesLocation) { 036 Map<String, Map<String, Integer>> portsByModuleType = new HashMap<>(); 037 038 try (InputStream inputStream = getInputStream(thePropertiesLocation)) { 039 Properties properties = new Properties(); 040 properties.load(inputStream); 041 042 // Extract port values from keys containing ".port" 043 for (String key : properties.stringPropertyNames()) { 044 if (key.contains(".port")) { 045 String value = properties.getProperty(key); 046 try { 047 int portValue = Integer.parseInt(value.trim()); 048 049 // Extract Module ID and Module Type 050 if (key.startsWith("module.")) { 051 String[] parts = key.split("\\."); 052 if (parts.length >= 3) { 053 String moduleId = parts[1]; 054 055 // Get the module type from the properties 056 String moduleTypeKey = "module." + moduleId + ".type"; 057 String moduleType = properties.getProperty(moduleTypeKey); 058 059 if (moduleType != null) { 060 // Add to the map: moduleType -> (moduleId -> port) 061 portsByModuleType.computeIfAbsent(moduleType, k -> new HashMap<>()) 062 .put(moduleId, portValue); 063 } 064 } 065 } 066 } catch (NumberFormatException e) { 067 // Skip if the port value is not a valid integer 068 } 069 } 070 } 071 } catch (IOException e) { 072 throw new RuntimeException("Failed to read properties file: " + thePropertiesLocation, e); 073 } 074 075 return portsByModuleType; 076 } 077 078 /** 079 * Reads a module's {@code context_path} from a properties file. 080 * 081 * @param thePropertiesLocation the path to the properties file. Can be a regular file path or a classpath resource prefixed with "classpath:" 082 * @param theModuleId the module whose {@code module.<id>.config.context_path} to read 083 * @return the configured value, or {@literal null} if the module sets none 084 * @throws RuntimeException if the properties file cannot be read 085 */ 086 public static @Nullable String loadContextPath( 087 @Nonnull String thePropertiesLocation, @Nonnull String theModuleId) { 088 try (InputStream inputStream = getInputStream(thePropertiesLocation)) { 089 Properties properties = new Properties(); 090 properties.load(inputStream); 091 return properties.getProperty("module." + theModuleId + ".config.context_path"); 092 } catch (IOException e) { 093 throw new RuntimeException("Failed to read properties file: " + thePropertiesLocation, e); 094 } 095 } 096 097 private static InputStream getInputStream(String thePropertiesLocation) throws IOException { 098 if (thePropertiesLocation.startsWith("classpath:")) { 099 String classpathResource = thePropertiesLocation.substring("classpath:".length()); 100 InputStream resourceStream = PropertiesTestUtil.class.getClassLoader().getResourceAsStream(classpathResource); 101 if (resourceStream == null) { 102 throw new IOException("Classpath resource not found: " + classpathResource); 103 } 104 return resourceStream; 105 } else { 106 return new FileInputStream(thePropertiesLocation); 107 } 108 } 109}