Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ on:
pull_request:
branches: [ "master" ]

env:
MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3

jobs:
docker-build:
runs-on: ubuntu-22.04
timeout-minutes: 180

strategy:
matrix:
java: [ 8, 17 ]

steps:
- uses: actions/checkout@v4
- name: Delete huge unnecessary tools folder
Expand All @@ -46,26 +48,34 @@ jobs:
path: |
~/.m2/repository/*/*/*
!~/.m2/repository/org/apache/atlas
key: maven-repo-${{ hashFiles('**/pom.xml') }}
key: maven-repo-${{ matrix.java }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
maven-repo-
maven-repo-${{ matrix.java }}-

- name: Set up .m2 directory and permissions
run: |
mkdir -p ~/.m2/repository
chmod -R 777 ~/.m2
chmod -R 777 ./

- name: Set up JDK 8
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: '8'
java-version: ${{ matrix.java }}
distribution: 'temurin'

- name: Set MAVEN_OPTS based on Java version
run: |
if [[ "${{ matrix.java }}" == "17" ]]; then
echo "MAVEN_OPTS=-Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED" >> $GITHUB_ENV
else
echo "MAVEN_OPTS=-Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3" >> $GITHUB_ENV
fi

- name: Clean up Docker space
run: docker system prune --all --force --volumes

- name: Build Atlas - JDK 8
- name: Build Atlas - JDK ${{ matrix.java }}
run: |
cd dev-support/atlas-docker
export DOCKER_BUILDKIT=1
Expand All @@ -84,7 +94,7 @@ jobs:
- name: Upload Code Coverage Results
uses: actions/upload-artifact@v4
with:
name: coverage
name: coverage-java-${{ matrix.java }}
path: dev-support/atlas-docker/dist/coverage/*

- name: Cache downloaded archives
Expand Down
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,30 @@ Regular Build Process
2. Execute the following commands to build Apache Atlas
```
export MAVEN_OPTS="-Xms2g -Xmx2g"
mvn clean install
mvn clean package -Pdist
```
- Apache Atlas supports building with **Java 8**, **Java 11**, and **Java 17**. Set the appropriate `JAVA_HOME` and `MAVEN_OPTS` before building.

- **For Java 8 / Java 11:**
```bash
export MAVEN_OPTS="-Xms2g -Xmx2g"
```

- **For Java 17:**
```bash
export MAVEN_OPTS="--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.nio=ALL-UNNAMED \
--add-opens=java.base/java.net=ALL-UNNAMED \
-Xms2g -Xmx2g"
```

- After setting the correct `MAVEN_OPTS`, run:
```bash
mvn clean install
mvn clean package -Pdist
```

4. After above build commands successfully complete, you should see the following files
3. After above build commands successfully complete, you should see the following files
```
distro/target/apache-atlas-<version>-bin.tar.gz
distro/target/apache-atlas-<version>-hbase-hook.tar.gz
Expand All @@ -89,4 +108,4 @@ Regular Build Process
distro/target/apache-atlas-<version>-couchbase-hook.tar.gz
```

5. For more details on installing and running Apache Atlas, please refer to https://atlas.apache.org/#/Installation
4. For more details on installing and running Apache Atlas, please refer to https://atlas.apache.org/#/Installation
3 changes: 2 additions & 1 deletion addons/hbase-bridge/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
Expand Down
3 changes: 2 additions & 1 deletion addons/hdfs-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
<!-- Logging -->
<dependency>
Expand Down
7 changes: 2 additions & 5 deletions addons/hive-bridge/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
Expand Down Expand Up @@ -233,7 +230,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import org.apache.hadoop.hive.ql.metadata.Table;
import org.apache.hadoop.mapred.TextInputFormat;

import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

Expand All @@ -64,9 +63,23 @@
import static org.apache.atlas.hive.hook.events.BaseHiveEvent.ATTRIBUTE_STORAGEDESC;
import static org.apache.atlas.hive.hook.events.BaseHiveEvent.HIVE_TYPE_DB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import static org.testng.AssertJUnit.*;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.testng.AssertJUnit.assertTrue;

public class HiveMetaStoreBridgeTest {
private static final String TEST_DB_NAME = "default";
Expand Down Expand Up @@ -116,7 +129,7 @@ public void testImportThatUpdatesRegisteredDatabase() throws Exception {
bridge.importHiveMetadata(null, null, true);

// verify update is called
verify(atlasClientV2).updateEntity(Matchers.any(AtlasEntity.AtlasEntityWithExtInfo.class));
verify(atlasClientV2).updateEntity(any());
}

@Test
Expand Down Expand Up @@ -156,7 +169,8 @@ public void testImportThatUpdatesRegisteredTable() throws Exception {
bridge.importHiveMetadata(null, null, true);

// verify update is called on table
verify(atlasClientV2, times(2)).updateEntity(Matchers.any(AtlasEntity.AtlasEntityWithExtInfo.class));
verify(atlasClientV2, times(2)).updateEntity(any());

}

private void returnExistingDatabase(String databaseName, AtlasClientV2 atlasClientV2, String metadataNamespace)
Expand Down Expand Up @@ -876,13 +890,27 @@ public void testGetAllDatabaseInClusterComprehensiveCoverage() throws Exception
getAllDatabaseInClusterMethod.setAccessible(true);

// Test Case 1: Empty result set (no databases)
when(atlasClientV2.basicSearch(Matchers.anyString(), Matchers.any(SearchParameters.FilterCriteria.class), (String) isNull(), (String) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt()))
when(atlasClientV2.basicSearch(
anyString(),
any(SearchParameters.FilterCriteria.class),
isNull(String.class),
isNull(String.class),
anyBoolean(),
anyInt(),
anyInt()))
.thenReturn(searchResult);
when(searchResult.getEntities()).thenReturn(Collections.emptyList());

List<AtlasEntityHeader> resultEmpty = (List<AtlasEntityHeader>) getAllDatabaseInClusterMethod.invoke(bridge);
assertTrue(resultEmpty.isEmpty());
verify(atlasClientV2).basicSearch(Matchers.anyString(), Matchers.any(SearchParameters.FilterCriteria.class), (String) isNull(), (String) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt());
verify(atlasClientV2).basicSearch(
anyString(),
any(SearchParameters.FilterCriteria.class),
isNull(String.class),
isNull(String.class),
anyBoolean(),
anyInt(),
anyInt());
verify(searchResult).getEntities();
verifyNoMoreInteractions(atlasClientV2); // Only one call due to break condition

Expand All @@ -905,13 +933,27 @@ public void testGetAllTablesInDbComprehensiveCoverage() throws Exception {
getAllTablesInDbMethod.setAccessible(true);

// Test Case 1: Empty result set (no tables)
when(atlasClientV2.relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt()))
when(atlasClientV2.relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt()))
.thenReturn(searchResult);
when(searchResult.getEntities()).thenReturn(Collections.emptyList());

List<AtlasEntityHeader> resultEmpty = (List<AtlasEntityHeader>) getAllTablesInDbMethod.invoke(bridge, DATABASE_GUID);
assertTrue(resultEmpty.isEmpty());
verify(atlasClientV2).relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt());
verify(atlasClientV2).relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt());
verify(searchResult).getEntities();
verifyNoMoreInteractions(atlasClientV2); // Only one call due to break condition

Expand All @@ -921,14 +963,28 @@ public void testGetAllTablesInDbComprehensiveCoverage() throws Exception {
// Test Case 2: Partial page with tables (less than pageSize)
List<AtlasEntityHeader> partialEntities = new ArrayList<>();
partialEntities.add(entityHeader1);
when(atlasClientV2.relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt()))
.thenReturn(searchResult);
when(atlasClientV2.relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt()))
.thenReturn(searchResult);
when(searchResult.getEntities()).thenReturn(partialEntities);

List<AtlasEntityHeader> resultPartial = (List<AtlasEntityHeader>) getAllTablesInDbMethod.invoke(bridge, DATABASE_GUID);
assertEquals(1, resultPartial.size());
assertTrue(resultPartial.contains(entityHeader1));
verify(atlasClientV2).relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt());
verify(atlasClientV2).relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt());
verify(searchResult).getEntities();
verifyNoMoreInteractions(atlasClientV2); // Breaks after one iteration

Expand All @@ -939,15 +995,29 @@ public void testGetAllTablesInDbComprehensiveCoverage() throws Exception {
List<AtlasEntityHeader> fullPage = new ArrayList<>();
fullPage.add(entityHeader1);
fullPage.add(entityHeader2);
when(atlasClientV2.relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt()))
.thenReturn(searchResult);
when(atlasClientV2.relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt()))
.thenReturn(searchResult);
when(searchResult.getEntities()).thenReturn(fullPage, partialEntities); // First page full, second partial

List<AtlasEntityHeader> resultMultiple = (List<AtlasEntityHeader>) getAllTablesInDbMethod.invoke(bridge, DATABASE_GUID);
assertEquals(2, resultMultiple.size());
assertTrue(resultMultiple.contains(entityHeader1));
assertTrue(resultMultiple.contains(entityHeader2));
verify(atlasClientV2).relationshipSearch(Matchers.anyString(), Matchers.anyString(), (String) isNull(), (SortOrder) isNull(), Matchers.anyBoolean(), Matchers.anyInt(), Matchers.anyInt());
verify(atlasClientV2).relationshipSearch(
anyString(),
anyString(),
isNull(String.class),
isNull(SortOrder.class),
anyBoolean(),
anyInt(),
anyInt());
verify(searchResult).getEntities();
}

Expand Down Expand Up @@ -1038,7 +1108,7 @@ public void testDeleteByGuidComprehensiveCoverage() throws Exception {

// --- Test Case 1: Empty guidTodelete list ---
deleteByGuidMethod.invoke(bridge, Collections.emptyList());
verify(atlasClientV2, never()).deleteEntityByGuid(Matchers.anyString());
verify(atlasClientV2, never()).deleteEntityByGuid(anyString());
verifyNoMoreInteractions(atlasClientV2);

reset(atlasClientV2);
Expand Down Expand Up @@ -1119,7 +1189,7 @@ public void testDeleteEntitiesForNonExistingHiveMetadataComprehensiveCoverage()
// Use reflection to call private methods
getAllDatabaseInClusterMethod.invoke(bridge);
bridge.deleteEntitiesForNonExistingHiveMetadata(false, null, null);
verify(hiveClient, never()).databaseExists(Matchers.anyString());
verify(hiveClient, never()).databaseExists(anyString());

// Reset mocks
reset(bridge, atlasClientV2, hiveClient);
Expand Down Expand Up @@ -1150,7 +1220,7 @@ public void testDeleteEntitiesForNonExistingHiveMetadataComprehensiveCoverage()
when(tableEntity1.getAttribute(ATTRIBUTE_QUALIFIED_NAME)).thenReturn("default.test_table@primary");
when(tableEntity2.getGuid()).thenReturn(TABLE_GUID2);
when(tableEntity2.getAttribute(ATTRIBUTE_QUALIFIED_NAME)).thenReturn("default.test_table2@primary");
when(atlasClientV2.deleteEntityByGuid(Matchers.anyString())).thenReturn(mutationResponse);
when(atlasClientV2.deleteEntityByGuid(anyString())).thenReturn(mutationResponse);
AtlasEntityHeader mockEntityHeader = mock(AtlasEntityHeader.class);
when(mutationResponse.getDeletedEntities())
.thenReturn(Collections.singletonList(mockEntityHeader));
Expand Down
Loading
Loading