Skip to content

Commit 3ad0fd0

Browse files
committed
protocol: Improve handling early exits & picture
Picture data was a part of the Client class, which wasn't useful in a real use case. This change removes that part and makes PersistenceProvider responsible for it. Also, checksum is now is considered 'revision number', so it doesn't mean it is the hash code of the picture data but rather a date on which the picture was changed.
1 parent 8e1db8b commit 3ad0fd0

13 files changed

Lines changed: 201 additions & 158 deletions

File tree

pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
<groupId>org.monora.uprotocol</groupId>
2424
<artifactId>core</artifactId>
25-
<version>0.1.0-ALPHA32</version>
25+
<version>0.1.0-ALPHA33</version>
2626
<name>UProtocol</name>
2727
<description>Java implementation of uprotocol, an open specification for p2p content exchange</description>
2828
<url>https://github.com/uprotocol</url>
@@ -165,19 +165,19 @@
165165
<dependency>
166166
<groupId>junit</groupId>
167167
<artifactId>junit</artifactId>
168-
<version>4.13.1</version>
168+
<version>4.13.2</version>
169169
<scope>test</scope>
170170
</dependency>
171171
<dependency>
172172
<groupId>org.junit.jupiter</groupId>
173173
<artifactId>junit-jupiter</artifactId>
174-
<version>5.6.1</version>
174+
<version>5.7.2</version>
175175
<scope>test</scope>
176176
</dependency>
177177
<dependency>
178178
<groupId>org.json</groupId>
179179
<artifactId>json</artifactId>
180-
<version>20201115</version>
180+
<version>20210307</version>
181181
</dependency>
182182
<dependency>
183183
<groupId>org.monora.coolsocket</groupId>
@@ -187,7 +187,7 @@
187187
<dependency>
188188
<groupId>org.junit.vintage</groupId>
189189
<artifactId>junit-vintage-engine</artifactId>
190-
<version>5.7.0</version>
190+
<version>5.7.2</version>
191191
<scope>test</scope>
192192
</dependency>
193193
<dependency>
@@ -205,8 +205,8 @@
205205
<dependency>
206206
<groupId>org.jetbrains</groupId>
207207
<artifactId>annotations</artifactId>
208-
<version>16.0.2</version>
208+
<version>21.0.1</version>
209209
<scope>compile</scope>
210210
</dependency>
211211
</dependencies>
212-
</project>
212+
</project>

src/main/java/org/monora/uprotocol/core/ClientLoader.java

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class ClientLoader
3030
* @param persistenceProvider That stores persistent data.
3131
* @param object To load the details from.
3232
* @param clientUid For which this method invocation is being made.
33-
* @param unblock True if this should unblocked the remote if blocked.
33+
* @param unblock True if this should unblock the remote if blocked.
3434
* @return The client produced from the JSON object and persistence database.
3535
* @throws JSONException If something goes wrong when inflating the JSON data.
3636
* @throws BlockedRemoteClientException If the remote is blocked on the side and 'unblock' parameter is false.
@@ -57,7 +57,7 @@ public class ClientLoader
5757
* @param clientUid For which this method invocation is being made.
5858
* @param hasPin Whether the request has a valid PIN. When it does, the remote client will be unblocked
5959
* if blocked.
60-
* @return The client produced from the JSON object and persistence database.
60+
* @return The client data produced from the JSON object and persistence database.
6161
* @throws JSONException If something goes wrong when inflating the JSON data.
6262
* @throws BlockedRemoteClientException If remote is blocked and has no valid PIN. The underlying data is loaded
6363
* after this is thrown.
@@ -79,33 +79,30 @@ public class ClientLoader
7979
@NotNull JSONObject response, @NotNull String clientUid, boolean hasPin,
8080
boolean asClient, boolean unblockAsClient) throws JSONException
8181
{
82-
String nickname = response.getString(Keyword.CLIENT_NICKNAME);
83-
String manufacturer = response.getString(Keyword.CLIENT_MANUFACTURER);
84-
String product = response.getString(Keyword.CLIENT_PRODUCT);
85-
ClientType clientType = ClientType.from(response.getString(Keyword.CLIENT_TYPE));
86-
String versionName = response.getString(Keyword.CLIENT_VERSION_NAME);
87-
int versionCode = response.getInt(Keyword.CLIENT_VERSION_CODE);
88-
int protocolVersion = response.getInt(Keyword.CLIENT_PROTOCOL_VERSION);
89-
int protocolVersionMin = response.getInt(Keyword.CLIENT_PROTOCOL_VERSION_MIN);
90-
long lastUsageTime = System.currentTimeMillis();
91-
boolean local = persistenceProvider.getClientUid().equals(clientUid);
92-
93-
if (nickname.length() > LENGTH_CLIENT_USERNAME) {
94-
nickname = nickname.substring(0, LENGTH_CLIENT_USERNAME);
95-
}
82+
final String nickname = Clients.cleanNickname(response.getString(Keyword.CLIENT_NICKNAME));
83+
final String manufacturer = response.getString(Keyword.CLIENT_MANUFACTURER);
84+
final String product = response.getString(Keyword.CLIENT_PRODUCT);
85+
final ClientType clientType = ClientType.from(response.getString(Keyword.CLIENT_TYPE));
86+
final String versionName = response.getString(Keyword.CLIENT_VERSION_NAME);
87+
final int versionCode = response.getInt(Keyword.CLIENT_VERSION_CODE);
88+
final int protocolVersion = response.getInt(Keyword.CLIENT_PROTOCOL_VERSION);
89+
final int protocolVersionMin = response.getInt(Keyword.CLIENT_PROTOCOL_VERSION_MIN);
90+
final long revisionOfPicture = response.getLong(Keyword.CLIENT_REVISION_PICTURE);
91+
final long lastUsageTime = System.currentTimeMillis();
92+
final boolean local = persistenceProvider.getClientUid().equals(clientUid);
9693

9794
Client client = persistenceProvider.getClientFor(clientUid);
98-
boolean updating = false;
95+
96+
final boolean updating = client != null;
97+
final boolean needsPictureRevision = client == null || client.getClientRevisionOfPicture() != revisionOfPicture;
9998

10099
if (client == null) {
101100
client = persistenceProvider.createClientFor(clientUid, nickname, manufacturer, product, clientType,
102-
versionName, versionCode, protocolVersion, protocolVersionMin);
101+
versionName, versionCode, protocolVersion, protocolVersionMin, revisionOfPicture);
103102
} else {
104103
Clients.fill(client, clientUid, client.getClientCertificate(), nickname, manufacturer, product, clientType,
105-
versionName, versionCode, protocolVersion, protocolVersionMin, client.isClientTrusted(),
106-
client.isClientBlocked());
107-
108-
updating = true;
104+
versionName, versionCode, protocolVersion, protocolVersionMin, revisionOfPicture,
105+
client.isClientTrusted(), client.isClientBlocked());
109106
}
110107

