Azure deployment setup #297

Closed
RecentRunner wants to merge 429 commits from azure-deploy into main
8 changed files with 286 additions and 11 deletions
Showing only changes of commit b2f291f256 - Show all commits

View File

@@ -9,6 +9,8 @@ public class PetRequest {
private Integer petAge;
private String petStatus;
private BigDecimal petPrice;
private Long customerId;
private Long storeId;
public PetRequest() {
}
@@ -60,4 +62,20 @@ public class PetRequest {
public void setPetPrice(BigDecimal petPrice) {
this.petPrice = petPrice;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public Long getStoreId() {
return storeId;
}
public void setStoreId(Long storeId) {
this.storeId = storeId;
}
}

View File

@@ -14,6 +14,10 @@ public class PetResponse {
private String imageUrl;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private Long customerId;
private String customerName;
private Long storeId;
private String storeName;
public PetResponse() {
}
@@ -97,4 +101,36 @@ public class PetResponse {
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public Long getStoreId() {
return storeId;
}
public void setStoreId(Long storeId) {
this.storeId = storeId;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
}

View File

@@ -24,7 +24,7 @@ public class PetApi {
return INSTANCE;
}
public List<PetResponse> listPets(String query, String species, String status) throws Exception {
public List<PetResponse> listPets(String query, String species, String status, Long storeId) throws Exception {
String path = "/api/v1/pets?page=0&size=1000";
if (query != null && !query.isEmpty()) {
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
@@ -35,6 +35,9 @@ public class PetApi {
if (status != null && !status.isEmpty()) {
path += "&status=" + URLEncoder.encode(status, StandardCharsets.UTF_8);
}
if (storeId != null) {
path += "&storeId=" + storeId;
}
String response = apiClient.getRawResponse(path);
PageResponse<PetResponse> pageResponse = apiClient.getObjectMapper().readValue(
response,
@@ -46,8 +49,12 @@ public class PetApi {
return pageResponse.getContent();
}
public List<PetResponse> listPets(String query, String species, String status) throws Exception {
return listPets(query, species, status, null);
}
public List<PetResponse> listPets(String query) throws Exception {
return listPets(query, null, null);
return listPets(query, null, null, null);
}
public PetResponse createPet(PetRequest request) throws Exception {

View File

@@ -63,6 +63,12 @@ public class PetController {
@FXML
private TableColumn<Pet, String> colPetStatus;
@FXML
private TableColumn<Pet, String> colCustomerName;
@FXML
private TableColumn<Pet, String> colStoreName;
@FXML
private TableView<Pet> tvPets;
@@ -156,11 +162,13 @@ public class PetController {
colPetAge.setCellValueFactory(new PropertyValueFactory<Pet,Integer>("petAge"));
colPetStatus.setCellValueFactory(new PropertyValueFactory<Pet,String>("petStatus"));
colPetPrice.setCellValueFactory(new PropertyValueFactory<Pet,Double>("petPrice"));
colCustomerName.setCellValueFactory(new PropertyValueFactory<Pet,String>("customerName"));
colStoreName.setCellValueFactory(new PropertyValueFactory<Pet,String>("storeName"));
configureImageColumn(colPetImage);
loadSpeciesFilter();
cbStatusFilter.setItems(FXCollections.observableArrayList("All Statuses", "Available", "Adopted", "Pending"));
cbStatusFilter.setItems(FXCollections.observableArrayList("All Statuses", "Available", "Adopted", "Owned", "Pending"));
cbStatusFilter.getSelectionModel().selectFirst();
displayPets();
@@ -316,7 +324,7 @@ public class PetController {
}
private Pet mapToPet(PetResponse response) {
return new Pet(
Pet pet = new Pet(
response.getPetId().intValue(),
response.getPetName(),
response.getPetSpecies(),
@@ -326,6 +334,11 @@ public class PetController {
response.getPetPrice().doubleValue(),
response.getImageUrl()
);
pet.setCustomerName(response.getCustomerName());
pet.setStoreName(response.getStoreName());
pet.setCustomerId(response.getCustomerId() != null ? response.getCustomerId() : 0L);
pet.setStoreId(response.getStoreId() != null ? response.getStoreId() : 0L);
return pet;
}
private void configureImageColumn(TableColumn<Pet, String> column) {

View File

@@ -1,5 +1,6 @@
package org.example.petshopdesktop.controllers.dialogcontrollers;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
@@ -10,8 +11,10 @@ import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.common.DropdownOption;
import org.example.petshopdesktop.api.dto.pet.PetRequest;
import org.example.petshopdesktop.api.dto.pet.PetResponse;
import org.example.petshopdesktop.api.endpoints.DropdownApi;
import org.example.petshopdesktop.api.endpoints.PetApi;
import org.example.petshopdesktop.models.Pet;
import org.example.petshopdesktop.util.ActivityLogger;
@@ -20,6 +23,7 @@ import org.example.petshopdesktop.util.FilePickerSupport;
import java.io.File;
import java.math.BigDecimal;
import java.util.List;
public class PetDialogController {
@@ -38,6 +42,12 @@ public class PetDialogController {
@FXML
private ComboBox<String> cbPetStatus;
@FXML
private ComboBox<DropdownOption> cbCustomer;
@FXML
private ComboBox<DropdownOption> cbStore;
@FXML
private Label lblMode;
@@ -70,16 +80,54 @@ public class PetDialogController {
private String currentImageUrl;
private boolean removeImageRequested;
private Long pendingCustomerId = null;
private Long pendingStoreId = null;
private ObservableList<String> statusList = FXCollections.observableArrayList(
"Available", "Adopted"
"Available", "Adopted", "Owned"
);
@FXML
void initialize() {
cbPetStatus.setItems(statusList); //set status combobox
cbPetStatus.setItems(statusList);
cbCustomer.setCellFactory(param -> new ListCell<>() {
@Override protected void updateItem(DropdownOption o, boolean empty) {
super.updateItem(o, empty);
setText(empty || o == null ? null : o.getLabel());
}
});
cbCustomer.setButtonCell(new ListCell<>() {
@Override protected void updateItem(DropdownOption o, boolean empty) {
super.updateItem(o, empty);
setText(empty || o == null ? null : o.getLabel());
}
});
cbStore.setCellFactory(param -> new ListCell<>() {
@Override protected void updateItem(DropdownOption o, boolean empty) {
super.updateItem(o, empty);
setText(empty || o == null ? null : o.getLabel());
}
});
cbStore.setButtonCell(new ListCell<>() {
@Override protected void updateItem(DropdownOption o, boolean empty) {
super.updateItem(o, empty);
setText(empty || o == null ? null : o.getLabel());
}
});
cbCustomer.setVisible(false);
cbStore.setVisible(false);
cbPetStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
boolean isOwned = "Owned".equalsIgnoreCase(newVal);
boolean isAvailable = "Available".equalsIgnoreCase(newVal) || "Unadopted".equalsIgnoreCase(newVal);
cbCustomer.setVisible(isOwned);
cbStore.setVisible(isAvailable);
});
//Set up mouse handlers for buttons
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
@@ -97,6 +145,9 @@ public class PetDialogController {
btnChangeImage.setOnMouseClicked(mouseEvent -> handleChangeImage());
btnRemoveImage.setOnMouseClicked(mouseEvent -> handleRemoveImage());
refreshImagePreview();
loadCustomers();
loadStores();
}
private void buttonSaveClicked(MouseEvent mouseEvent) {
@@ -111,6 +162,10 @@ public class PetDialogController {
if (cbPetStatus.getSelectionModel().getSelectedItem() == null){
errorMsg += "Status is required";
}
String selectedStatus = cbPetStatus.getValue();
if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) {
errorMsg += "Customer is required for Owned status\n";
}
//Check validation (length size)
errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50);
@@ -184,9 +239,81 @@ public class PetDialogController {
}
request.setPetAge(age);
String status = cbPetStatus.getValue();
if ("Owned".equalsIgnoreCase(status) && cbCustomer.getValue() != null) {
request.setCustomerId(cbCustomer.getValue().getId());
}
if (("Available".equalsIgnoreCase(status) || "Unadopted".equalsIgnoreCase(status)) && cbStore.getValue() != null) {
request.setStoreId(cbStore.getValue().getId());
}
return request;
}
private void loadCustomers() {
new Thread(() -> {
try {
List<DropdownOption> customers = DropdownApi.getInstance().getCustomers();
Platform.runLater(() -> {
cbCustomer.setItems(FXCollections.observableArrayList(customers));
applySelectedCustomer();
});
} catch (Exception e) {
Platform.runLater(() -> {
ActivityLogger.getInstance().logException(
"PetDialogController.loadCustomers", e, "Loading customers");
cbCustomer.setDisable(true);
cbCustomer.setPromptText("Unable to load customers");
});
}
}).start();
}
private void loadStores() {
new Thread(() -> {
try {
List<DropdownOption> stores = DropdownApi.getInstance().getStores();
Platform.runLater(() -> {
cbStore.setItems(FXCollections.observableArrayList(stores));
applySelectedStore();
});
} catch (Exception e) {
Platform.runLater(() -> {
ActivityLogger.getInstance().logException(
"PetDialogController.loadStores", e, "Loading stores");
cbStore.setDisable(true);
cbStore.setPromptText("Unable to load stores");
});
}
}).start();
}
private void applySelectedCustomer() {
if (pendingCustomerId == null) return;
DropdownOption selected = findOptionById(cbCustomer.getItems(), pendingCustomerId);
if (selected != null) {
cbCustomer.setValue(selected);
pendingCustomerId = null;
}
}
private void applySelectedStore() {
if (pendingStoreId == null) return;
DropdownOption selected = findOptionById(cbStore.getItems(), pendingStoreId);
if (selected != null) {
cbStore.setValue(selected);
pendingStoreId = null;
}
}
private DropdownOption findOptionById(List<DropdownOption> options, Long id) {
if (id == null || options == null) return null;
for (DropdownOption option : options) {
if (option.getId() != null && option.getId().equals(id)) return option;
}
return null;
}
private void closeStage(MouseEvent mouseEvent) {
Node node = (Node) mouseEvent.getSource();
Stage stage = (Stage) node.getScene().getWindow();
@@ -206,14 +333,14 @@ public class PetDialogController {
removeImageRequested = false;
refreshImagePreview();
//get the right combobox selection
pendingCustomerId = pet.getCustomerId() > 0 ? pet.getCustomerId() : null;
pendingStoreId = pet.getStoreId() > 0 ? pet.getStoreId() : null;
for (String status : cbPetStatus.getItems()) {
if(status.equals(pet.getPetStatus())){
cbPetStatus.getSelectionModel().select(status);
}
}
}
}

View File

@@ -13,6 +13,10 @@ public class Pet {
private SimpleStringProperty petStatus;
private SimpleDoubleProperty petPrice;
private SimpleStringProperty imageUrl;
private SimpleStringProperty customerName = new SimpleStringProperty("");
private SimpleStringProperty storeName = new SimpleStringProperty("");
private long customerId = 0L;
private long storeId = 0L;
public Pet(int petId, String petName, String petSpecies, String petBreed, int petAge, String petStatus, double petPrice, String imageUrl) {
this.petId = new SimpleIntegerProperty(petId);
@@ -120,4 +124,44 @@ public class Pet {
public SimpleStringProperty imageUrlProperty() {
return imageUrl;
}
public String getCustomerName() {
return customerName.get();
}
public void setCustomerName(String customerName) {
this.customerName.set(customerName != null ? customerName : "");
}
public SimpleStringProperty customerNameProperty() {
return customerName;
}
public String getStoreName() {
return storeName.get();
}
public void setStoreName(String storeName) {
this.storeName.set(storeName != null ? storeName : "");
}
public SimpleStringProperty storeNameProperty() {
return storeName;
}
public long getCustomerId() {
return customerId;
}
public void setCustomerId(long customerId) {
this.customerId = customerId;
}
public long getStoreId() {
return storeId;
}
public void setStoreId(long storeId) {
this.storeId = storeId;
}
}

View File

@@ -13,7 +13,7 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="660.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
<children>
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
<children>
@@ -153,6 +153,34 @@
</TextField>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="3">
<children>
<Label text="Customer:" textFill="#2c3e50">
<font>
<Font name="System Bold" size="16.0" />
</font>
</Label>
<ComboBox fx:id="cbCustomer" prefHeight="29.0" prefWidth="336.0" promptText="Select Customer" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
<padding>
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
</padding>
</ComboBox>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<children>
<Label text="Store:" textFill="#2c3e50">
<font>
<Font name="System Bold" size="16.0" />
</font>
</Label>
<ComboBox fx:id="cbStore" prefHeight="29.0" prefWidth="336.0" promptText="Select Store" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
<padding>
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
</padding>
</ComboBox>
</children>
</VBox>
</children>
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />

View File

@@ -79,6 +79,8 @@
<TableColumn fx:id="colPetAge" prefWidth="60.0" text="Age" />
<TableColumn fx:id="colPetStatus" prefWidth="110.0" text="Status" />
<TableColumn fx:id="colPetPrice" prefWidth="80.0" text="Price" />
<TableColumn fx:id="colCustomerName" prefWidth="130.0" text="Owner" />
<TableColumn fx:id="colStoreName" prefWidth="130.0" text="Store" />
</columns>
</TableView>
</children>