SlideShare ist ein Scribd-Unternehmen logo
1 von 10
Downloaden Sie, um offline zu lesen
App Maker Server - Part II
REST API
✦The API will consist of multiple stages to construct the
restaurant in the cloud
✦We will upload the various pieces of the restaurant
(images, dishes etc.) then request a build
© Codename One 2017 all rights reserved
API calls
✦/updateRestaurant - will either update or create a
restaurant entry in the database, returns the secret
✦/dish - allows updating/adding/deleting a dish
✦/files - fetches a result file from the build
✦/doBuildApp - actually builds the app based on the
values set in the previous calls
✦We will probably need a few additional API’s later
including one for categories
© Codename One 2017 all rights reserved
@Controller
@RequestMapping("/updateRestaurant")
public class UpdateRestaurantService {
@Autowired
private RestaurantRepository restRepository;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String update(@RequestParam(name="logo", required = false) MultipartFile logo,
@RequestParam(name="icon", required = false) MultipartFile icon,
@RequestParam(name="backgroundImage", required = false) MultipartFile backgroundImage,
@RequestParam(name="secret", required = true) String secret) throws IOException {
RestaurantEntity e = restRepository.findBySecret(secret);
if(icon != null) {
e.setIcon(icon.getBytes());
}
if(logo != null) {
e.setLogo(logo.getBytes());
}
if(backgroundImage != null) {
e.setBackgroundImage(backgroundImage.getBytes());
}
restRepository.save(e);
return e.getSecret();
}
UpdateRestaurantService
@RequestMapping(method = RequestMethod.PUT)
public @ResponseBody String update(@RequestBody(required = true) RestaurantRequest data) throws
IOException {
RestaurantEntity e;
if(data.getId() == null) {
e = new RestaurantEntity();
} else {
e = restRepository.findBySecret(data.getId());
}
e.setMerchantId(data.getMerchantId());
e.setPrivateKey(data.getPrivateKey());
e.setPublicKey(data.getPublicKey());
e.setName(data.getName());
e.setRestaurantEmail(data.getRestaurantEmail());
e.setTagline(data.getTagline());
restRepository.save(e);
String sec = e.getSecret();
return sec;
}
}
UpdateRestaurantService
@Controller
@RequestMapping("/doBuildApp")
public class BuildAppService {
@Autowired
private BuildAppAsync buildAsync;
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String build(
@RequestParam(name = "secret", required = true) String secret,
@RequestParam(name = "pushKey", required = false) String pushKey,
@RequestParam(name = "targetType", required = true) String targetType) {
buildAsync.buildApp(secret, pushKey, targetType);
return "OK";
}
}
BuildAppService
@SpringBootApplication
@EnableAsync
public class AppBackendServerApplication extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(AppBackendServerApplication.class, args);
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("AppBuilder-");
executor.initialize();
return executor;
}
}
AppBackendServerApplication
@Service
public class BuildAppAsync {
@Autowired
private RestaurantRepository restRepository;
@Async
public void buildApp(String secret, String pushKey, String targetType) {
try {
RestaurantEntity re = restRepository.findBySecret(secret);
if(re == null) {
return;
}
File tempDirectory = File.createTempFile("tempDir", "ending");
tempDirectory.delete();
tempDirectory.mkdirs();
unzip(getClass().getResourceAsStream("/MyRestaurant.zip"), tempDirectory);
String uuid = UUID.randomUUID().toString();
FileResponseService.FILES_DIRECTORY.mkdirs();
File tempFileName = new File(FileResponseService.FILES_DIRECTORY, uuid + ".zip");
zipDir(tempFileName.getAbsolutePath(), tempDirectory.getAbsolutePath());
} catch(IOException err) {
throw new RuntimeException(err);
}
BuildAppAsync
spring.http.multipart.max-file-size=800KB
spring.http.multipart.max-request-size=2048KB
application.properties
@Controller @RequestMapping("/files")
public class FileResponseService {
public static final File FILES_DIRECTORY=new File(System.getProperty("user.home")+File.separator
+"files");
@RequestMapping(value = "/{file_name}", method = RequestMethod.GET)
public void getFile(@PathVariable("file_name") String fileName,
HttpServletResponse response) throws IOException {
for(int iter = 0 ; iter < fileName.length() ; iter++) {
char c = fileName.charAt(iter);
if(c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '.' || c == '-' || c == '_') {
continue;
}
// illegal character that might compromise security
response.setStatus(404);
return;
}
File f = new File(FILES_DIRECTORY, fileName +".zip");
if(f.exists()) {
response.setStatus(200);
try(OutputStream os = response.getOutputStream()) {
Files.copy(f.toPath(), os);
}
} else {
response.setStatus(404);
}
}
}
FileResponseService
Problematic URL
https://server.com/../../../etc/passwd

Weitere ähnliche Inhalte

Ähnlich wie App Maker Server - Part 2.pdf

Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 

Ähnlich wie App Maker Server - Part 2.pdf (20)

Microservices - Components
Microservices - ComponentsMicroservices - Components
Microservices - Components
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Quick Fetch API Introduction
Quick Fetch API IntroductionQuick Fetch API Introduction
Quick Fetch API Introduction
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Angular JS2 Training Session #3
Angular JS2 Training Session #3Angular JS2 Training Session #3
Angular JS2 Training Session #3
 
AWS re:Invent 2016: Chalice: A Serverless Microframework for Python (DEV308)
AWS re:Invent 2016: Chalice: A Serverless Microframework for Python (DEV308)AWS re:Invent 2016: Chalice: A Serverless Microframework for Python (DEV308)
AWS re:Invent 2016: Chalice: A Serverless Microframework for Python (DEV308)
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
Creating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdfCreating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdf
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
How To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native AppHow To Manage API Request with AXIOS on a React Native App
How To Manage API Request with AXIOS on a React Native App
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New Features
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networking
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
 
Cloud native programming model comparison
Cloud native programming model comparisonCloud native programming model comparison
Cloud native programming model comparison
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 

Mehr von ShaiAlmog1

Mehr von ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

App Maker Server - Part 2.pdf

  • 1. App Maker Server - Part II
  • 2. REST API ✦The API will consist of multiple stages to construct the restaurant in the cloud ✦We will upload the various pieces of the restaurant (images, dishes etc.) then request a build © Codename One 2017 all rights reserved
  • 3. API calls ✦/updateRestaurant - will either update or create a restaurant entry in the database, returns the secret ✦/dish - allows updating/adding/deleting a dish ✦/files - fetches a result file from the build ✦/doBuildApp - actually builds the app based on the values set in the previous calls ✦We will probably need a few additional API’s later including one for categories © Codename One 2017 all rights reserved
  • 4. @Controller @RequestMapping("/updateRestaurant") public class UpdateRestaurantService { @Autowired private RestaurantRepository restRepository; @RequestMapping(method = RequestMethod.POST) public @ResponseBody String update(@RequestParam(name="logo", required = false) MultipartFile logo, @RequestParam(name="icon", required = false) MultipartFile icon, @RequestParam(name="backgroundImage", required = false) MultipartFile backgroundImage, @RequestParam(name="secret", required = true) String secret) throws IOException { RestaurantEntity e = restRepository.findBySecret(secret); if(icon != null) { e.setIcon(icon.getBytes()); } if(logo != null) { e.setLogo(logo.getBytes()); } if(backgroundImage != null) { e.setBackgroundImage(backgroundImage.getBytes()); } restRepository.save(e); return e.getSecret(); } UpdateRestaurantService
  • 5. @RequestMapping(method = RequestMethod.PUT) public @ResponseBody String update(@RequestBody(required = true) RestaurantRequest data) throws IOException { RestaurantEntity e; if(data.getId() == null) { e = new RestaurantEntity(); } else { e = restRepository.findBySecret(data.getId()); } e.setMerchantId(data.getMerchantId()); e.setPrivateKey(data.getPrivateKey()); e.setPublicKey(data.getPublicKey()); e.setName(data.getName()); e.setRestaurantEmail(data.getRestaurantEmail()); e.setTagline(data.getTagline()); restRepository.save(e); String sec = e.getSecret(); return sec; } } UpdateRestaurantService
  • 6. @Controller @RequestMapping("/doBuildApp") public class BuildAppService { @Autowired private BuildAppAsync buildAsync; @RequestMapping(method = RequestMethod.POST) public @ResponseBody String build( @RequestParam(name = "secret", required = true) String secret, @RequestParam(name = "pushKey", required = false) String pushKey, @RequestParam(name = "targetType", required = true) String targetType) { buildAsync.buildApp(secret, pushKey, targetType); return "OK"; } } BuildAppService
  • 7. @SpringBootApplication @EnableAsync public class AppBackendServerApplication extends AsyncConfigurerSupport { public static void main(String[] args) { SpringApplication.run(AppBackendServerApplication.class, args); } @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(1); executor.setQueueCapacity(10); executor.setThreadNamePrefix("AppBuilder-"); executor.initialize(); return executor; } } AppBackendServerApplication
  • 8. @Service public class BuildAppAsync { @Autowired private RestaurantRepository restRepository; @Async public void buildApp(String secret, String pushKey, String targetType) { try { RestaurantEntity re = restRepository.findBySecret(secret); if(re == null) { return; } File tempDirectory = File.createTempFile("tempDir", "ending"); tempDirectory.delete(); tempDirectory.mkdirs(); unzip(getClass().getResourceAsStream("/MyRestaurant.zip"), tempDirectory); String uuid = UUID.randomUUID().toString(); FileResponseService.FILES_DIRECTORY.mkdirs(); File tempFileName = new File(FileResponseService.FILES_DIRECTORY, uuid + ".zip"); zipDir(tempFileName.getAbsolutePath(), tempDirectory.getAbsolutePath()); } catch(IOException err) { throw new RuntimeException(err); } BuildAppAsync
  • 10. @Controller @RequestMapping("/files") public class FileResponseService { public static final File FILES_DIRECTORY=new File(System.getProperty("user.home")+File.separator +"files"); @RequestMapping(value = "/{file_name}", method = RequestMethod.GET) public void getFile(@PathVariable("file_name") String fileName, HttpServletResponse response) throws IOException { for(int iter = 0 ; iter < fileName.length() ; iter++) { char c = fileName.charAt(iter); if(c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '.' || c == '-' || c == '_') { continue; } // illegal character that might compromise security response.setStatus(404); return; } File f = new File(FILES_DIRECTORY, fileName +".zip"); if(f.exists()) { response.setStatus(200); try(OutputStream os = response.getOutputStream()) { Files.copy(f.toPath(), os); } } else { response.setStatus(404); } } } FileResponseService Problematic URL https://server.com/../../../etc/passwd