25
Architecture and Implementation

We sport architecture_implementation

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: We sport architecture_implementation

Architecture and Implementation

Page 3: We sport architecture_implementation

User selects the sports he practices or would like to practice

Page 4: We sport architecture_implementation

User selects places on map where practices the selected sports

Page 5: We sport architecture_implementation

User selects his favourite days and time

Page 6: We sport architecture_implementation

HomePage showing participants and events near the selected location

Page 7: We sport architecture_implementation

January 2011, We-Sport is sponsor of"2011 IPC ALPINE SKIING WORLD CHAMPIONSHIPS"

Page 8: We sport architecture_implementation

Quick diagram

Page 9: We sport architecture_implementation

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

Page 10: We sport architecture_implementation

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){...}}

Page 11: We sport architecture_implementation

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)

Page 12: We sport architecture_implementation

Examples of API requests:

Page 13: We sport architecture_implementation

RpcSportsServiceImpl

public class RpcSportsServiceImpl extends AutoinjectingRemoteServiceServletimplementsRpcSportsService {

@Autowiredprivate SportsService sportsService;

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

}

// getters and setters of sportsService}

Page 14: We sport architecture_implementation

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);}

}

Page 15: We sport architecture_implementation

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);

}}

Page 16: We sport architecture_implementation

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)

Page 17: We sport architecture_implementation

BaseDaoJdo

package com.sports.dao.jdo;import ...

public abstract class BaseDaoJdo {

@Autowiredprotected PersistenceManagerFactory pmf;

@Autowiredprotected JdoTemplate jdoTemplate;@Autowiredprotected JdoTransactionManager transactionManager;

}

Page 18: We sport architecture_implementation

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));}}

Page 19: We sport architecture_implementation

Cron + TaskQueue

cron:- description: Update Sports Counterurl: /api/cron/updateSportCounterschedule: every 24 hours

cron.yaml

Page 20: We sport architecture_implementation

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."); } }

Page 21: We sport architecture_implementation

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);

}

}

Page 22: We sport architecture_implementation

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);} }

Page 23: We sport architecture_implementation

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.

Page 24: We sport architecture_implementation

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:

Page 25: We sport architecture_implementation

Thank you for your kind attention

busy busy ...