111108
try {
@@ -122,13 +119,10 @@ public class ClientLoader
122119
client.setClientLocal(local);
123120
persistenceProvider.persist(client, updating);
124121

125-
int checksum = response.getInt(Keyword.CLIENT_PICTURE_CHECKSUM);
126-
127-
if (client.getClientPictureChecksum() != checksum) {
122+
if (needsPictureRevision) {
128123
String data = response.optString(Keyword.CLIENT_PICTURE);
129124
try {
130-
persistenceProvider.persistClientPicture(client,
131-
data != null ? Base64.decode(data) : null, checksum);
125+
persistenceProvider.persistClientPicture(client, data != null ? Base64.decode(data) : null);
132126
} catch (IOException ignored) {
133127
}
134128
}

src/main/java/org/monora/uprotocol/core/CommunicationBridge.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static void convertToSSL(@NotNull ConnectionFactory connectionFactory,
252252
* <p>
253253
* For instance, the remote is setting up a file transfer request and is about to pick a client. If you make this
254254
* request in that timespan, this will invoke {@link TransportSeat#handleAcquaintanceRequest(Client, ClientAddress)}
255-
* method on the remote and it will choose you.
255+
* method on the remote, and it will choose you.
256256
*
257257
* @return True if successful.
258258
* @throws IOException If an IO error occurs.
@@ -572,11 +572,12 @@ public CommunicationBridge connect() throws IOException, JSONException, Protocol
572572
String remoteClientUid = activeConnection.receive().getAsString();
573573

574574
if (clientUid != null && !clientUid.equals(remoteClientUid)) {
575-
activeConnection.closeSafely();
575+
Responses.send(activeConnection, false, new JSONObject());
576576
throw new DifferentRemoteClientException(clientUid, remoteClientUid, address);
577577
}
578578

579-
activeConnection.reply(persistenceProvider.clientAsJson(pin));
579+
Responses.send(activeConnection, true, persistenceProvider.clientAsJson(pin));
580+
580581
JSONObject jsonObject = activeConnection.receive().getAsJson();
581582
Client client = ClientLoader.loadAsClient(persistenceProvider, jsonObject, remoteClientUid,
582583
clearBlockedStatus);
@@ -644,4 +645,4 @@ public void setPin(int pin)
644645
this.pin = pin;
645646
}
646647
}
647-
}
648+
}

src/main/java/org/monora/uprotocol/core/TransportSession.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ public void onConnected(@NotNull ActiveConnection activeConnection)
6969
activeConnection.reply(persistenceProvider.getClientUid());
7070

7171
final JSONObject response = activeConnection.receive().getAsJson();
72+
if (!Responses.getResult(response)) {
73+
getLogger().log(Level.INFO, "Remote returned false");
74+
return;
75+
}
76+
7277
final int activePin = persistenceProvider.getNetworkPin();
7378
final boolean hasPin = activePin != 0 && activePin == response.getInt(Keyword.CLIENT_PIN);
7479

