Skip to content

Commit 69f0f6d

Browse files
ThibaudDauceManuthor
authored andcommitted
feat: add exception handling for Findex callbacks
1 parent 9897ba5 commit 69f0f6d

17 files changed

Lines changed: 431 additions & 147 deletions

.github/workflows/maven.yml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,137 @@ jobs:
4545

4646
- name: Build with Maven
4747
run: mvn -B package --file pom.xml
48+
49+
build_in_docker:
50+
services:
51+
kms:
52+
image: cosmian/kms:4.0.1
53+
env:
54+
COSMIAN_SERVER_URL: http://localhost:9998
55+
KMS_PUBLIC_PATH: /tmp
56+
KMS_PRIVATE_PATH: /tmp
57+
KMS_SHARED_PATH: /tmp
58+
ports:
59+
- 9998:9998
60+
61+
redis:
62+
image: redis
63+
options: >-
64+
--health-cmd "redis-cli ping"
65+
--health-interval 10s
66+
--health-timeout 5s
67+
--health-retries 5
68+
ports:
69+
- 6379:6379
70+
71+
runs-on: ${{ matrix.os }}
72+
container: centos:centos7.4.1708
73+
strategy:
74+
fail-fast: false
75+
matrix:
76+
include:
77+
- os: ubuntu-20.04
78+
79+
steps:
80+
- uses: actions/checkout@v3
81+
82+
- name: Cache build
83+
uses: actions/cache@v3
84+
continue-on-error: false
85+
with:
86+
path: |
87+
~/.m2/repository
88+
target
89+
key: ${{ runner.os }}-maven-docker-${{ hashFiles('**/pom.xml') }}
90+
restore-keys: |
91+
${{ runner.os }}-maven-docker-${{ hashFiles('**/pom.xml') }}
92+
- run: yum -y install java-1.8.0-openjdk maven python3 python3-pip
93+
- run: python3 scripts/get_native_libraries.py
94+
95+
- name: Build with Maven
96+
run: mvn compile
97+
env:
98+
COSMIAN_SERVER_URL: http://kms:9998
99+
REDIS_HOSTNAME: redis
100+
REDIS_PORT: 6379
101+
LANG: en_US.UTF-8
102+
LANGUAGE: en_US:en
103+
LC_ALL: en_US.UTF-8
104+
105+
- name: Test with Maven
106+
run: mvn test
107+
env:
108+
COSMIAN_SERVER_URL: http://kms:9998
109+
REDIS_HOSTNAME: redis
110+
REDIS_PORT: 6379
111+
LANG: en_US.UTF-8
112+
LANGUAGE: en_US:en
113+
LC_ALL: en_US.UTF-8
114+
115+
maven_deploy:
116+
needs:
117+
- build
118+
- build_in_docker
119+
runs-on: ubuntu-20.04
120+
121+
steps:
122+
- uses: actions/checkout@v3
123+
124+
- name: Cache build
125+
uses: actions/cache@v3
126+
continue-on-error: false
127+
with:
128+
path: |
129+
~/.m2/repository
130+
target
131+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
132+
restore-keys: |
133+
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
134+
- name: Set up JDK 8
135+
uses: actions/setup-java@v3
136+
with:
137+
java-version: 8
138+
distribution: temurin
139+
cache: maven
140+
141+
- uses: actions/setup-python@v3
142+
with:
143+
python-version: 3.7
144+
- run: python scripts/get_native_libraries.py
145+
146+
- name: Import GPG key
147+
id: import_gpg
148+
uses: crazy-max/ghaction-import-gpg@v5
149+
with:
150+
gpg_private_key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
151+
passphrase: ${{ secrets.GPG_PASSPHRASE }}
152+
153+
- name: Maven deploy
154+
if: startsWith(github.ref, 'refs/tags/')
155+
run: |
156+
sudo apt-get update
157+
sudo apt-get install -y gnupg2
158+
mkdir -p ~/.m2 ~/.gpg
159+
echo "$M2_SETTINGS" > ~/.m2/settings.xml
160+
echo "$MAVEN_GPG_PRIVATE_KEY" > ~/.gpg/maven_gpg_private_key.asc
161+
mvn clean deploy -Dmaven.test.skip
162+
env:
163+
M2_SETTINGS: ${{ secrets.M2_SETTINGS }}
164+
MAVEN_GPG_PRIVATE_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
165+
166+
release:
167+
needs:
168+
- maven_deploy
169+
name: release
170+
runs-on: ubuntu-latest
171+
steps:
172+
- uses: actions/checkout@v1
173+
- name: Release
174+
if: startsWith(github.ref, 'refs/tags/')
175+
uses: softprops/action-gh-release@v1
176+
177+
cleanup:
178+
needs:
179+
- release
180+
uses: Cosmian/reusable_workflows/.github/workflows/cleanup_cache.yml@findex_2.0_cover_crypt_8.0
181+
secrets: inherit

