We sport architecture_implementation

Preview:

DESCRIPTION

We-Sport.com architecture implementation with Google Web Toolkit and Google App Engine.

Citation preview

Architecture and Implementation

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 {

@Autowiredprivate 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 3ContentNegotiatingViewResolver

(sports-servlet.xml)

Examples of API requests:

RpcSportsServiceImpl

public class RpcSportsServiceImpl extends AutoinjectingRemoteServiceServletimplementsRpcSportsService {

@Autowiredprivate SportsService sportsService;

public Sport findSportById(Long sportId) {return sportsService.findSportById(sportId);

}

// getters and setters of sportsService}

AutoinjectingRemoteServiceServlet

public abstract class AutoinjectingRemoteServiceServlet extends RemoteServiceServlet {

@Overridepublic 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 {

@Autowiredprivate 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 {

@Autowiredprotected PersistenceManagerFactory pmf;

@Autowiredprotected JdoTemplate jdoTemplate;@Autowiredprotected JdoTransactionManager transactionManager;

}

SportDaoJdopackage com.sports.dao.jdo;import ...

@Componentpublic 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 Counterurl: /api/cron/updateSportCounterschedule: 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 {

@Autowiredprivate 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

DecentralizationDistributed 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 ...

Recommended