• No results found

Implementation of the Campaigns Function

6.4 Implementation of the Dashboard Functions

6.4.1 Implementation of the Campaigns Function

The CampaignResource, CampaignServiceImpl, Campaign, and Message classes were used to implement the business layer. The CampaignDaoImpl class was used to implement the

6.4. IMPLEMENTATION OF THE DASHBOARD FUNCTIONS 86

data access layer. Figures 6.3 and 6.4 are high-level diagrams showing the classes and how they relate to each other.

Figure 6.3: Classes used to implement the business and data access layers of the Cam-paigns function

6.4.1.1 Business Layer

The CampaignResource class, located in the resource package, was used to implement the Service Layer to expose the Campaigns function as a RESTful web service. It has a campaignService eld of CampaignService interface data type, which is annotated with

@Autowired so that it is automatically injected with its dependency using DI. The class has methods to create, update, delete, and retrieve campaign data, and set campaign targets and messages.

The CampaignServiceImpl class, located in the service package, was used to implement the App Services. It implements the CampaignService interface. It has a campaignDao eld of the CampaignDao interface data type, which is annotated with the @Resource of the javax.annotation.Resource data type so that it is automatically injected with its depen-dency using DI. The class has methods that correspond to those of the CampaignResource class.

The Campaign and Message classes, located in the model package, were used to implement the Domain Model. The elds of the Campaign class are title, aim, description, slogan, creationDate, startDate, endDate, status, target, user, organisa-tion, and messages. The title, aim, descriporganisa-tion, slogan, creationDate,

star-6.4. IMPLEMENTATION OF THE DASHBOARD FUNCTIONS 87

tDate, endDate, and status are annotated with @Column and @NotNull. The target

eld has a Target class data type, the organisation eld has a Organisation class data type and user eld has a User class data type. The elds are annotated with @JsonBack-Reference and @ManyToOne. The @JsonBack@JsonBack-Reference indicates that the annotated eld is part of a two-way linkage between elds and that its role is `child' (or `back') link.12 The

@ManyToOne indicates that many campaigns can have the same target, can be created by the same user, or can belong to the same organisation, but a campaign can have one and only one target, can be created by one and only one user, and can belong to one and only organisation. The Organisation and User classes have a campaign eld of the Campaign class data type that is annotated with @OneToMany and @JsonManagedReference. The

@OneToMany annotation is a reverse of the @ManyToOne. The @JsonManagedReference indicates that the annotated eld is part of a two-way linkage between elds and that its role is `parent' (or `forward') link.13 The messages eld has a java.util.List<Message>

data type and is annotated with @OneToMany and @JsonManagedReference. The elds of the Message class are messageTitle, message, and campaign. The messageTitle and message elds are annotated with @Column and @NotNull. The campaign eld has a Campaign class data type and is annotated with @JsonBackReference and @ManyToOne.

Figure 6.4 shows the classes that implement the Domain Model and how they relate to each other.

Figure 6.4: Domain Model classes for the Campaigns function

12http://jackson.codehaus.org/1.6.0/javadoc/org/codehaus/jackson/annotate/JsonBackReference.html 13http://jackson.codehaus.org/1.6.0/javadoc/org/codehaus/jackson/annotate/JsonManagedReference.html

6.4. IMPLEMENTATION OF THE DASHBOARD FUNCTIONS 88

6.4.1.2 Data Access Layer

The CampaignDaoImpl class, located in the DAO package, was used to implement the data access layer. It extends the BaseDao class and implements the CampaignDao interface.

The class has methods to create, delete, and retrieve campaign information.

6.4.1.3 Publishing a Campaign

According to the requirements specication, publication a campaign retrieves a copy of the information from the Dashboard database and posts it to the HealthMessenger where a record is created in the database. Publishing from one domain (e.g. www.example1.com) to another domain (e.g. www.example2.com) is subject to same-origin restrictions to network requests enforced by user agents (web browsers) [85]. These restrictions are done to prevent a client-side web application running on one domain from executing (POST, GET, DELETE etc.) requests at another domain. The aim is to limit unsafe HTTP requests that can be automatically launched towards destinations on a domain that is dierent from where the request is coming from. To allow cross-origin network requests, the World Wide Web Consortium (W3C)14 developed a specication named Cross-Origin Resource Sharing (CORS) to enable an API to make cross-origin requests to resources.

The specication was used to implement data interchange between the Dashboard and the HealthMessenger. The implementation used a Jersey response lter and works as follows:

1. when making a cross-domain request (publishing a campaign), a request called a preight request is made in order to discover whether the cross-origin resource (HealthMessenger) is prepared to accept the request - this is done automatically by the user agent using the OPTIONS HTTP method);

2. the preight request executes a method in the HealthMessenger, which is annotated with @OPTIONS (see lines 13 - 17 of Listing 6.2) and sends back an HTTP 200 OK status code as a response;

3. the Jersey response lter adds the Access-Control-Allow-Origin header to the re-sponse, which has a value of the URL of the Dashboard to indicate that it accepts cross-domain requests from that URL (Note: The response is cached on the Dash-board user agent for 24 hours and any request made within the 24 hour period is not preceded by a preight request); and

14http://www.w3.org/TR/cors/

6.4. IMPLEMENTATION OF THE DASHBOARD FUNCTIONS 89

4. the preight request is followed by the actual request to post campaign data to the HealthMessenger.

9 protected void setCampaignService ( CampaignService campaignService ) {

10 this . campaignService = campaignService ;

11 }

12

13 @OPTIONS

14 @CorsPreflight

15 public Response optionRequest ( ) {

16 return Response . ok ( ) . b u i l d ( ) ;

22 public Response saveOrUpdateCampaign (CampaignDTO campaign ) {

23 campaignService . saveOrUpdateCampaign ( campaign ) ;

24 return Response . noContent ( ) . b u i l d ( ) ;

25 }

26

27 @RolesAllowed ({ " a d m i n i s t r a t o r " , " a u t h e n t i c a t e d " })

28 @GET

29 public Response getRunningCampaigns ( @Context SecurityContext sc ) { 30 ExternalUser userMakingRequest = ( ExternalUser ) sc . g e t U s e r P r i n c i p a l ( ) ;

31 List <CampaignRequest> campaignList = campaignService . getRunningCampaigns ( userMakingRequest ) ;

32 return Response . ok ( ) . e n t i t y ( campaignList ) . b u i l d ( ) ;

33 }

34 }

Listing 6.2: Extract of the source code for CampaignResource class