.github/workflows/release_on_tags.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [3.0.4] - 2023-04-25
6+
7+
### Features
8+
9+
- Add exception handling for Findex callbacks
10+
11+
### Ci
12+
13+
- Test on docker too
14+
515
## [3.0.3] - 2023-01-16
616

717
### Deleted

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ This library is open-source software and is available on Maven Central.
4040
<dependency>
4141
<groupId>com.cosmian</groupId>
4242
<artifactId>cloudproof_java</artifactId>
43-
<version>3.0.3</version>
43+
<version>3.0.4</version>
4444
</dependency>
4545
```
4646

@@ -76,3 +76,4 @@ This table shows the compatible versions of the various components
7676
|----------|------------|------------|--------|
7777
| 3.0.0 | 4.0.1 | 8.0.1 | 1.0.1 |
7878
| 3.0.2 | 4.0.1 | 8.0.1 | 2.0.0 |
79+
| 3.0.4 | 4.0.1 | 8.0.2 | 2.0.2 |

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>com.cosmian</groupId>
77
<artifactId>cloudproof_java</artifactId>
8-
<version>3.0.3</version>
8+
<version>3.0.4</version>
99

1010
<name>cloudproof_java</name>
1111
<description>The Cloudproof Java Lib secures data repositories in the cloud with attributes-based access control encryption and encrypted search</description>

scripts/get_native_libraries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def download_native_libraries(name: str, version: str, destination: str):
5656

5757

5858
if __name__ == '__main__':
59-
download_native_libraries('findex', 'v2.0.0', 'src/main/resources')
59+
download_native_libraries('findex', 'v2.0.2', 'src/main/resources')
6060
download_native_libraries('findex', 'last_build', 'src/main/resources')
6161
download_native_libraries('cover_crypt', 'v8.0.2', 'src/main/resources')
6262
download_native_libraries('cover_crypt', 'last_build', 'src/main/resources')

src/main/java/com/cosmian/jna/findex/Findex.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ public static void upsert(
8080
labelPointer.write(0, label, 0, label.length);
8181

8282
// Indexes creation + insertion/update
83+
long start = System.currentTimeMillis();
8384
unwrap(Findex.INSTANCE.h_upsert(
8485
keyPointer, key.length,
8586
labelPointer, label.length,
8687
indexedValuesToJson(indexedValuesAndWords),
8788
db.fetchEntryCallback(),
8889
db.upsertEntryCallback(),
89-
db.upsertChainCallback()));
90+
db.upsertChainCallback()), start);
9091
}
9192
}
9293

@@ -178,6 +179,7 @@ public static Map<Keyword, Set<Location>> search(byte[] key,
178179
}
179180

180181
// Indexes creation + insertion/update
182+
long start = System.currentTimeMillis();
181183
int ffiCode = Findex.INSTANCE.h_search(
182184
indexedValuesBuffer, indexedValuesBufferSize,
183185
keyPointer, key.length,
@@ -189,10 +191,13 @@ public static Map<Keyword, Set<Location>> search(byte[] key,
189191
db.progressCallback(),
190192
db.fetchEntryCallback(),
191193
db.fetchChainCallback());
194+
FindexCallbackException.rethrowOnErrorCode(ffiCode, start, System.currentTimeMillis());
195+
192196
if (ffiCode != 0) {
193197
// Retry with correct allocated size
194198
indexedValuesBuffer = new byte[indexedValuesBufferSize.getValue()];
195-
ffiCode = Findex.INSTANCE.h_search(
199+
long startRetry = System.currentTimeMillis();
200+
unwrap(Findex.INSTANCE.h_search(
196201
indexedValuesBuffer, indexedValuesBufferSize,
197202
keyPointer, key.length,
198203
labelPointer, label.length,
@@ -202,10 +207,7 @@ public static Map<Keyword, Set<Location>> search(byte[] key,
202207
insecureFetchChainsBatchSize,
203208
db.progressCallback(),
204209
db.fetchEntryCallback(),
205-
db.fetchChainCallback());
206-
if (ffiCode != 0) {
207-
throw new CloudproofException(get_last_error(4095));
208-
}
210+
db.fetchChainCallback()), startRetry);
209211
}
210212

211213
byte[] indexedValuesBytes = Arrays.copyOfRange(indexedValuesBuffer, 0, indexedValuesBufferSize.getValue());
@@ -236,6 +238,7 @@ public static void compact(int numberOfReindexingPhasesBeforeFullSet,
236238
labelPointer.write(0, label, 0, label.length);
237239

238240
// Indexes creation + insertion/update
241+
long start = System.currentTimeMillis();
239242
unwrap(Findex.INSTANCE.h_compact(
240243
numberOfReindexingPhasesBeforeFullSet,
241244
existingKeyPointer, existingKey.length,
@@ -245,21 +248,34 @@ public static void compact(int numberOfReindexingPhasesBeforeFullSet,
245248
database.fetchEntryCallback(),
246249
database.fetchChainCallback(),
247250
database.updateLinesCallback(),
248-
database.listRemoveLocationsCallback()));
251+
database.listRemoveLocationsCallback()), start);
249252
}
250253
}
251254

252255
/**
253256
* If the result of the last FFI call is in Error, recover the last error from the native code and throw an
254257
* exception wrapping it.
255258
*
256-
* @param result the result of the FFI call
259+
* @param errorCode the errorCode of the FFI call
257260
* @throws CloudproofException in case of native library error
258261
*/
259-
public static void unwrap(int result) throws CloudproofException {
260-
if (result == 1) {
262+
public static void unwrap(int errorCode) throws CloudproofException {
263+
if (errorCode != 0) {
261264
throw new CloudproofException(get_last_error(4095));
262265
}
263266
}
264267

268+
/**
269+
* If the result of the last FFI call is in Error, recover the last error from the native code and throw an
270+
* exception wrapping it.
271+
*
272+
* @param errorCode the errorCode of the FFI call
273+
* @throws CloudproofException in case of native library error
274+
*/
275+
public static void unwrap(int errorCode, long start) throws CloudproofException {
276+
FindexCallbackException.rethrowOnErrorCode(errorCode, start, System.currentTimeMillis());
277+
278+
unwrap(errorCode);
279+
}
280+
265281
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.cosmian.jna.findex;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import com.cosmian.utils.CloudproofException;
7+
8+
public class FindexCallbackException {
9+
10+
private final static int CALLBACK_ERROR_CODE_WHEN_THROWING = 42;
11+
public static int purgeExceptionsWhenCountIsGreaterThan = 50;
12+
public static int purgeExceptionsAfterMillis = 1000 * 60 * 5; // 5 minutes
13+
14+
public static List<FindexCallbackException> exceptions = new ArrayList<>();
15+
16+
private long timestamp = System.currentTimeMillis();
17+
private CloudproofException e;
18+
19+
public FindexCallbackException(CloudproofException e) {
20+
this.e = e;
21+
}
22+
23+
public static int record(CloudproofException e) {
24+
if (exceptions.size() > purgeExceptionsWhenCountIsGreaterThan) {
25+
exceptions.removeIf(exception -> exception.timestamp < System.currentTimeMillis() - purgeExceptionsAfterMillis);
26+
}
27+
28+
exceptions.add(new FindexCallbackException(e));
29+
30+
return CALLBACK_ERROR_CODE_WHEN_THROWING;
31+
}
32+
33+
public static void rethrowOnErrorCode(int errorCode, long start, long end) throws CloudproofException {
34+
if (errorCode != CALLBACK_ERROR_CODE_WHEN_THROWING) {
35+
return;
36+
}
37+
38+
for (FindexCallbackException e : exceptions) {
39+
if (e.timestamp >= start && e.timestamp <= end) {
40+
throw e.e;
41+
}
42+
}
43+
44+
throw new CloudproofException("Findex returned an error code " + errorCode + " reserved for exceptions but no exception was recorded during the callbacks.");
45+
}
46+
}

src/main/java/com/cosmian/jna/findex/ffi/FetchAllEntryTableUids.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Set;
44
import java.util.logging.Logger;
55

6+
import com.cosmian.jna.findex.FindexCallbackException;
67
import com.cosmian.jna.findex.ffi.FindexNativeWrapper.FetchAllEntryTableUidsCallback;
78
import com.cosmian.jna.findex.ffi.FindexUserCallbacks.DBFetchAllEntryTableUids;
89
import com.cosmian.jna.findex.structs.Uid32;
@@ -24,16 +25,19 @@ public FetchAllEntryTableUids(DBFetchAllEntryTableUids fetch) {
2425
public int apply(Pointer uidsPointer,
2526
IntByReference uidsSize)
2627
throws CloudproofException {
27-
28-
//
29-
// Select uids and values in EntryTable
30-
//
31-
Set<Uid32> uidsAndValues = this.fetch.fetchAll();
32-
33-
//
34-
// Serialize results
35-
//
36-
return FFiUtils.setToOutputPointer(uidsAndValues, uidsPointer, uidsSize);
28+
try {
29+
//
30+
// Select uids and values in EntryTable
31+
//
32+
Set<Uid32> uidsAndValues = this.fetch.fetchAll();
33+
34+
//
35+
// Serialize results
36+
//
37+
return FFiUtils.setToOutputPointer(uidsAndValues, uidsPointer, uidsSize);
38+
} catch (CloudproofException e) {
39+
return FindexCallbackException.record(e);
40+
}
3741
}
3842

3943
}

0 commit comments

Comments
 (0)