Skip to content

Commit

Permalink
Merge pull request #54 from rwth-acis/rc_v7.1.0
Browse files Browse the repository at this point in the history
New Release v0.7.1
  • Loading branch information
hexTileX authored Oct 17, 2017
2 parents 48f232f + 58fc879 commit b519b58
Show file tree
Hide file tree
Showing 58 changed files with 768 additions and 504 deletions.
2 changes: 1 addition & 1 deletion etc/ant_configuration/service.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
service.version=0.7
service.version=0.7.1
service.name=de.rwth.dbis.acis.bazaar.service
service.path=de/rwth/dbis/acis/bazaar/service
service.class=BazaarService
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
dbUserName=root
dbPassword=reqbaz
dbUrl=jdbc:mysql://localhost:3306/reqbaz
lang=eng
lang=en
country=us
baseURL=http://localhost:8080/bazaar/
frontendBaseURL=http://localhost:5000/
activityTrackerService=de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService@0.4
activityOrigin=https://requirements-bazaar.org
smtpServer=
emailFromAddress=
emailSummaryTimePeriodInMinutes=
monitor=
44 changes: 24 additions & 20 deletions src/i18n/Translation_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,28 @@ error.authorization.requirement.modify=Only the creator can modify requirements.
error.resource.notfound=$s not found.

