Skip to content

Commit

Permalink
feat: make user profile byte data as base64 store
Browse files Browse the repository at this point in the history
  • Loading branch information
arifBurakDemiray committed Dec 5, 2023
1 parent 67dfbfb commit b9634df
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 198 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private JSONObject doInBackground(String requestData, String customEndpoint, Tra
request.endpoint(customEndpoint);
//getting connection ready
try {
connection = cp.connection(request, null);
connection = cp.connection(request);
} catch (IOException e) {
L.e("[ImmediateRequestMaker] IOException while preparing remote config update request :[" + e + "]");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

public class ModuleUserProfile extends ModuleBase {
static final String CUSTOM_KEY = "custom";
static final String PICTURE_IN_USER_PROFILE = "[CLY]_USER_PROFILE_PICTURE";
boolean isSynced = true;
UserProfile userProfileInterface;
private final Map<String, Object> sets;
Expand Down Expand Up @@ -114,7 +113,7 @@ void perform(JSONObject changes) throws JSONException {
} else if (value instanceof byte[]) {
internalConfig.sdk.user().picture = (byte[]) value;
//set a special value to indicate that the picture information is already stored in memory
changes.put(PredefinedUserPropertyKeys.PICTURE_PATH, PICTURE_IN_USER_PROFILE);
changes.put(PredefinedUserPropertyKeys.PICTURE_PATH, Utils.Base64.encode((byte[]) value));
}
break;
case PredefinedUserPropertyKeys.PICTURE_PATH:
Expand Down Expand Up @@ -220,7 +219,7 @@ private Params prepareRequestParamsForUserProfile() {
L.w("Won't send picturePath" + e);
}
}
if (!json.isEmpty() || internalConfig.sdk.user().picturePath != null || internalConfig.sdk.user().picture != null) {
if (!json.isEmpty() || params.has(PredefinedUserPropertyKeys.PICTURE_PATH)) {
params.add("user_details", json.toString());
return params;
} else {
Expand Down
11 changes: 1 addition & 10 deletions sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -557,16 +557,7 @@ public Integer remaningRequests() {
}
}

try {
user = Storage.read(config, new UserImpl(config));
if (user == null) {
user = new UserImpl(config);
}
} catch (Throwable e) {
L.e("[SDKCore] Cannot happen" + e);
user = new UserImpl(config);
}

user = new UserImpl(config);
initFinished(config);
}

Expand Down
54 changes: 26 additions & 28 deletions sdk-java/src/main/java/ly/count/sdk/java/internal/Transport.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -36,7 +37,6 @@
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import ly.count.sdk.java.PredefinedUserPropertyKeys;
import ly.count.sdk.java.User;
import org.json.JSONObject;

/**
Expand Down Expand Up @@ -118,11 +118,10 @@ public HttpURLConnection openConnection(String url, String params, boolean using
* set SSL context, calculate and add checksum, load and send user picture if needed.
*
* @param request request to send
* @param user user to check for picture
* @return connection, not {@link HttpURLConnection} yet
* @throws IOException from {@link HttpURLConnection} in case of error
*/
HttpURLConnection connection(final Request request, final User user) throws IOException {
HttpURLConnection connection(final Request request) throws IOException {
String endpoint = request.params.remove(Request.ENDPOINT);

if (!request.params.has("device_id") && config.getDeviceId() != null) {
Expand Down Expand Up @@ -160,7 +159,7 @@ HttpURLConnection connection(final Request request, final User user) throws IOEx
PrintWriter writer = null;
try {
L.d("[network] Picture path value " + picturePathValue);
byte[] pictureByteData = picturePathValue == null ? null : getPictureDataFromGivenValue(user, picturePathValue);
byte[] pictureByteData = picturePathValue == null ? null : getPictureDataFromGivenValue(picturePathValue);

if (pictureByteData != null) {
String boundary = Long.toHexString(System.currentTimeMillis());
Expand Down Expand Up @@ -240,36 +239,35 @@ void addMultipart(OutputStream output, PrintWriter writer, String boundary, Stri
* If we have the bytes, give them
* Otherwise load them from disk
*
* @param user
* @param picture
* @return
* @param picture picture path or base64 encoded byte array
* @return picture data
*/
byte[] getPictureDataFromGivenValue(User user, String picture) {
if (user == null) {
return null;
}

byte[] data = null;
if (ModuleUserProfile.PICTURE_IN_USER_PROFILE.equals(picture)) {
//if the value is this special value then we know that we will send over bytes that are already provided by the integrator
//those stored bytes are already in a internal data structure, use them
data = user.picture();
} else {
//otherwise we assume it is a local path, and we try to read it from disk
try {
File file = new File(picture);
if (!file.exists()) {
return null;
}
data = Files.readAllBytes(file.toPath());
} catch (Throwable t) {
L.w("[Transport] getPictureDataFromGivenValue, Error while reading picture from disk " + t);
byte[] getPictureDataFromGivenValue(String picture) {
byte[] data;
//firstly, we assume it is a local path, and we try to read it from disk
try {
File file = new File(picture);
if (!file.exists()) {
return null;
}
data = Files.readAllBytes(file.toPath());
} catch (Throwable t) {
//if we can't read it from disk, we assume it is a base64 encoded byte array
data = readBase64String(picture);
}

return data;
}

private byte[] readBase64String(String string) {
try {
return Base64.getDecoder().decode(string);
} catch (IllegalArgumentException e) {
L.w("[Transport] readBase64String, Error while reading base64 string " + e);
return null;
}
}

String response(HttpURLConnection connection) {
BufferedReader reader = null;
try {
Expand Down Expand Up @@ -319,7 +317,7 @@ public Boolean send() {
Class requestOwner = request.owner();
request.params.remove(Request.MODULE);

connection = connection(request, SDKCore.instance.user());
connection = connection(request);
connection.connect();

int code = connection.getResponseCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ public User commit() {

try {
Countly.instance().userProfile().save();
Storage.push(SDKCore.instance.config, user); // todo this is not need it is for another task
} catch (JSONException e) {
L.e("[UserEditorImpl] Exception while committing changes to User profile" + e);
}
Expand Down
153 changes: 4 additions & 149 deletions sdk-java/src/main/java/ly/count/sdk/java/internal/UserImpl.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package ly.count.sdk.java.internal;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import ly.count.sdk.java.User;
import ly.count.sdk.java.UserEditor;

/**
* Class for user profile data access & manipulation
*/

public class UserImpl extends User implements Storable {
public class UserImpl extends User {
private Log L = null;

String id;
Expand Down Expand Up @@ -102,131 +98,6 @@ public UserEditor edit() {
return new UserEditorImpl(this, L);
}

@Override
public byte[] store(Log L) {
ByteArrayOutputStream bytes = null;
ObjectOutputStream stream = null;
try {
bytes = new ByteArrayOutputStream();
stream = new ObjectOutputStream(bytes);
stream.writeObject(name);
stream.writeObject(username);
stream.writeObject(email);
stream.writeObject(org);
stream.writeObject(phone);
stream.writeInt(picture == null ? 0 : picture.length);
if (picture != null) {
stream.write(picture);
}
stream.writeObject(picturePath);
stream.writeObject(gender == null ? null : gender.toString());
stream.writeInt(birthyear == null ? -1 : birthyear);
stream.writeObject(locale);
stream.writeObject(country);
stream.writeObject(city);
stream.writeObject(location);
stream.writeObject(null);//this is for the removed "cohorts" functionality. just to keep the correct order. Throw away in the future
stream.writeObject(custom);
stream.close();
return bytes.toByteArray();
} catch (IOException e) {
if (L != null) {
L.e("[UserImpl Cannot serialize session" + e);
}
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
if (L != null) {
L.e("[UserImpl Cannot happen" + e);
}
}
}
if (bytes != null) {
try {
bytes.close();
} catch (IOException e) {
if (L != null) {
L.e("[UserImpl Cannot happen" + e);
}
}
}
}
return null;
}

@SuppressWarnings("unchecked")
public boolean restore(byte[] data, Log L) {
ByteArrayInputStream bytes = null;
ObjectInputStream stream = null;

try {
bytes = new ByteArrayInputStream(data);
stream = new ObjectInputStream(bytes);
name = (String) stream.readObject();
username = (String) stream.readObject();
email = (String) stream.readObject();
org = (String) stream.readObject();
phone = (String) stream.readObject();

int picLength = stream.readInt();
if (picLength != 0) {
picture = new byte[picLength];
stream.readFully(picture);
}
picturePath = (String) stream.readObject();

String g = (String) stream.readObject();
if (g != null) {
gender = Gender.fromString(g);
}

int y = stream.readInt();
if (y != -1) {
birthyear = y;
}
locale = (String) stream.readObject();
country = (String) stream.readObject();
city = (String) stream.readObject();
location = (String) stream.readObject();

Set<String> throwawayCohorts = (Set<String>) stream.readObject();//this is for keeping backwards compatibility. Throw away in the future

custom = (Map<String, Object>) stream.readObject();
if (custom == null) {
custom = new HashMap<>();
}

return true;
} catch (IOException | ClassNotFoundException e) {
if (L != null) {
L.e("[UserImpl Cannot deserialize session" + e);
}
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
if (L != null) {
L.e("[UserImpl Cannot happen" + e);
}
}
}
if (bytes != null) {
try {
bytes.close();
} catch (IOException e) {
if (L != null) {
L.e("[UserImpl Cannot happen" + e);
}
}
}
}

return false;
}

@Override
public String toString() {
return "UserImpl{" +
Expand All @@ -247,20 +118,4 @@ public String toString() {
", custom=" + custom +
'}';
}

@Override
public Long storageId() {
return 0L;
}

@Override
public String storagePrefix() {
return "user";
}

@Override
public void setId(Long id) {
this.id = id.toString();
//todo remove this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,18 +270,16 @@ private static File[] getRequestFiles(File targetFolder) {
private static Map<String, String> parseRequestParams(File file) throws IOException {
try (Scanner scanner = new Scanner(file)) {
String firstLine = scanner.nextLine();
String urlDecodedStr = Utils.urldecode(firstLine);

if (urlDecodedStr == null) {
if (Utils.isEmptyOrNull(firstLine)) {
return new HashMap<>();
}

String[] params = urlDecodedStr.split("&");
String[] params = firstLine.split("&");

Map<String, String> paramMap = new HashMap<>();
for (String param : params) {
String[] pair = param.split("=");
paramMap.put(pair[0], pair.length == 1 ? "" : pair[1]);
paramMap.put(Utils.urldecode(pair[0]), pair.length == 1 ? "" : Utils.urldecode(pair[1]));
}

return paramMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void setPicture_binaryData() {
sessionHandler(() -> Countly.instance().user().edit().setPicture(imgData).commit());
validatePictureAndPath(null, imgData);
Countly.session().end();
validateUserDetailsRequestInRQ(map("user_details", "{}", "picturePath", ModuleUserProfile.PICTURE_IN_USER_PROFILE));
validateUserDetailsRequestInRQ(map("user_details", "{}", "picturePath", Utils.Base64.encode(imgData)));
}

/**
Expand Down

0 comments on commit b9634df

Please sign in to comment.