Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(release): pulling release/1.23.2 into master #452

Merged
merged 7 commits into from
Jun 25, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Bug report
about: Create a report to help us improve
title: "BUG : <Title>"
labels: bug, open source
assignees: itsdebs
assignees: "@rudderlabs/sdk-android"
---

**Describe the bug**
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/draft_new_release-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ jobs:
github_token: ${{ secrets.PAT }}
pr_title: 'chore(release): pulling ${{ steps.create-release.outputs.branch_name }} into master-v2'
pr_body: ':crown: *An automated PR*'
pr_reviewer: 'itsdebs'
pr_reviewer: '@rudderlabs/sdk-android'
2 changes: 1 addition & 1 deletion .github/workflows/draft_new_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ jobs:
github_token: ${{ secrets.PAT }}
pr_title: "chore(release): pulling ${{ steps.create-release.outputs.branch_name }} into ${{ steps.create-release.outputs.main_branch }}"
pr_body: ":crown: *An automated PR*"
pr_reviewer: 'itsdebs'
pr_reviewer: '@rudderlabs/sdk-android'
2 changes: 1 addition & 1 deletion .github/workflows/publish-new-github-release-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
github_token: ${{ secrets.PAT }}
pr_title: 'chore(release): pulling master-v2 into develop-v2 post release v${{ steps.extract-version.outputs.release_version }}'
pr_body: ':crown: *An automated PR*'
pr_reviewer: 'itsdebs'
pr_reviewer: '@rudderlabs/sdk-android'

- name: Delete hotfix release branch v2
uses: koj-co/delete-merged-action@master
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-new-github-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
github_token: ${{ secrets.PAT }}
pr_title: "chore(release): pulling main into develop post release v${{ steps.extract-version.outputs.release_version }}"
pr_body: ':crown: *An automated PR*'
pr_reviewer: 'itsdebs'
pr_reviewer: '@rudderlabs/sdk-android'
- name: Create pull request into develop-mpx
uses: repo-sync/pull-request@v2
if: (startsWith(github.event.pull_request.head.ref, 'release-mpx/') || startsWith(github.event.pull_request.head.ref, 'hotfix-release-mpx/'))
Expand All @@ -59,7 +59,7 @@ jobs:
github_token: ${{ secrets.PAT }}
pr_title: "chore(release): pulling main into develop post release v${{ steps.extract-version.outputs.release_version }}"
pr_body: ':crown: *An automated PR*'
pr_reviewer: 'itsdebs'
pr_reviewer: '@rudderlabs/sdk-android'