src/main/java/org/monora/uprotocol/core/persistence/PersistenceProvider.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import net.iharder.Base64;
44
import org.jetbrains.annotations.NotNull;
55
import org.jetbrains.annotations.Nullable;
6-
import org.json.JSONArray;
76
import org.json.JSONException;
87
import org.json.JSONObject;
98
import org.monora.uprotocol.core.CommunicationBridge;
@@ -27,7 +26,6 @@
2726
import java.security.cert.Certificate;
2827
import java.security.cert.CertificateException;
2928
import java.security.cert.X509Certificate;
30-
import java.util.ArrayList;
3129
import java.util.List;
3230

3331
/**
@@ -71,7 +69,8 @@ public interface PersistenceProvider
7169
default @NotNull JSONObject clientAsJson(int pin) throws JSONException
7270
{
7371
Client client = getClient();
74-
String pictureData = client.hasPicture() ? Base64.encodeBytes(client.getClientPictureData()) : null;
72+
byte[] picture = getClientPicture(client);
73+
String pictureData = picture == null ? null : Base64.encodeBytes(picture);
7574

7675
return new JSONObject()
7776
.put(Keyword.CLIENT_UID, client.getClientUid())
@@ -81,11 +80,11 @@ public interface PersistenceProvider
8180
.put(Keyword.CLIENT_TYPE, client.getClientType().getProtocolValue())
8281
.put(Keyword.CLIENT_VERSION_CODE, client.getClientVersionCode())
8382
.put(Keyword.CLIENT_VERSION_NAME, client.getClientVersionName())
83+
.put(Keyword.CLIENT_PICTURE, pictureData)
8484
.put(Keyword.CLIENT_PROTOCOL_VERSION, client.getClientProtocolVersion())
8585
.put(Keyword.CLIENT_PROTOCOL_VERSION_MIN, client.getClientProtocolVersionMin())
86-
.put(Keyword.CLIENT_PIN, pin)
87-
.put(Keyword.CLIENT_PICTURE, pictureData)
88-
.put(Keyword.CLIENT_PICTURE_CHECKSUM, client.getClientPictureChecksum());
86+
.put(Keyword.CLIENT_REVISION_PICTURE, client.getClientRevisionOfPicture())
87+
.put(Keyword.CLIENT_PIN, pin);
8988
}
9089

9190
/**
@@ -116,14 +115,16 @@ public interface PersistenceProvider
116115
* @param versionName Points to {@link Client#getClientVersionName()}
117116
* @param versionCode Points to {@link Client#getClientVersionCode()}.
118117
* @param protocolVersion Points to {@link Client#getClientProtocolVersion()}.
119-
* @param protocolVersionMin Points {@link Client#getClientProtocolVersionMin()}.
118+
* @param protocolVersionMin Points to {@link Client#getClientProtocolVersionMin()}.
119+
* @param revisionOfPicture Points to {@link Client#getClientRevisionOfPicture()}
120120
* @return The client instance.
121121
* @see #persist(Client, boolean)
122122
* @see #getClientFor(String)
123123
*/
124124
@NotNull Client createClientFor(@NotNull String uid, @NotNull String nickname, @NotNull String manufacturer,
125125
@NotNull String product, @NotNull ClientType type, @NotNull String versionName,
126-
int versionCode, int protocolVersion, int protocolVersionMin);
126+
int versionCode, int protocolVersion, int protocolVersionMin,
127+
long revisionOfPicture);
127128

128129
/**
129130
* todo: Should this really exist? This user can avoid using it. The benefit may be to use it as a factory.
@@ -172,6 +173,17 @@ public interface PersistenceProvider
172173
*/
173174
@NotNull String getClientNickname();
174175

176+
/**
177+
* Returns the profile picture data for the given client.
178+
* <p>
179+
* If the given client's UID matches {@link #getClientUid()}, you should return your own picture data to be sent to
180+
* remote clients.
181+
*
182+
* @param client For which the picture will be provided.
183+
* @return The client picture data or null if no such data exists for the given client.
184+
*/
185+
byte @Nullable [] getClientPicture(@NotNull Client client);
186+
175187
/**
176188
* This should return the unique identifier for this client. It should be both unique and persistent.
177189
* <p>
@@ -402,11 +414,10 @@ public void checkServerTrusted(X509Certificate[] certs, String authType)
402414
* <p>
403415
* The invocation of this method mean the picture is new and should be saved.
404416
*
405-
* @param client The client that owns the picture.
406-
* @param data The bitmap data of the picture which is null if the owner client no longer has one.
407-
* @param checksum The hash code of the given data which is invalidated if the data is null.
417+
* @param client The client that owns the picture.
418+
* @param data The bitmap data of the picture which is null if the owner client no longer has one.
408419
*/
409-
void persistClientPicture(@NotNull Client client, byte @Nullable [] data, int checksum);
420+
void persistClientPicture(@NotNull Client client, byte @Nullable [] data);
410421

411422
/**
412423
* Revoke the current valid network PIN.

0 commit comments

Comments
 (0)