-
Notifications
You must be signed in to change notification settings - Fork 21
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
TRIB-105: Create endpoint for removing connection #146
Changes from all commits
1d2585f
fa7250b
b251c66
ff2ee34
58c5bfe
cb2119f
b4d775c
44fc3fc
b7b1a3d
c6aed44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.savvato.tribeapp.controllers.annotations.controllers.ConnectAPIController; | ||
|
||
|
||
import com.savvato.tribeapp.controllers.annotations.requests.DocumentedRequestBody; | ||
import com.savvato.tribeapp.controllers.annotations.responses.BadRequest; | ||
import com.savvato.tribeapp.controllers.annotations.responses.Success; | ||
import com.savvato.tribeapp.controllers.dto.ConnectionRemovalRequest; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.media.ExampleObject; | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
@Operation( | ||
summary = "Delete connection between two users", | ||
description = "Provided a ConnectionRemovalRequest (see schemas), save the connection.") | ||
@DocumentedRequestBody(description = "A request to delete connection", implementation = ConnectionRemovalRequest.class) | ||
@Success( | ||
description = "Status of attempt to delete connection", | ||
examples = { | ||
@ExampleObject(name = "Connection deleted successfully", value = "true"), | ||
@ExampleObject(name = "Connection could not be deleted", value = "false"), | ||
}) | ||
@BadRequest(description = "Could not delete the connection", noContent = true) | ||
public @interface RemoveConnection { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.savvato.tribeapp.controllers.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
@Schema(description = "A request to delete a connection between two users") | ||
public class ConnectionRemovalRequest { | ||
@Schema(example = "1") | ||
public Long requestingUserId; | ||
|
||
@Schema(example = "2") | ||
public Long connectedWithUserId; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
package com.savvato.tribeapp.repositories; | ||
|
||
import com.savvato.tribeapp.entities.Connection; | ||
import com.savvato.tribeapp.entities.Noun; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.CrudRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface ConnectionsRepository extends CrudRepository<Connection, Long> { | ||
@Query(nativeQuery = true, value = "delete from connections where requesting_user_id=?1 AND to_be_connected_with_user_id=?2") | ||
void removeConnection(Long requestingUserId, Long connectedWithUserId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
package com.savvato.tribeapp.services; | ||
|
||
import com.savvato.tribeapp.config.principal.UserPrincipal; | ||
import com.savvato.tribeapp.controllers.dto.ConnectRequest; | ||
import com.savvato.tribeapp.controllers.dto.ConnectionRemovalRequest; | ||
import com.savvato.tribeapp.dto.ConnectIncomingMessageDTO; | ||
import com.savvato.tribeapp.dto.ConnectOutgoingMessageDTO; | ||
import com.savvato.tribeapp.entities.Connection; | ||
|
@@ -10,9 +9,7 @@ | |
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.messaging.handler.annotation.Header; | ||
import org.springframework.messaging.handler.annotation.MessageMapping; | ||
import org.springframework.messaging.handler.annotation.Payload; | ||
import org.springframework.messaging.simp.SimpMessagingTemplate; | ||
import org.springframework.stereotype.Service; | ||
|
||
|
@@ -37,23 +34,23 @@ public class ConnectServiceImpl implements ConnectService { | |
|
||
private final int QRCODE_STRING_LENGTH = 12; | ||
|
||
public Optional<String> getQRCodeString(long userId){ | ||
public Optional<String> getQRCodeString(long userId) { | ||
String userIdToCacheKey = String.valueOf(userId); | ||
String getCode = cache.get("ConnectQRCodeString", userIdToCacheKey); | ||
Optional<String> opt = Optional.of(getCode); | ||
return opt; | ||
|
||
} | ||
|
||
public Optional<String> storeQRCodeString(long userId){ | ||
public Optional<String> storeQRCodeString(long userId) { | ||
String generatedQRCodeString = generateRandomString(QRCODE_STRING_LENGTH); | ||
String userIdToCacheKey = String.valueOf(userId); | ||
cache.put("ConnectQRCodeString", userIdToCacheKey, generatedQRCodeString); | ||
logger.debug("User ID: " + userId + " ConnectQRCodeString: " + generatedQRCodeString); | ||
return Optional.of(generatedQRCodeString); | ||
} | ||
|
||
private String generateRandomString(int length){ | ||
private String generateRandomString(int length) { | ||
Random random = new Random(); | ||
char[] digits = new char[length]; | ||
digits[0] = (char) (random.nextInt(9) + '1'); | ||
|
@@ -80,11 +77,11 @@ public Boolean validateQRCode(String qrcodePhrase, Long toBeConnectedWithUserId) | |
|
||
@MessageMapping("/connect/room") | ||
public void connect(ConnectIncomingMessageDTO incoming) { | ||
if(!validateQRCode(incoming.qrcodePhrase, incoming.toBeConnectedWithUserId)) { | ||
if (!validateQRCode(incoming.qrcodePhrase, incoming.toBeConnectedWithUserId)) { | ||
ConnectOutgoingMessageDTO msg = ConnectOutgoingMessageDTO.builder() | ||
.connectionError(true) | ||
.message("Invalid QR code; failed to connect.") | ||
.build(); | ||
.connectionError(true) | ||
.message("Invalid QR code; failed to connect.") | ||
.build(); | ||
simpMessagingTemplate.convertAndSendToUser( | ||
String.valueOf(incoming.toBeConnectedWithUserId), | ||
"/connect/user/queue/specific-user", | ||
|
@@ -102,7 +99,7 @@ public void connect(ConnectIncomingMessageDTO incoming) { | |
|
||
public ConnectOutgoingMessageDTO handleConnectionIntent(String connectionIntent, Long requestingUserId, Long toBeConnectedWithUserId) { | ||
if (connectionIntent == "") { | ||
List<Long> recipients = new ArrayList<>(Arrays.asList(toBeConnectedWithUserId)); | ||
List<Long> recipients = new ArrayList<>(Collections.singletonList(toBeConnectedWithUserId)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any specific reason you used Collections.singletonList rather than Array.asList? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I was experimenting with the Collections.singletonList method and accidentally modified it here. I'll undo this change. |
||
return ConnectOutgoingMessageDTO.builder().message("Please confirm that you wish to connect.").to(recipients).build(); | ||
} else if (connectionIntent == "confirmed") { | ||
Boolean connectionStatus = saveConnectionDetails(requestingUserId, toBeConnectedWithUserId); | ||
|
@@ -128,4 +125,16 @@ public ConnectOutgoingMessageDTO handleConnectionIntent(String connectionIntent, | |
} | ||
return null; | ||
} | ||
|
||
public boolean removeConnection(ConnectionRemovalRequest connectionRemovalRequest) { | ||
if (Objects.equals(connectionRemovalRequest.requestingUserId, connectionRemovalRequest.connectedWithUserId)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is Object.equals() necessary here? Would == work as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the ConnectionRemovalRequest DTO uses the Long wrapper type for the user IDs, they're technically different objects, so I don't think == would work. But if I use the "long" primitive type, then == should also work fine. (Other DTO objects also use Long wrapper types though, so for consistency, using the wrapper type may be better.) |
||
return false; | ||
} | ||
try { | ||
connectionsRepository.removeConnection(connectionRemovalRequest.requestingUserId, connectionRemovalRequest.connectedWithUserId); | ||
return true; | ||
} catch (Exception e) { | ||
return false; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets return a ResponseEntity here as well, rather than just boolean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a different endpoint, but I'd be glad to refactor this in another issue! The endpoint in this PR is the one with the @DeleteMapping - this line seems to have changed due to reformatting.