Skip to content
This repository was archived by the owner on Jun 8, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ch.swaechter.angularjuniversal.data;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.InputStream;

/**
Expand All @@ -14,6 +17,7 @@ public class DataLoader {
*
* @return Input stream of the index template
*/
@Nullable
public InputStream getIndexAsInputStream() {
return this.getClass().getResourceAsStream("/public/index.html");
}
Expand All @@ -23,6 +27,7 @@ public InputStream getIndexAsInputStream() {
*
* @return Input stream of the server bundle
*/
@Nullable
public InputStream getServerBundleAsInputStream() {
return this.getClass().getResourceAsStream("/server.js");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.swaechter.angularjuniversal.keywords;

import org.jetbrains.annotations.NotNull;

/**
* This class is responsible for representing a keyword with a name.
*
Expand All @@ -10,17 +12,21 @@ public class Keyword {
/**
* ID of the keyword.
*/
@NotNull
private Integer id;

/**
* Name of the keyword.
*/
@NotNull
private String name;

/**
* Default constructor.
*/
public Keyword() {
this.id = (int) Math.round(Math.random() * Integer.MAX_VALUE);
this.name = "";
}

/**
Expand All @@ -29,7 +35,7 @@ public Keyword() {
* @param id ID of the keyword
* @param name Name of the keyword
*/
public Keyword(Integer id, String name) {
public Keyword(@NotNull Integer id, @NotNull String name) {
this.id = id;
this.name = name;
}
Expand All @@ -39,6 +45,7 @@ public Keyword(Integer id, String name) {
*
* @return ID of the keyword
*/
@NotNull
public Integer getId() {
return id;
}
Expand All @@ -48,8 +55,7 @@ public Integer getId() {
*
* @param id New ID of the keyword
*/

public void setId(Integer id) {
public void setId(@NotNull Integer id) {
this.id = id;
}

Expand All @@ -58,6 +64,7 @@ public void setId(Integer id) {
*
* @return Name of the keyword
*/
@NotNull
public String getName() {
return name;
}
Expand All @@ -67,7 +74,7 @@ public String getName() {
*
* @param name New name of the keyword
*/
public void setName(String name) {
public void setName(@NotNull String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.swaechter.angularjuniversal.keywords;

import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
Expand All @@ -11,6 +13,7 @@
*/
public class KeywordService {

@NotNull
private final List<Keyword> keywords;

public KeywordService() {
Expand All @@ -25,6 +28,7 @@ public KeywordService() {
*
* @return All keywords as list
*/
@NotNull
public List<Keyword> getKeywords() {
return keywords;
}
Expand All @@ -35,6 +39,7 @@ public List<Keyword> getKeywords() {
* @param id ID of the keyword
* @return Optional keyword
*/
@NotNull
public Optional<Keyword> getKeyword(int id) {
if (id >= 0 && id < keywords.size()) {
return Optional.of(keywords.get(id));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import ch.swaechter.angularjuniversal.renderer.engine.RenderEngineFactory;
import ch.swaechter.angularjuniversal.renderer.utils.RenderUtils;
import ch.swaechter.angularjuniversal.tcprenderer.TcpRenderEngineFactory;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
Expand All @@ -32,33 +33,38 @@ public static void main(String[] args) {
@RestController
public class ContentController {

@NotNull
private final RenderService renderService;

@Autowired
public ContentController(RenderService renderService) {
public ContentController(@NotNull RenderService renderService) {
this.renderService = renderService;
}

@ResponseBody
@GetMapping({"/", "/home"})
@NotNull
public String showHome() throws Exception {
return renderService.renderPage("/home").get();
}

@ResponseBody
@GetMapping("/keywords")
@NotNull
public String showLogin() throws Exception {
return renderService.renderPage("/keywords").get();
}

@ResponseBody
@GetMapping("/keywords/{id}")
@NotNull
public String showLogout(@PathVariable("id") int id) throws Exception {
return renderService.renderPage("/keywords/" + id).get();
}

@ResponseBody
@GetMapping("/about")
@NotNull
public String showPage() throws Exception {
return renderService.renderPage("/about").get();
}
Expand All @@ -68,13 +74,15 @@ public String showPage() throws Exception {
@RequestMapping("/api")
public class KeywordController {

@NotNull
private final KeywordService keywordService;

public KeywordController() {
this.keywordService = new KeywordService();
}

@GetMapping("/keyword")
@NotNull
public ResponseEntity<List<Keyword>> getKeywords() {
return new ResponseEntity<>(keywordService.getKeywords(), HttpStatus.OK);
}
Expand All @@ -83,8 +91,10 @@ public ResponseEntity<List<Keyword>> getKeywords() {
@Service
public class RenderService {

@NotNull
private final Renderer renderer;

@NotNull
public RenderService() throws IOException {
// Load the template and create a temporary server bundle file from the resource (This file will of course never change until manually edited)
InputStream templateInputStream = getClass().getResourceAsStream("/public/index.html");
Expand All @@ -105,7 +115,8 @@ public RenderService() throws IOException {
this.renderer.startRenderer();
}

Future<String> renderPage(String uri) {
@NotNull
Future<String> renderPage(@NotNull String uri) {
// Render a request and return a resolvable future
return renderer.addRenderRequest(uri);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch.swaechter.angularjuniversal.example.springboot.configuration;

import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
Expand All @@ -8,7 +9,7 @@
public class ApplicationConfiguration implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
public void addCorsMappings(@NotNull CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ch.swaechter.angularjuniversal.keywords.Keyword;
import ch.swaechter.angularjuniversal.keywords.KeywordService;
import org.jetbrains.annotations.NotNull;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -19,6 +20,7 @@
@RequestMapping("/api")
public class KeywordController {

@NotNull
private final KeywordService keywordService;

/**
Expand All @@ -34,6 +36,7 @@ public KeywordController() {
* @return All keywords
*/
@GetMapping("/keyword")
@NotNull
public ResponseEntity<List<Keyword>> getKeywords() {
return new ResponseEntity<>(keywordService.getKeywords(), HttpStatus.OK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import ch.swaechter.angularjuniversal.renderer.configuration.RenderConfiguration;
import ch.swaechter.angularjuniversal.renderer.engine.RenderEngine;
import ch.swaechter.angularjuniversal.renderer.exception.RenderException;
import ch.swaechter.angularjuniversal.renderer.request.RenderRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.BufferedReader;
import java.io.InputStreamReader;
Expand All @@ -23,18 +26,19 @@ public class TcpRenderEngine implements RenderEngine {
/**
* Name of the environment variable passed to Node.js to indicate the port.
*/
@NotNull
private static final String NODE_PORT_ENVIRONMENT_VARIABLE_NAME = "NODEPORT";

/**
* Object mapper used to serialize/deserialize TCP request and responses.
*/
private final ObjectMapper objectMapper;
@NotNull
private final ObjectMapper objectMapper = new ObjectMapper();

/**
* Create a new TCP based render engine that will access a NodeJS server for rendering
*/
public TcpRenderEngine() {
this.objectMapper = new ObjectMapper();
}

/**
Expand All @@ -45,36 +49,62 @@ public TcpRenderEngine() {
* @param renderConfiguration Render configuration with the all required information
*/
@Override
public void startWorking(BlockingQueue<Optional<RenderRequest>> renderRequests, RenderConfiguration renderConfiguration) {
public void startWorking(@NotNull BlockingQueue<Optional<RenderRequest>> renderRequests, @NotNull RenderConfiguration renderConfiguration) {
try {
// Start the Node.js render service
@NotNull
ProcessBuilder processBuilder = new ProcessBuilder(renderConfiguration.getNodePath(), renderConfiguration.getServerBundleFile().getAbsolutePath());
@NotNull
Map<String, String> processEnvironment = processBuilder.environment();
processEnvironment.put(NODE_PORT_ENVIRONMENT_VARIABLE_NAME, String.valueOf(renderConfiguration.getNodePort()));

@NotNull
Process process = processBuilder.start();

while (true) {
Optional<RenderRequest> renderRequestItem = renderRequests.take();

if (renderRequestItem.isPresent()) {
try {
// Get the render request item
RenderRequest renderRequest = renderRequestItem.get();
// Get the render request item
@NotNull
RenderRequest renderRequest = renderRequestItem.get();

try {
// Create the socket and initialize the writer reader
@NotNull
Socket socket = new Socket("localhost", renderConfiguration.getNodePort());
@NotNull
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
@NotNull
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

// Write the request
TcpRequest tcpRequest = new TcpRequest(renderRequest.getUuid(), renderRequest.getUri(), renderConfiguration.getTemplateContent());
@NotNull
TcpRequest tcpRequest = new TcpRequest(renderRequest.getId(), renderRequest.getUri(), renderConfiguration.getTemplateContent());
writer.println(objectMapper.writeValueAsString(tcpRequest));
writer.flush();

// Read the response
@NotNull
TcpResponse tcpResponse = objectMapper.readValue(reader, TcpResponse.class);
renderRequest.getFuture().complete(tcpResponse.getHtml());
} catch (Exception exception) {

// Get the error message if an error occurred on the render server
@Nullable
String errorMessage = tcpResponse.getError();

// check if an error occurred
if (errorMessage == null) {
renderRequest.getFuture().complete(tcpResponse.getHtml());
} else {
throw new RenderException(errorMessage);
}
} catch (Throwable exception) {
exception.printStackTrace();
if (exception instanceof RenderException) {
renderRequest.getFuture().completeExceptionally(exception);
} else {
renderRequest.getFuture().completeExceptionally(new RenderException(exception));
}
}
} else {
process.destroy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ch.swaechter.angularjuniversal.renderer.engine.RenderEngine;
import ch.swaechter.angularjuniversal.renderer.engine.RenderEngineFactory;
import org.jetbrains.annotations.NotNull;

/**
* Provide a TCP render engine factory which is able to create new TCP render engines.
Expand All @@ -16,6 +17,7 @@ public class TcpRenderEngineFactory implements RenderEngineFactory {
* @return New TCP render engine
*/
@Override
@NotNull
public RenderEngine createRenderEngine() {
return new TcpRenderEngine();
}
Expand Down
Loading