Architecture and Implementation

batterycopperInternet και Εφαρμογές Web

12 Νοε 2013 (πριν από 4 χρόνια και 1 μήνα)

99 εμφανίσεις

Architecture and Implementation

Short video...

User selects the sports he practices or would
like to practice

User selects places on map where practices
the selected sports

User selects his favourite days and time

HomePage showing participants and events
near the selected location

January 2011, We
-
Sport is sponsor of

"2011 IPC ALPINE SKIING WORLD CHAMPIONSHIPS"

Quick diagram

Spring configuration


web.xml

...

<servlet>




<servlet
-
name>sports</servlet
-
name>




<servlet
-
class>






org.springframework.web.servlet.DispatcherServlet




</servlet
-
class>






<load
-
on
-
startup>2</load
-
on
-
startup>


</servlet>


<servlet
-
mapping>




<servlet
-
name>sports</servlet
-
name>




<url
-
pattern>
/api/*
</url
-
pattern>


</servlet
-
mapping>

...

SportController

@Controller

@RequestMapping("
/sport
")

public class SportController extends
AbstractController

{


@Autowired

private SportsService
sportsService
;


@Override

@RequestMapping(method = RequestMethod.GET)

protected ModelAndView
handleRequestInternal
(HttpServletRequest request,

HttpServletResponse response) throws Exception {


setParams(request);

Sport sport = null;

ModelAndView result = new ModelAndView();

sport =
sportsService.findSportById
(getSportId());

result.addObject("sport", sport);

return result;

}








private void setParams(request){...}


}

Handle multiple output types

<?xml..><beans ...">

<bean class="org.springframework.web.servlet.view.
ContentNegotiatingViewResolver
"> <property name="
mediaTypes
">
<map><entry key="
json
" value="
application/json
" /> <entry key="
xml
" value="
application/xml
" /> <entry key="
pdf
"
value="
application/pdf
" /></map> </property> <property name="defaultViews"> <list> <bean class="com.sports.service.
PDFPage
"
p:contentType="
application/pdf
" /> <bean class="org.springframework.web.servlet.view.
json.MappingJacksonJsonView
" />
<bean class="org.springframework.web.servlet.view.
xml.MarshallingView
"> <constructor
-
arg> <bean id="castorMarshaller"
class="org.springframework.oxm.castor.
CastorMarshaller
" /> </constructor
-
arg> </bean></list></property> </bean></beans>

Spring 3


ContentNegotiatingViewResolver

(sports
-
servlet.xml)

Examples of API requests:

RpcSportsServiceImpl

public class
RpcSportsServiceImpl

extends
AutoinjectingRemoteServiceServlet

implements

RpcSportsService {








@Autowired




private SportsService

sportsService
;





public Sport findSportById(Long sportId) {






return
sportsService.findSportById
(sportId);




}












// getters and setters of sportsService

}

AutoinjectingRemoteServiceServlet

public abstract class
AutoinjectingRemoteServiceServlet

extends
RemoteServiceServlet {




@Override



public void
init
(ServletConfig config) throws ServletException {





super.init(config);

WebApplicationContext ctx =

WebApplicationContextUtils





.getRequiredWebApplicationContext(config.
getServletContext()
);




AutowireCapableBeanFactory beanFactory = ctx

.
getAutowireCapableBeanFactory
();





beanFactory.autowireBean(this);



}

}

SportsServiceImpl

public class
SportsServiceImpl

implements
SportsService

{








@Autowired



private SportDao
sportDao
;








public Sport
findSportById
(Long sportId) {




final String cacheKey = "findSportById_"+sportId;






if (!getCache().contains(cacheKey) ||










getCache().get(cacheKey) == null) {

getCache().put(cacheKey,
sportDao.findById(sportId))
;






}






return (Sport) getCache().get(cacheKey);




}

}

DataStore Access
-

JDO

<?xml version="1.0" encoding="UTF
-
8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

....... default
-
lazy
-
init="true">

<context:
component
-
scan

base
-
package="com.sports.dao.jdo" /> <context:
component
-
scan

base
-
package="com.sports.server.servlet.filter" /> <bean id="
sportsService
" class="com.sports.service.SportsServiceImpl" />
<tx:annotation
-
driven /> <bean id="
persistenceManagerFactory
" class="com.sports.server.utils.GaePMF" factory
-
method="getPersistenceManagerFactory"> </bean> <bean id="
transactionManager
"
class="org.springframework.orm.jdo.JdoTransactionManager"> <property name="persistenceManagerFactory"
ref="persistenceManagerFactory" /> </bean> <bean id="
jdoTemplate
" class="org.springframework.orm.jdo.JdoTemplate">
<constructor
-
arg ref="persistenceManagerFactory" /> <constructor
-
arg value="false" type="boolean" /> </bean> </beans>

Spring 3
-

JDOTemplate
Configuration
(applicationContext.xml)

BaseDaoJdo

package com.sports.dao.jdo;

import ...


public abstract class BaseDaoJdo {


@Autowired

protected PersistenceManagerFactory
pmf
;


@Autowired

protected JdoTemplate
jdoTemplate
;

@Autowired

protected JdoTransactionManager
transactionManager
;


}

SportDaoJdo

package com.sports.dao.jdo;

import ...


@Component

public class SportDaoJdo extends
BaseDaoJdo

implements SportDao {






public Sport save(Sport sport) {

return
jdoTemplate
.makePersistent(sport);

}






@SuppressWarnings("unchecked")

public Collection<Sport> findAll() {

Object[] a = {};

return

jdoTemplate
.detachCopyAll(jdoTemplate.find("select from "

+
Sport.class.getName() + " order by name", a));

}

}

Cron + TaskQueue

cron:

-

description: Update Sports Counter


url:
/api/cron/updateSportCounter


schedule: every 24 hours


cron.yaml

UpdateSportCounter

@Controller

@RequestMapping("
/cron/updateSportCounter
")

public class UpdateSportCounter {


@Autowired

private SportsService
sportsService
;


@RequestMapping(method = RequestMethod.GET)


public void
execute
(HttpServletResponse response) throws IOException {





for (SportOutput sportOut :
sportsService
.findAllSports()){































final Long id = sportOut.getId();






final int counter =
sportsService
.getCountPlayersBySport(id);






UpdateCounterSportTaskQueue.updateCounterSportTask
(id, counter);

}

response.getWriter().write("Scheduled all taskqueues.");

}

}

UpdateCounterSportTaskQueue

public class UpdateCounterSportTaskQueue {


public static void
updateCounterSportTask
(final Long id,

final int counter) {




TaskOptions
taskOptions

=








TaskOptions.Builder.withUrl(

"
/api/task/updateCounterSport
");





taskOptions
.param("id", String.valueOf(id));



taskOptions
.param("counter", String.valueOf(counter));




QueueFactory.getDefaultQueue().add(
taskOptions
);




}

}

UpdateCounterSportWorker

@Controller

@RequestMapping("/task/updateCounterSport")

public class UpdateCounterSportWorker {






@Autowired

private SportDao
sportDao
;






@RequestMapping(method = RequestMethod.POST)

@ResponseStatus(HttpStatus.ACCEPTED)

@Transactional(propagation = Propagation.REQUIRES_NEW)

public void execute(
@RequestParam long id, @RequestParam int counter
) {

Sport sport =
sportDao
.findById(id);

sport.setCounter(counter);

sport.setUpdatedDate(new Date());

sportDao
.save(sport);

}

}

Version Control
-

GIT

Decentralization

Distributed Version Control Systems take advantage of the peer
-
to
-
peer
approach. Clients can communicate between each other and maintain their
own local branches without having to go through a Central
Server/Repository. Then synchronization takes place between the peers who
decide which changesets to exchange.

GIT + Dropbox

http://stackoverflow.com/questions/1960799/using
-
gitdropbox
-
together
-
effectively


I think that git on dropbox is great. I use it all of the time. I have multiple
computers (two at home and one elsewhere) that I use dropbox as a central
bare repo. Since I don't want to host it on a public service and I don't have
access to a server that I can always ssh to, Dropbox takes care of this by
syncing (very quickly) in the background.

Setup is something like this:

Thank you for your kind attention

busy busy ...