Skip to content

Commit 266f881

Browse files
committed
Fixed License Headers
1 parent bc1f7b6 commit 266f881

File tree

12 files changed

+283
-3500
lines changed

12 files changed

+283
-3500
lines changed

contrib/storage-hive/core/src/test/java/org/apache/drill/exec/hive/HiveContainer.java

Lines changed: 125 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,20 @@ public class HiveContainer extends GenericContainer<HiveContainer> {
3939
// For 10-20 minute startup: use "drill-hive-test:latest" (build with docker build)
4040
private static final String HIVE_IMAGE = System.getProperty("hive.image", "drill-hive-test:fast");
4141
private static final String FALLBACK_IMAGE = "apache/hive:3.1.3";
42-
private static final boolean USE_PREINITIALIZED = HIVE_IMAGE.contains("preinitialized");
4342
private static final int METASTORE_PORT = 9083;
4443
private static final int HIVESERVER2_PORT = 10000;
4544
private static final int HIVESERVER2_HTTP_PORT = 10002;
4645

4746
private static HiveContainer instance;
48-
private boolean dataInitialized = false;
47+
private static String initializationError = null;
48+
private final boolean usePreinitialized;
49+
private final boolean useFallbackImage;
4950

50-
private HiveContainer() {
51-
this(getHiveImage());
51+
private HiveContainer(String dockerImageName, boolean useFallback) {
52+
super(DockerImageName.parse(dockerImageName).asCompatibleSubstituteFor("apache/hive"));
53+
this.useFallbackImage = useFallback;
54+
this.usePreinitialized = dockerImageName.contains("preinitialized");
55+
configureContainer();
5256
}
5357

5458
private static String getHiveImage() {
@@ -57,24 +61,44 @@ private static String getHiveImage() {
5761
return HIVE_IMAGE;
5862
}
5963

60-
private HiveContainer(String dockerImageName) {
61-
super(DockerImageName.parse(dockerImageName).asCompatibleSubstituteFor("apache/hive"));
64+
/**
65+
* Checks if Docker is available on the system.
66+
*/
67+
public static boolean isDockerAvailable() {
68+
try {
69+
org.testcontainers.DockerClientFactory.instance().client();
70+
return true;
71+
} catch (Exception e) {
72+
return false;
73+
}
74+
}
75+
76+
/**
77+
* Returns any initialization error that occurred.
78+
*/
79+
public static String getInitializationError() {
80+
return initializationError;
81+
}
6282

83+
private void configureContainer() {
6384
withExposedPorts(METASTORE_PORT, HIVESERVER2_PORT, HIVESERVER2_HTTP_PORT);
6485

6586
// Set environment variables for Hive configuration
6687
withEnv("SERVICE_NAME", "hiveserver2");
6788
// Don't set IS_RESUME - let the entrypoint initialize the schema
6889

6990
// Wait strategy depends on image type:
70-
// - Standard image: Wait for data initialization to complete (20 minutes)
71-
// - Pre-initialized image: Wait for services to start only (2 minutes)
72-
if (USE_PREINITIALIZED) {
91+
if (usePreinitialized) {
7392
// Pre-initialized image: schema and data already exist, just wait for services
7493
waitingFor(Wait.forLogMessage(".*Hive container ready \\(pre-initialized\\)!.*", 1)
7594
.withStartupTimeout(Duration.ofMinutes(2)));
95+
} else if (useFallbackImage) {
96+
// Fallback to apache/hive:3.1.3 - wait for HiveServer2 to be ready
97+
// This image uses a different startup sequence
98+
waitingFor(Wait.forLogMessage(".*Starting HiveServer2.*", 1)
99+
.withStartupTimeout(Duration.ofMinutes(5)));
76100
} else {
77-
// Standard image: wait for both HiveServer2 to start AND test data to be initialized
101+
// Custom image: wait for both HiveServer2 to start AND test data to be initialized
78102
// Allow up to 20 minutes: Metastore + HiveServer2 startup (~5-10 min) + data initialization (~5-10 min)
79103
// This is only on first run; container reuse makes subsequent tests fast (~1 second)
80104
waitingFor(Wait.forLogMessage(".*Test data loaded and ready for queries.*", 1)
@@ -84,49 +108,88 @@ private HiveContainer(String dockerImageName) {
84108
// Enable reuse for faster test execution
85109
withReuse(true);
86110

87-
logger.info("Hive container configured with image: {}", dockerImageName);
111+
logger.info("Hive container configured with image: {}", getDockerImageName());
88112
}
89113

90114
/**
91115
* Gets the singleton instance of HiveContainer.
92116
* Container is started on first access and reused for all subsequent tests.
117+
* If the custom image is not available, falls back to apache/hive:3.1.3.
93118
*
94-
* @return Shared HiveContainer instance
119+
* @return Shared HiveContainer instance, or null if Docker is unavailable
120+
* @throws RuntimeException if container fails to start
95121
*/
96122
public static synchronized HiveContainer getInstance() {
97-
if (instance == null) {
98-
System.out.println("========================================");
99-
System.out.println("Starting Hive Docker container...");
100-
if (USE_PREINITIALIZED) {
101-
System.out.println("Using pre-initialized image (~1 minute startup)");
102-
} else {
103-
System.out.println("Using standard image (~15 minute startup on first run)");
104-
}
105-
System.out.println("Image: " + HIVE_IMAGE);
106-
System.out.println("========================================");
107-
logger.info("Creating new Hive container instance");
108-
instance = new HiveContainer();
109-
110-
System.out.println("Pulling Docker image and starting container...");
111-
long startTime = System.currentTimeMillis();
112-
instance.start();
113-
long elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000;
114-
115-
System.out.println("========================================");
116-
System.out.println("Hive container started successfully!");
117-
System.out.println("Startup time: " + elapsedSeconds + " seconds");
118-
System.out.println("Metastore: " + instance.getMetastoreUri());
119-
System.out.println("JDBC: " + instance.getJdbcUrl());
120-
System.out.println("Container will be reused for all tests");
121-
if (USE_PREINITIALIZED) {
122-
System.out.println("Tip: Build pre-initialized image with build-preinitialized-image.sh");
123-
}
124-
System.out.println("========================================");
125-
logger.info("Hive container started and ready for tests");
126-
} else {
123+
if (instance != null) {
127124
logger.debug("Reusing existing Hive container instance");
125+
return instance;
126+
}
127+
128+
// Check if Docker is available
129+
if (!isDockerAvailable()) {
130+
initializationError = "Docker is not available. Please install and start Docker to run Hive tests.";
131+
logger.error(initializationError);
132+
throw new RuntimeException(initializationError);
133+
}
134+
135+
System.out.println("========================================");
136+
System.out.println("Starting Hive Docker container...");
137+
System.out.println("Requested image: " + HIVE_IMAGE);
138+
System.out.println("========================================");
139+
140+
// Try the requested image first
141+
try {
142+
instance = tryStartContainer(HIVE_IMAGE, false);
143+
return instance;
144+
} catch (Exception e) {
145+
logger.warn("Failed to start container with image '{}': {}", HIVE_IMAGE, e.getMessage());
146+
System.out.println("Failed to start with " + HIVE_IMAGE + ", trying fallback image...");
147+
}
148+
149+
// Fall back to apache/hive:3.1.3
150+
System.out.println("Falling back to: " + FALLBACK_IMAGE);
151+
try {
152+
instance = tryStartContainer(FALLBACK_IMAGE, true);
153+
return instance;
154+
} catch (Exception e) {
155+
initializationError = "Failed to start Hive container with both custom and fallback images: " + e.getMessage();
156+
logger.error(initializationError, e);
157+
throw new RuntimeException(initializationError, e);
128158
}
129-
return instance;
159+
}
160+
161+
private static HiveContainer tryStartContainer(String imageName, boolean isFallback) {
162+
boolean usePreinit = imageName.contains("preinitialized");
163+
if (usePreinit) {
164+
System.out.println("Using pre-initialized image (~1 minute startup)");
165+
} else if (isFallback) {
166+
System.out.println("Using fallback apache/hive image (~5 minute startup)");
167+
} else {
168+
System.out.println("Using custom image (~15 minute startup on first run)");
169+
}
170+
System.out.println("Image: " + imageName);
171+
172+
logger.info("Creating Hive container with image: {}", imageName);
173+
HiveContainer container = new HiveContainer(imageName, isFallback);
174+
175+
System.out.println("Pulling Docker image and starting container...");
176+
long startTime = System.currentTimeMillis();
177+
container.start();
178+
long elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000;
179+
180+
System.out.println("========================================");
181+
System.out.println("Hive container started successfully!");
182+
System.out.println("Startup time: " + elapsedSeconds + " seconds");
183+
System.out.println("Metastore: " + container.getMetastoreUri());
184+
System.out.println("JDBC: " + container.getJdbcUrl());
185+
System.out.println("Container will be reused for all tests");
186+
if (isFallback) {
187+
System.out.println("NOTE: Using fallback image - test data must be created via JDBC");
188+
}
189+
System.out.println("========================================");
190+
logger.info("Hive container started and ready for tests");
191+
192+
return container;
130193
}
131194

132195
/**
@@ -179,6 +242,25 @@ public Integer getHiveServer2Port() {
179242
return getMappedPort(HIVESERVER2_PORT);
180243
}
181244

245+
/**
246+
* Checks if this container is using the fallback image (apache/hive:3.1.3).
247+
* When using the fallback image, test data must be created via JDBC.
248+
*
249+
* @return true if using fallback image
250+
*/
251+
public boolean isUsingFallbackImage() {
252+
return useFallbackImage;
253+
}
254+
255+
/**
256+
* Checks if this container is using a pre-initialized image.
257+
*
258+
* @return true if using pre-initialized image
259+
*/
260+
public boolean isUsingPreinitializedImage() {
261+
return usePreinitialized;
262+
}
263+
182264
@Override
183265
protected void doStart() {
184266
super.doStart();

0 commit comments

Comments
 (0)