# email fields. english only at the moment.
email.subject.requirement.created=New Requirement:
email.subject.requirement.updated=Updated Requirement:
email.subject.requirement.realized=Realized Requirement:
email.subject.comment.created=New Comment to Requirement:
email.subject.comment.updated=Updated Comment to Requirement:
email.subject.category.created=New Component:
email.subject.category.updated=Updated Component:
email.subject.project.created=New Project:
email.subject.project.updated=Updated Project:
email.bodyText.greeting=Hello,
email.bodyText.requirement.created=a new requirement that might may be interested in was created:
email.bodyText.requirement.updated=a requirement that you might be interested in was updated:
email.bodyText.requirement.realized=a requirement that you might be interested in was realized:
email.bodyText.comment.created=a new comment that you might be interested in was posted:
email.bodyText.comment.updated=a comment that you might be interested in was updated:
email.bodyText.category.created=a new category that you might be interested in was created:
email.bodyText.category.updated=a category that you might be interested in was updated:
email.bodyText.project.created=a new project that you might be interested in was created:
email.bodyText.project.updated=a project that you might be interested in was updated:
email.bodyText.footer1=This email was automatically sent by Requirements Bazaar.
email.bodyText.footer2=To change your email notification settings, please go to your profile settings on Requirements Bazaar.
email.bodyText.user=User
email.bodyText.created=created
email.bodyText.updated=updated
email.bodyText.realized=realized
email.bodyText.project=project
email.bodyText.category=category
email.bodyText.requirement=requirement
email.bodyText.comment=comment
email.bodyText.attachment=attachment
email.bodyText.forDetails=For more details, check:
email.bodyText.in=in
email.bodyText.for=for
email.bodyText.with=with
email.bodyText.the=the
email.bodyText.description=description
email.subject.New=New
email.subject.singleSummary=update on Requirements Bazaar!
email.subject.multipleSummary=updates on Requirements Bazaar!
email.subject.updated=Updated
email.subject.realized=Realized
email.bodyText.news=Requirements Bazaar has news for an item you are following:
email.bodyText.nextSummary=In case there is more activity on Requirements Bazaar, we will send you another notification in around %s minutes.
email.bodyText.bestWishes=Best,\r\n Requirements Bazaar
email.bodyText.footer=This email was generated automatically by Requirements Bazaar.\r\nTo change your email notification settings, please log in and check your profile settings:\r\nhttps://requirements-bazaar.org
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,8 @@ public Response getAttachmentsForRequirement(int requirementId, int page, int pe
responseBuilder = responseBuilder.entity(attachmentsResult.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, attachmentsResult, "requirements/" + String.valueOf(requirementId) + "/attachments", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, attachmentsResult);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
Expand Down
94 changes: 60 additions & 34 deletions src/main/de/rwth/dbis/acis/bazaar/service/BazaarService.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@
import org.jooq.SQLDialect;

import javax.sql.DataSource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -87,6 +84,7 @@ public class BazaarService extends RESTService {
protected String activityOrigin;
protected String smtpServer;
protected String emailFromAddress;
protected String emailSummaryTimePeriodInMinutes;

private Vtor vtor;
private List<BazaarFunctionRegistrar> functionRegistrar;
Expand Down Expand Up @@ -118,38 +116,29 @@ public BazaarService() throws Exception {
dataSource = setupDataSource(dbUrl, dbUserName, dbPassword);

functionRegistrar = new ArrayList<>();
functionRegistrar.add(new BazaarFunctionRegistrar() {
@Override
public void registerFunction(EnumSet<BazaarFunction> functions) throws BazaarException {
DALFacade dalFacade = null;
try {
dalFacade = getDBConnection();
AuthorizationManager.SyncPrivileges(dalFacade);
} catch (BazaarException ex) {
ExceptionHandler.getInstance().convertAndThrowException(ex, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, Localization.getInstance().getResourceBundle().getString("error.privilege_sync"));
} catch (Exception e) {
ExceptionHandler.getInstance().convertAndThrowException(e, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, Localization.getInstance().getResourceBundle().getString("error.privilege_sync"));
} finally {
closeDBConnection(dalFacade);
}
functionRegistrar.add(functions -> {
DALFacade dalFacade = null;
try {
dalFacade = getDBConnection();
AuthorizationManager.SyncPrivileges(dalFacade);
} catch (BazaarException ex) {
ExceptionHandler.getInstance().convertAndThrowException(ex, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, Localization.getInstance().getResourceBundle().getString("error.privilege_sync"));
} catch (Exception e) {
ExceptionHandler.getInstance().convertAndThrowException(e, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, Localization.getInstance().getResourceBundle().getString("error.privilege_sync"));
} finally {
closeDBConnection(dalFacade);
}
});

functionRegistrar.add(new BazaarFunctionRegistrar() {
@Override
public void registerFunction(EnumSet<BazaarFunction> functions) {
if (functions.contains(BazaarFunction.VALIDATION)) {
createValidators();
}
functionRegistrar.add(functions -> {
if (functions.contains(BazaarFunction.VALIDATION)) {
createValidators();
}
});

functionRegistrar.add(new BazaarFunctionRegistrar() {
@Override
public void registerFunction(EnumSet<BazaarFunction> functions) throws Exception {
if (functions.contains(BazaarFunction.USER_FIRST_LOGIN_HANDLING)) {
registerUserAtFirstLogin();
}
functionRegistrar.add(functions -> {
if (functions.contains(BazaarFunction.USER_FIRST_LOGIN_HANDLING)) {
registerUserAtFirstLogin();
}
});

Expand All @@ -160,16 +149,28 @@ public void registerFunction(EnumSet<BazaarFunction> functions) throws Exception
if (!smtpServer.isEmpty()) {
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpServer);
notificationDispatcher.setEmailDispatcher(new EmailDispatcher(this, smtpServer, emailFromAddress, frontendBaseURL));
notificationDispatcher.setEmailDispatcher(new EmailDispatcher(this, smtpServer, emailFromAddress, frontendBaseURL, emailSummaryTimePeriodInMinutes));

if (!emailSummaryTimePeriodInMinutes.isEmpty()) {
try {
// This task is scheduled to run every 60 seconds * emailSummaryTimePeriodInMinutes
Timer timer = new Timer();
timer.scheduleAtFixedRate((NotificationDispatcherImp) notificationDispatcher, 0, 60000 * Integer.valueOf(emailSummaryTimePeriodInMinutes));
} catch (Exception ex) {
logger.warning(ex.getMessage());
}
}

}

notificationDispatcher.setBazaarService(this);
}

@Api(value = "/", description = "Bazaar service")
@SwaggerDefinition(
info = @Info(
title = "Requirements Bazaar",
version = "0.7",
version = "0.7.1",
description = "Requirements Bazaar project",
termsOfService = "http://requirements-bazaar.org",
contact = @Contact(
Expand Down Expand Up @@ -202,7 +203,6 @@ public static class Resource {
@ApiResponses(value = {
@ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Returns statistics", response = Statistic.class),
@ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized"),
@ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Not found"),
@ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems")
})
public Response getStatistics(
Expand Down Expand Up @@ -240,6 +240,32 @@ public Response getStatistics(
bazaarService.closeDBConnection(dalFacade);
}
}

/**
* This method sends all notifications (emails) in the waiting queue. Run this method before shutting down Requirements Bazaar.
*
* @return Response
*/
@POST
@Path("/notifications")
@ApiOperation(value = "This method sends all notifications (emails) in the waiting queue. Run this method before shutting down Requirements Bazaar.")
@ApiResponses(value = {
@ApiResponse(code = HttpURLConnection.HTTP_CREATED, message = "Notifications send"),
@ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized"),
@ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems")
})
public Response sendNotifications() {
// TODO: Use authorization scopes to limit users who can run this method to admins
try {
bazaarService.notificationDispatcher.run();
return Response.status(Response.Status.CREATED).build();
} catch (Exception ex) {
BazaarException bex = ExceptionHandler.getInstance().convert(ex, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, ex.getMessage());
L2pLogger.logEvent(NodeObserver.Event.SERVICE_ERROR, Context.getCurrent().getMainAgent(), "Send Notifications failed");
bazaarService.logger.warning(bex.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
}
}
}

public String notifyRegistrars(EnumSet<BazaarFunction> functions) {
Expand Down Expand Up @@ -342,7 +368,7 @@ public static DataSource setupDataSource(String dbUrl, String dbUserName, String
return dataSource;
}

public DALFacade getDBConnection() throws Exception {
public DALFacade getDBConnection() throws Exception { // TODO: Specify Exception
return new DALFacadeImpl(dataSource, SQLDialect.MYSQL);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ public Response getCategoriesForProject(int projectId, int page, int perPage, St
responseBuilder = responseBuilder.entity(categoriesResult.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, categoriesResult, "projects/" + String.valueOf(projectId) + "/categories", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, categoriesResult);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
Expand Down Expand Up @@ -685,9 +684,8 @@ public Response getFollowersForCategory(@PathParam("categoryId") int categoryId,
responseBuilder = responseBuilder.entity(categoryFollowers.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, categoryFollowers, "categories/" + String.valueOf(categoryId) + "/followers", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, categoryFollowers);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,8 @@ public Response getCommentsForRequirement(int requirementId, int page, int perPa
responseBuilder = responseBuilder.entity(commentsResult.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, commentsResult, "requirements/" + String.valueOf(requirementId) + "/comments", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, commentsResult);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,8 @@ public Response getProjects(
responseBuilder = responseBuilder.entity(projectsResult.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, projectsResult, "projects", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, projectsResult);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
logger.warning(bex.getMessage());
L2pLogger.logEvent(NodeObserver.Event.SERVICE_ERROR, Context.getCurrent().getMainAgent(), "Get projects failed");
Expand Down Expand Up @@ -612,9 +611,8 @@ public Response getFollowersForProject(@PathParam("projectId") int projectId,
responseBuilder = responseBuilder.entity(projectFollowers.toJSON());
responseBuilder = bazaarService.paginationLinks(responseBuilder, projectFollowers, "projects/" + String.valueOf(projectId) + "/followers", parameter);
responseBuilder = bazaarService.xHeaderFields(responseBuilder, projectFollowers);
Response response = responseBuilder.build();

return response;
return responseBuilder.build();
} catch (BazaarException bex) {
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
Expand Down
Loading

0 comments on commit b519b58

Please sign in to comment.