Upload
aurelianaur
View
829
Download
0
Embed Size (px)
DESCRIPTION
We-Sport.com architecture implementation with Google Web Toolkit and Google App Engine.
Citation preview
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 {
@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 ...