- name: Delete hotfix release branch
uses: koj-co/delete-merged-action@master
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.23.2](https://github.com/rudderlabs/rudder-sdk-android/compare/v1.23.1...v1.23.2) (2024-06-25)


### Bug Fixes

* database crash issue ([#449](https://github.com/rudderlabs/rudder-sdk-android/issues/449)) ([9251b68](https://github.com/rudderlabs/rudder-sdk-android/commit/9251b6882162d61f6300f16d543bec9864a397cc))

### [1.23.1](https://github.com/rudderlabs/rudder-sdk-android/compare/v1.23.0...v1.23.1) (2024-05-28)


Expand Down
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @pallabmaiti @itsdebs @bardisg @ChryssaAliferi
* @rudderlabs/sdk-android
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ For any questions, concerns, or queries, you can start by asking a question on o
<!----variables---->

[issue]: https://github.com/rudderlabs/rudder-sdk-android/issues/new
[CLA]: https://rudderlabs.wufoo.com/forms/rudderlabs-contributor-license-agreement
[CLA]: https://forms.gle/845JRGVZaC6kPZy68
[Slack]: https://rudderstack.com/join-rudderstack-slack-community/
54 changes: 0 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,60 +117,6 @@ The variable `it` contains the intialized nativeSDK object.

[**Registering Lotame's onSync callback**](https://github.com/rudderlabs/rudder-integration-lotame-android#register-your-onsync-callback) shows one more example of registering a callback using `onIntegrationReady`.

#### Do I need to add anything to my ProGuard rules?

If you are using Proguard full mode to optimize your app, add the following lines to your Android ProGuard rules:

```java
# Reporter Module
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.LabelEntity { *; }
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.MetricEntity { *; }
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.ErrorEntity { *; }

# Required for the usage off TypeToken class in Utils.converToMap, Utils.convertToList
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken

# Required for the serialization of SourceConfig once it is downloaded.
-keep class com.google.gson.internal.LinkedTreeMap { *; }
-keep class * implements java.io.Serializable { *; }
-keep class com.rudderstack.rudderjsonadapter.RudderTypeAdapter { *; }
-keep class * extends com.rudderstack.rudderjsonadapter.RudderTypeAdapter

# Required to ensure the DefaultPersistenceProviderFactory is not removed by Proguard
# and works as expected even when the customer is not using encryption feature.
-dontwarn net.sqlcipher.Cursor
-dontwarn net.sqlcipher.database.SQLiteDatabase$CursorFactory
-dontwarn net.sqlcipher.database.SQLiteDatabase
-dontwarn net.sqlcipher.database.SQLiteOpenHelper
-keep class com.rudderstack.android.sdk.core.persistence.DefaultPersistenceProviderFactory { *; }

# Required for the usage of annotations across reporter and web modules
-dontwarn com.fasterxml.jackson.annotation.JsonIgnore
-dontwarn com.squareup.moshi.Json
-dontwarn com.fasterxml.jackson.annotation.JsonProperty

# Required for Device Mode Transformations
-keep class com.rudderstack.android.sdk.core.TransformationResponse { *; }
-keep class com.rudderstack.android.sdk.core.TransformationResponseDeserializer { *; }

# to make sure that serialized name annotations are not removed by the Proguard full mode.
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}

# Required for proper serialization of the custom traits and custom context
-keep class * implements com.google.gson.JsonSerializer { *; }

# to make sure that the customContextMap, custom traits are sent in the proper format
-keepclassmembers class com.rudderstack.android.sdk.core.RudderContext { java.util.Map customContextMap; }
-keepclassmembers class com.rudderstack.android.sdk.core.RudderTraits { java.util.Map extras; }

# Required for DBEncryption feature using SQLCipher
-keep class net.sqlcipher.** { *; }
-keep class net.sqlcipher.database.* { *; }
```

## Contribute

We would love to see you contribute to this project. Get more information on how to contribute [**here**](./CONTRIBUTING.md).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.rudderstack.android.ruddermetricsreporterandroid.RudderReporter;
import com.rudderstack.android.sdk.core.persistence.DefaultPersistenceProviderFactory;
import com.rudderstack.android.sdk.core.persistence.Persistence;
import com.rudderstack.android.sdk.core.persistence.PersistenceProvider;
Expand All @@ -26,11 +25,9 @@
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
Expand All @@ -43,7 +40,6 @@
class DBPersistentManager/* extends SQLiteOpenHelper*/ {

public static final String DBPERSISTENT_MANAGER_CHECK_FOR_MIGRATIONS_TAG = "DBPersistentManager: checkForMigrations: ";
public static final Object QUEUE_LOCK = new Object();
public static final ExecutorService executor = Executors.newSingleThreadExecutor();
static final String EVENT = "EVENT";

Expand Down Expand Up @@ -100,8 +96,7 @@ class DBPersistentManager/* extends SQLiteOpenHelper*/ {
//synchronizing database access
private static final Object DB_LOCK = new Object();
private static DBPersistentManager instance;
final Queue<Message> queue = new LinkedList<>();
DBInsertionHandlerThread dbInsertionHandlerThread;
private DBInsertionHandlerThread dbInsertionHandlerThread;
private Persistence persistence;

private DBPersistentManager(Application application,
Expand Down Expand Up @@ -190,18 +185,18 @@ private void createSchema(String eventSchemaSQL) {


/*
* Receives message from Repository, and passes it to the Handler thread if it exists, else adds it to a queue for replay
* once Handler thread is initialized.
* Receives message from Repository, and passes it to the Handler thread if it exists else creates a new Handler thread.
* This method should be called in a synchronized way.
* */
void saveEvent(String messageJson, EventInsertionCallback callback) {
Message msg = createOsMessageFromJson(messageJson, callback);
synchronized (DBPersistentManager.QUEUE_LOCK) {
if (dbInsertionHandlerThread == null) {
queue.add(msg);
return;
}
addMessageToHandlerThread(msg);
if (dbInsertionHandlerThread == null) {
// Need to perform db operations on a separate thread to support strict mode.
// saveEvent method is already called on an executor thread, so we can directly call DBInsertionHandlerThread
dbInsertionHandlerThread = new DBInsertionHandlerThread("db_insertion_thread", persistence);
dbInsertionHandlerThread.start();
}
dbInsertionHandlerThread.addMessage(msg);
}

private Message createOsMessageFromJson(String messageJson, EventInsertionCallback callback) {
Expand All @@ -213,13 +208,6 @@ private Message createOsMessageFromJson(String messageJson, EventInsertionCallba
return msg;
}

/*
Passes the input message to the Handler thread.
*/
void addMessageToHandlerThread(Message msg) {
dbInsertionHandlerThread.addMessage(msg);
}

@VisibleForTesting
void saveEventSync(String messageJson) {
ContentValues insertValues = new ContentValues();
Expand Down Expand Up @@ -456,32 +444,6 @@ private int getCountForCommand(String sql) {
return count;
}

/*
Starts the Handler thread, which is responsible for storing the messages in its internal queue, and
save them to the sqlite db sequentially.
*/
void startHandlerThread() {
Runnable runnable = () -> {
try {
synchronized (DBPersistentManager.QUEUE_LOCK) {
dbInsertionHandlerThread = new DBInsertionHandlerThread("db_insertion_thread", persistence);
dbInsertionHandlerThread.start();
for (Message msg : queue) {
addMessageToHandlerThread(msg);
}
}
} catch (SQLiteDatabaseCorruptException | ConcurrentModificationException |
NullPointerException ex) {
RudderLogger.logError(ex);
ReportManager.reportError(ex);

}
};
// Need to perform db operations on a separate thread to support strict mode.
executor.execute(runnable);
}


private boolean checkIfColumnExists(String newColumn) {
String checkIfStatusExistsSqlString = "PRAGMA table_info(events)";
if (!persistence.isAccessible()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ private void initializeDbManager(Application application) {
dbEncryption.getPersistenceProviderFactoryClassName(), dbEncryption.key);
this.dbManager = DBPersistentManager.getInstance(application, dbManagerParams);
dbManager.checkForMigrations();
dbManager.startHandlerThread();
}

private void initiatePreferenceManager(Application application) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,29 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.reflect.Whitebox;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;

import static java.util.concurrent.TimeUnit.SECONDS;

import android.os.Build;
import android.os.Message;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasProperty;
import static java.lang.Thread.sleep;

import android.app.Application;

import androidx.test.core.app.ApplicationProvider;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import com.google.common.collect.ImmutableList;
import com.rudderstack.android.sdk.core.gson.RudderGson;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = Build.VERSION_CODES.O_MR1)
Expand Down Expand Up @@ -84,8 +67,6 @@ public void setUp() throws Exception {
dbPersistentManager = PowerMockito.mock(DBPersistentManager.class);
PowerMockito.when(dbPersistentManager, "saveEventSync", anyString()).thenCallRealMethod();
PowerMockito.when(dbPersistentManager, "saveEvent", anyString(), any()).thenCallRealMethod();
PowerMockito.when(dbPersistentManager, "startHandlerThread").thenCallRealMethod();
Whitebox.setInternalState(dbPersistentManager, "queue", new LinkedList<Message>());
deviceModeManager = Mockito.mock(RudderDeviceModeManager.class);
}

Expand All @@ -98,57 +79,6 @@ public void tearDown() {

private int addMessageCalled = 0;

@Test
public void testSynchronicity() throws Exception {
final AtomicInteger messagesSaved = new AtomicInteger(0);
// Mocking the addMessageToQueue, which is used by both the save-event-thread and Handler thread, to verify synchronization
PowerMockito.when(dbPersistentManager, "addMessageToHandlerThread", any(Message.class))
.thenAnswer((Answer<Void>) invocation -> {
++addMessageCalled;
System.out.println("addMessageToQueue called by: " + Thread.currentThread().getName());
//assert if called by multiple thread
assertThat(addMessageCalled, Matchers.lessThan(2));
sleep(500);
--addMessageCalled;
assertThat(addMessageCalled, Matchers.lessThan(1));
System.out.println("return from addMessageToQueue by: " + Thread.currentThread().getName());
messagesSaved.incrementAndGet();
return null;
}
);

// Triggering the saveEvent method of DBPersistentManager from save-event-thread, as this method adds messages to the queue.
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < messages.size(); i++) {
dbPersistentManager.saveEvent(messages.get(i),
new EventInsertionCallback(new RudderMessageBuilder().build(),
deviceModeManager));
// Starting the Handler thread, only when some events are added to the queue, so that the replay happens, and handler
// thread starts reading from the queue.
if (i == messages.size() / 2) {
dbPersistentManager.startHandlerThread();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "save-event-thread") {
}.start();


//await until finished
await().atMost(15, SECONDS).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return messagesSaved.get() == messages.size();
}
});
}
@Test
public void doneEventsTest() {
final DBPersistentManager dbPersistentManager = DBPersistentManager.getInstance(ApplicationProvider
Expand Down Expand Up @@ -216,4 +146,4 @@ private List<RudderMessage> parse(List<String> messageJsons) {
}
return messages;
}
}
}
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ android.enableJetifier=true
android.enableR8.fullMode=true
kotlin.code.style=official
GROUP=com.rudderstack.android.sdk
VERSION_CODE=28
VERSION_NAME=1.23.1
VERSION_CODE=29
VERSION_NAME=1.23.2
POM_NAME=Rudderstack SDK for android
POM_DESCRIPTION=Rudderstack SDK for android
POM_ARTIFACT_ID=core
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.23.1",
"version": "1.23.2",
"dependencies": {
"properties-reader": "^2.2.0"
}
Expand Down
Loading
Loading