Skip to content

Commit

Permalink
feat(Peer Group): Add endpoint for getting Peer Group (#45)
Browse files Browse the repository at this point in the history
* feat(Peer Group): Add endpoint to get PeerGroup

- Ensure there are at least 2 submissions before pairing

* feat(Peer Group): Add endpoint to get PeerGroup

- Threshold not met now throws an exception instead of returning null.
- Throws PeerGroupCreationException when there are other workgroups
to wait for.
- Fix issue calculating completion percentage by using float instead
of int.

* feat(Peer Group): Add endpoint to get PeerGroup

- Add id equality test to WorkgroupImpl and PersistentGroup
- Changed getNumWorkgroupsInPeerGroup() to get PeerGroup for activity
component instead of logic component
- Return exception key in ResponseBody
  • Loading branch information
hirokiterashima authored Oct 28, 2021
1 parent ad1a14b commit 5317963
Show file tree
Hide file tree
Showing 18 changed files with 833 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Cascade;
import org.hibernate.proxy.HibernateProxy;
import org.wise.portal.domain.group.Group;
import org.wise.portal.domain.user.User;
import org.wise.portal.domain.user.impl.UserImpl;
Expand Down Expand Up @@ -132,9 +133,16 @@ public boolean equals(Object obj) {
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
if (obj instanceof HibernateProxy) {
if (getClass() != (( HibernateProxy) obj).getHibernateLazyInitializer().getImplementation().getClass()) {
return false;
}
} else if (getClass() != obj.getClass())
return false;
final PersistentGroup other = (PersistentGroup) obj;
if (this.getId() != null && this.getId().equals(other.getId())) {
return true;
}
if (name == null) {
if (other.name != null)
return false;
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/wise/portal/domain/peergroup/PeerGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
*/
package org.wise.portal.domain.peergroup;

import java.util.Set;

import org.wise.portal.domain.peergroupactivity.PeerGroupActivity;
import org.wise.portal.domain.workgroup.Workgroup;

/**
* An interface that defines a group of workgroups
Expand All @@ -32,4 +35,10 @@
public interface PeerGroup {

PeerGroupActivity getPeerGroupActivity();

Set<Workgroup> getMembers();

void setMembers(Set<Workgroup> members);

public void addMember(Workgroup workgroup);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ public PeerGroupImpl(PeerGroupActivity activity, Set<Workgroup> members) {
this.peerGroupActivity = activity;
this.members = members;
}

public void addMember(Workgroup workgroup) {
this.members.add(workgroup);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,25 @@
*/
public interface PeerGroupActivity {

void setRun(Run run);
String getComponentId();

Long getId();

Run getRun();

String getLogic();

String getLogicNodeId() throws JSONException;

String getLogicComponentId() throws JSONException;

String getLogicNodeId() throws JSONException;

int getLogicThresholdCount();

int getLogicThresholdPercent();

int getMaxMembershipCount();

String getNodeId();

Run getRun();

void setRun(Run run);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import lombok.Setter;
import org.wise.portal.domain.group.Group;
import org.wise.portal.domain.group.impl.PersistentGroup;
import org.hibernate.proxy.HibernateProxy;
import org.wise.portal.domain.Tag;
import org.wise.portal.domain.impl.TagImpl;
import org.wise.portal.domain.run.Run;
Expand Down Expand Up @@ -179,9 +180,16 @@ public boolean equals(Object obj) {
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
if (obj instanceof HibernateProxy) {
if (getClass() != (( HibernateProxy) obj).getHibernateLazyInitializer().getImplementation().getClass()) {
return false;
}
} else if (getClass() != obj.getClass())
return false;
final WorkgroupImpl other = (WorkgroupImpl) obj;
if (this.getId() != null && this.getId().equals(other.getId())) {
return true;
}
if (group == null) {
if (other.group != null)
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright (c) 2008-2021 Regents of the University of California (Regents).
* Created by WISE, Graduate School of Education, University of California, Berkeley.
*
* This software is distributed under the GNU General Public License, v3,
* or (at your option) any later version.
*
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
* documentation for any purpose, provided that the above copyright notice and
* the following two paragraphs appear in all copies of this software.
*
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
* HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
* REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.wise.portal.presentation.web.controllers.peergroup;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.wise.portal.dao.ObjectNotFoundException;
import org.wise.portal.domain.peergroup.PeerGroup;
import org.wise.portal.domain.peergroupactivity.PeerGroupActivity;
import org.wise.portal.domain.run.Run;
import org.wise.portal.domain.user.User;
import org.wise.portal.domain.workgroup.Workgroup;
import org.wise.portal.service.peergroup.PeerGroupActivityThresholdNotSatisfiedException;
import org.wise.portal.service.peergroup.PeerGroupCreationException;
import org.wise.portal.service.peergroup.PeerGroupService;
import org.wise.portal.service.peergroupactivity.PeerGroupActivityNotFoundException;
import org.wise.portal.service.peergroupactivity.PeerGroupActivityService;
import org.wise.portal.service.run.RunService;
import org.wise.portal.service.user.UserService;
import org.wise.portal.service.workgroup.WorkgroupService;

@RestController
@Secured("ROLE_USER")
@RequestMapping("/api/peer-group")
public class PeerGroupAPIController {

@Autowired
private RunService runService;

@Autowired
private UserService userService;

@Autowired
private WorkgroupService workgroupService;

@Autowired
private PeerGroupService peerGroupService;

@Autowired
private PeerGroupActivityService peerGroupActivityService;

@GetMapping("/run/{runId}/workgroup/{workgroupId}/node-id/{nodeId}/component-id/{componentId}")
PeerGroup getPeerGroup(@PathVariable Long runId, @PathVariable Long workgroupId,
@PathVariable String nodeId, @PathVariable String componentId, Authentication auth)
throws ObjectNotFoundException, PeerGroupActivityNotFoundException,
PeerGroupCreationException, PeerGroupActivityThresholdNotSatisfiedException {
Run run = runService.retrieveById(runId);
Workgroup workgroup = workgroupService.retrieveById(workgroupId);
User user = userService.retrieveUserByUsername(auth.getName());
if (workgroupService.isUserInWorkgroupForRun(user, run, workgroup)) {
return getPeerGroup(run, nodeId, componentId, workgroup);
} else {
throw new AccessDeniedException("Not permitted");
}
}

private PeerGroup getPeerGroup(Run run, String nodeId, String componentId, Workgroup workgroup)
throws PeerGroupActivityNotFoundException, PeerGroupCreationException,
PeerGroupActivityThresholdNotSatisfiedException {
PeerGroupActivity activity = peerGroupActivityService.getByComponent(run, nodeId, componentId);
return peerGroupService.getPeerGroup(workgroup, activity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,21 @@
*/
package org.wise.portal.service.peergroup;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
* A checked exception that is thrown when the PeerGroup is not ready to be formed yet
* because a threshold has not been met
*
* @author Hiroki Terashima
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
public class PeerGroupActivityThresholdNotSatisfiedException extends Exception {

private static final long serialVersionUID = 1L;

public PeerGroupActivityThresholdNotSatisfiedException() {
super("PeerGroupActivityThresholdNotSatisfied");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,21 @@
*/
package org.wise.portal.service.peergroup;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
* A checked exception that is thrown while creating a PeerGroup, for example not being able to
* find the members to group together
*
* @author Hiroki Terashima
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
public class PeerGroupCreationException extends Exception {

private static final long serialVersionUID = 1L;

public PeerGroupCreationException() {
super("PeerGroupWaitingForClassmates");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2008-2021 Regents of the University of California (Regents).
* Created by WISE, Graduate School of Education, University of California, Berkeley.
*
* This software is distributed under the GNU General Public License, v3,
* or (at your option) any later version.
*
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
* documentation for any purpose, provided that the above copyright notice and
* the following two paragraphs appear in all copies of this software.
*
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
* HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
* REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.wise.portal.service.peergroup;

import org.wise.portal.domain.group.Group;
import org.wise.portal.domain.peergroupactivity.PeerGroupActivity;

/**
* @author Hiroki Terashima
*/
public interface PeerGroupThresholdService {

/**
* Returns true iff the completion threshold has been satisfied to start creating PeerGroup.
* Completion threshold includes minimum workgroups completed count and percentage
* @param activity PeerGroupActivity for which to test for PeerGroup members
* @param period Group subset of workgroups in the run to test for PeerGroup members
* @return boolean
*/
public boolean isCompletionThresholdSatisfied(PeerGroupActivity activity, Group period);

/**
* Returns true iff this workgroup is the last workgroup to be in a PeerGroup (last one left), or
* there are at least two workgroups who have completed the logic step but are not in a PeerGroup
* @param activity PeerGroupActivity for which to test for PeerGroup members
* @param period Group subset of workgroups in the run to test for PeerGroup members
* @return boolean
*/
public boolean canCreatePeerGroup(PeerGroupActivity activity, Group period);
}
Loading

0 comments on commit 5317963

Please sign in to comment.