ECE366 - Lesson 12

More Testing and Hosting on the Cloud

Instructor: Professor Hong

Review & Questions

## More Testing
## WebserviceController.java ```java package ece366.rpsjdbc.webservice; import ece366.rpsjdbc.DatabaseConnectionManager; import ece366.rpsjdbc.Player; import ece366.rpsjdbc.PlayerDAO; import org.springframework.web.bind.annotation.*; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import java.util.Map; @CrossOrigin @RestController @RequestMapping("/api") public class WebserviceController { private final PlayerDAO playerDAO; private final boolean isTestMode; // Constructor for dependency injection (used in tests) public WebserviceController(PlayerDAO playerDAO) { this.playerDAO = playerDAO; this.isTestMode = true; // Indicates that this is a test instance } // Default constructor (used in production) public WebserviceController() { this.isTestMode = false; this.playerDAO = null; // Will be initialized dynamically in production } @GetMapping("/testPlayer") public String getTestPlayer() { return "TEST PLAYER"; } @GetMapping("/player/{id}") public Player getPlayerById(@PathVariable Long id) { System.out.println("getPlayerById: " + id); try { // Use injected PlayerDAO in test mode, otherwise create it dynamically PlayerDAO dao = isTestMode ? playerDAO : createPlayerDAO(); Player player = dao.findById(id); System.out.println(player.toString()); return player; } catch (Exception e) { e.printStackTrace(); } return null; } // Factory method to create PlayerDAO in production private PlayerDAO createPlayerDAO() throws SQLException { DatabaseConnectionManager dcm = new DatabaseConnectionManager("db", "rps", "postgres", "password"); Connection connection = dcm.getConnection(); return new PlayerDAO(connection); } } ```
## WebserviceControllerTest .java ```java package ece366.rpsjdbc.webservice; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import ece366.rpsjdbc.Player; import ece366.rpsjdbc.PlayerDAO; @ExtendWith(MockitoExtension.class) public class WebserviceControllerTest { @Mock private PlayerDAO playerDAO; // Mock the PlayerDAO private WebserviceController wc; // WebserviceController instance @BeforeEach public void setup() { // Manually inject the mock PlayerDAO into WebserviceController wc = new WebserviceController(playerDAO); } @Test void getTestPlayer() { assertEquals("TEST PLAYER", wc.getTestPlayer()); } @Test public void getPlayerByIdTest() { // Create a mock Player object Player mockPlayer = new Player(); mockPlayer.setPlayerId(1L); mockPlayer.setUserName("TestUser"); mockPlayer.setTotalWins(600); // Mock the behavior of PlayerDAO's findById method when(playerDAO.findById(1L)).thenReturn(mockPlayer); // Call the method under test Player p = wc.getPlayerById(1L); // Verify the result assertEquals(600, p.getTotalWins()); assertEquals("TestUser", p.getUserName()); assertEquals(1L, p.getPlayerId()); } } ```
## More Hosting on the Cloud
## docker-compose.yaml ``` services: db: image: ece366acr.azurecr.io/rpsdb:latest build: db environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password ports: - 5432:5432 restart: always app: image: ece366acr.azurecr.io/rpsapp:latest build: server/rpsjdbc environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password depends_on: - db ports: - 8080:8080 ui: image: ece366acr.azurecr.io/rpsui:latest build: rpsui depends_on: - app ports: - 80:80 ```
## deploy-aci.yaml ``` apiVersion: 2019-12-01 location: eastus name: rpsContainerGroup properties: containers: - name: db properties: image: ece366acr.azurecr.io/rpsdb:latest environmentVariables: - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD value: password resources: requests: cpu: 1 memoryInGb: 1.5 ports: - port: 5432 - name: app properties: image: ece366acr.azurecr.io/rpsapp:latest resources: requests: cpu: 1 memoryInGb: 1.5 ports: - port: 8080 - name: ui properties: image: ece366acr.azurecr.io/rpsui:latest resources: requests: cpu: 1 memoryInGb: 1.5 ports: - port: 80 osType: Linux ipAddress: type: Public dnsNameLabel: moosetracks # Add your desired DNS name label here ports: - protocol: tcp port: 5432 - protocol: tcp port: 8080 - protocol: tcp port: 80 imageRegistryCredentials: - server: ece366acr.azurecr.io username: 00000000-0000-0000-0000-000000000000 password: your token tags: {exampleTag: tutorial} type: Microsoft.ContainerInstance/containerGroups ```
## webservice/Webconfig.java ```java package ece366.rpsjdbc.webservice; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // Apply CORS to all endpoints .allowedOrigins("http://moosetracks.eastus.azurecontainer.io") // Allow requests from your frontend .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // Allow specific HTTP methods .allowedHeaders("*") // Allow all headers, including Authorization .allowCredentials(true); // Allow cookies or Authorization headers } } ```
## webservice/WebserviceController.java ``` package ece366.rpsjdbc.webservice; import ece366.rpsjdbc.DatabaseConnectionManager; import ece366.rpsjdbc.Player; import ece366.rpsjdbc.PlayerDAO; import org.springframework.web.bind.annotation.*; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import java.util.Map; @CrossOrigin(origins = {"http://moosetracks.eastus.azurecontainer.io"}) @RestController @RequestMapping("/api") public class WebserviceController { private final PlayerDAO playerDAO; private final boolean isTestMode; // Constructor for dependency injection (used in tests) public WebserviceController(PlayerDAO playerDAO) { this.playerDAO = playerDAO; this.isTestMode = true; // Indicates that this is a test instance } // Default constructor (used in production) public WebserviceController() { this.isTestMode = false; this.playerDAO = null; // Will be initialized dynamically in production } @GetMapping("/testPlayer") public String getTestPlayer() { return "TEST PLAYER"; } @GetMapping("/player/{id}") public Player getPlayerById(@PathVariable Long id) { System.out.println("getPlayerById: " + id); try { // Use injected PlayerDAO in test mode, otherwise create it dynamically PlayerDAO dao = isTestMode ? playerDAO : createPlayerDAO(); Player player = dao.findById(id); System.out.println(player.toString()); return player; } catch (Exception e) { e.printStackTrace(); } return null; } // Factory method to create PlayerDAO in production private PlayerDAO createPlayerDAO() throws SQLException { DatabaseConnectionManager dcm = new DatabaseConnectionManager("localhost", "rps", "postgres", "password"); Connection connection = dcm.getConnection(); return new PlayerDAO(connection); } } ```
## Azure Review ``` az login az acr login --name ece366acr az acr login --name ece366acr --expose-token docker compose build docker compose push az container create --resource-group ece366rg --file deploy-aci.yaml ```