Compare commits

..

No commits in common. "d4b830096f8c013d1bf4df810abcc1e40225570a" and "21a6a22a9e3d8f0731be468d3b6ac59c9536b9a0" have entirely different histories.

21 changed files with 95 additions and 378 deletions

View File

@ -1,69 +0,0 @@
# dotnet build environment
FROM alpine:latest as dotnet
WORKDIR /
RUN apk add dotnet8-sdk git
RUN git clone https://gitlab.com/kzotkin/hiveemulator
WORKDIR /hiveemulator/src/CommunicationControl/
RUN dotnet build DevOpsProject/DevOpsProject.CommunicationControl.API.csproj
RUN dotnet build DevOpsProject.HiveMind.API/DevOpsProject.HiveMind.API.csproj
# nodejs build environment
#FROM alpine:latest as nodejs
#WORKDIR /
#RUN apk add git npm
#RUN git clone https://gitlab.com/kzotkin/hiveemulator
#WORKDIR /hiveemulator/src/MapClient/
#RUN npm install
#RUN npm run build
# production environment
FROM alpine:latest
WORKDIR /
#RUN apk add dotnet8-sdk redis openrc lighttpd npm
#RUN apk add git dotnet8-sdk redis openrc npm
#RUN apk add git aspnetcore8-runtime redis openrc npm
RUN apk add aspnetcore8-runtime redis openrc npm
#RUN git clone https://gitlab.com/kzotkin/hiveemulator
#COPY --from=nodejs /hiveemulator/ /hiveemulator/
COPY --from=dotnet /hiveemulator/ /hiveemulator/
#COPY --from=nodejs /hiveemulator/src/MapClient/dist/* /var/www/localhost/htdocs/
#RUN mkdir /hive-cc
#COPY --from=0 /hiveemulator/src/CommunicationControl/DevOpsProject/* /hive-cc/
#COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject/* /hiveemulator/src/CommunicationControl/DevOpsProject/
#COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/* /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/
#RUN mkdir /hive-hm
#COPY --from=0 /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/* /hive-hm/
WORKDIR /hiveemulator/src/MapClient/
RUN npm install
RUN sed -i 's/localhost/10\.1\.1\.2/' public/config.json
WORKDIR /
COPY ./daemon-files/hive-cc /etc/init.d/hive-cc
COPY ./daemon-files/hive-hm /etc/init.d/hive-hm
COPY ./daemon-files/hive-map /etc/init.d/hive-map
RUN chmod u+x /etc/init.d/hive-hm /etc/init.d/hive-cc /etc/init.d/hive-map
#RUN mkdir /etc/rulevels/{stage-redis,stage-cc,stage-hm,stage-map}
#RUN rc-update add redis default
#RUN rc-update add hive-hm default
#RUN rc-update add hive-cc default
#RUN rc-update add hive-map default
CMD sh -c "openrc default ; \
rc-service redis start ; \
rc-service hive-cc start ; \
rc-service hive-hm start ; \
rc-service hive-map start ; \
exec sh"

View File

@ -1,24 +0,0 @@
# dotnet build environment
FROM alpine:latest as dotnet
WORKDIR /
RUN apk add git
RUN git clone https://gitlab.com/kzotkin/hiveemulator
RUN apk add dotnet8-sdk
WORKDIR /hiveemulator/src/CommunicationControl/
RUN dotnet publish DevOpsProject/DevOpsProject.CommunicationControl.API.csproj
# production environment
#FROM mcr.microsoft.com/dotnet/aspnet:8.0 as prod
FROM alpine:latest as prod
#COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Release/net8.0/ /app/
RUN apk add aspnetcore8-runtime
RUN mkdir -p /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Release/net8.0/
COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Release/net8.0/ /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Release/net8.0/
EXPOSE 8080
WORKDIR /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Release/net8.0/
ENTRYPOINT ["./DevOpsProject.CommunicationControl.API"]

View File

@ -1,23 +0,0 @@
# dotnet build environment
FROM alpine:latest as dotnet
WORKDIR /
RUN apk add git
RUN git clone https://gitlab.com/kzotkin/hiveemulator
RUN apk add dotnet8-sdk
WORKDIR /hiveemulator/src/CommunicationControl/
RUN dotnet publish DevOpsProject.HiveMind.API/DevOpsProject.HiveMind.API.csproj
# production environment
#FROM mcr.microsoft.com/dotnet/aspnet:8.0 as prod
FROM alpine:latest as prod
RUN apk add aspnetcore8-runtime
RUN mkdir -p /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Release/net8.0/
#COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Release/net8.0/ /app/
COPY --from=dotnet /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Release/net8.0/ /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Release/net8.0/
WORKDIR /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Release/net8.0/
ENTRYPOINT ["./DevOpsProject.HiveMind.API"]

View File

@ -1,22 +0,0 @@
# nodejs build environment
FROM alpine:latest as nodejs
WORKDIR /
RUN apk add git
RUN git clone https://gitlab.com/kzotkin/hiveemulator
RUN apk add npm
WORKDIR /hiveemulator/src/MapClient/
RUN npm install
RUN npm run build
RUN rm public/config.json
# production environment
FROM nginx:alpine
COPY --from=nodejs /hiveemulator/src/MapClient/dist/ /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]

View File

@ -1,14 +0,0 @@
#!/sbin/openrc-run
command="./DevOpsProject.CommunicationControl.API"
command_args=""
pidfile="/run/hive-cc.pid"
supervisor="supervise-daemon"
start_pre() {
cd /hiveemulator/src/CommunicationControl/DevOpsProject/bin/Debug/net8.0/
}
depend() {
need redis
}

View File

@ -1,14 +0,0 @@
#!/sbin/openrc-run
command="./DevOpsProject.HiveMind.API"
command_args=""
pidfile="/run/hive-hm.pid"
supervisor="supervise-daemon"
start_pre() {
cd /hiveemulator/src/CommunicationControl/DevOpsProject.HiveMind.API/bin/Debug/net8.0/
}
depend() {
need hive-cc
}

View File

@ -1,14 +0,0 @@
#!/sbin/openrc-run
command="npm"
command_args="run dev"
pidfile="/run/hive-map.pid"
supervisor="supervise-daemon"
depend() {
need hive-cc
}
start_pre() {
cd /hiveemulator/src/MapClient/
}

View File

@ -1,50 +0,0 @@
services:
redis:
image: redis:7
restart: always
networks:
- sys
cc:
build:
context: .
dockerfile: Dockerfile-cc
#image: registry.digitalocean.com/duke-listings/cc
restart: always
environment:
Redis__ConnectionString: "redis:6379"
ports:
- 8080:8080
networks:
- sys
depends_on:
- redis
hm:
build:
context: .
dockerfile: Dockerfile-hm
#image: registry.digitalocean.com/duke-listings/hm
restart: always
environment:
CommunicationConfiguration__CommunicationControlIP: "cc"
networks:
- sys
depends_on:
- cc
map:
build:
context: .
dockerfile: Dockerfile-map
#image: registry.digitalocean.com/duke-listings/map
restart: always
volumes:
- ./map/config.json:/usr/share/nginx/html/config.json:ro
ports:
- 80:80
networks:
- sys
networks:
sys:

View File

@ -1,3 +0,0 @@
{
"API": "http://10.1.1.2:8080/api/v1/client"
}

View File

@ -1,4 +1,4 @@
using DevOpsProject.CommunicationControl.Logic.Services.Interfaces; using DevOpsProject.CommunicationControl.Logic.Services.Interfaces;
using DevOpsProject.Shared.Clients; using DevOpsProject.Shared.Clients;
using DevOpsProject.Shared.Configuration; using DevOpsProject.Shared.Configuration;
using DevOpsProject.Shared.Enums; using DevOpsProject.Shared.Enums;
@ -37,7 +37,7 @@ namespace DevOpsProject.CommunicationControl.Logic.Services
bool isSuccessfullyDisconnected = false; bool isSuccessfullyDisconnected = false;
try try
{ {
var result = await _redisService.DeleteAsync(GetHiveKey(hiveId)); var result = await _redisService.DeleteAsync(hiveId);
isSuccessfullyDisconnected = result; isSuccessfullyDisconnected = result;
return result; return result;
} }
@ -65,32 +65,10 @@ namespace DevOpsProject.CommunicationControl.Logic.Services
public async Task<HiveOperationalArea> ConnectHive(HiveModel model) public async Task<HiveOperationalArea> ConnectHive(HiveModel model)
{ {
bool isHiveAlreadyConnected = await IsHiveConnected(model.HiveID);
if (isHiveAlreadyConnected)
{
_logger.LogWarning("Reconnect Hive request: {@model}", model);
}
else
{
_logger.LogInformation("Trying to connect Hive: {@model}", model);
}
bool result = await _redisService.SetAsync(GetHiveKey(model.HiveID), model); bool result = await _redisService.SetAsync(GetHiveKey(model.HiveID), model);
if (result) if (result)
{ {
_logger.LogInformation("Successfully connected Hive: {@model}", model);
var operationalArea = _spatialService.GetHiveOperationalArea(model); var operationalArea = _spatialService.GetHiveOperationalArea(model);
if (isHiveAlreadyConnected)
{
await _messageBus.Publish(new HiveReconnectedMessage
{
HiveID = model.HiveID,
Hive = model,
InitialOperationalArea = operationalArea,
IsSuccessfullyReconnected = result
});
}
else
{
await _messageBus.Publish(new HiveConnectedMessage await _messageBus.Publish(new HiveConnectedMessage
{ {
HiveID = model.HiveID, HiveID = model.HiveID,
@ -98,39 +76,31 @@ namespace DevOpsProject.CommunicationControl.Logic.Services
InitialOperationalArea = operationalArea, InitialOperationalArea = operationalArea,
IsSuccessfullyConnected = result IsSuccessfullyConnected = result
}); });
}
return operationalArea; return operationalArea;
} }
else else
{ {
_logger.LogError("Failed to connect Hive: {@model}", model); await _messageBus.Publish(new HiveConnectedMessage
{
HiveID = model.HiveID,
Hive = model,
IsSuccessfullyConnected = result
});
throw new HiveConnectionException($"Failed to connect hive for HiveId: {model.HiveID}"); throw new HiveConnectionException($"Failed to connect hive for HiveId: {model.HiveID}");
} }
} }
public async Task<bool> IsHiveConnected(string hiveId)
{
string hiveKey = GetHiveKey(hiveId);
return await _redisService.CheckIfKeyExists(hiveKey);
}
public async Task<DateTime> AddTelemetry(HiveTelemetryModel model) public async Task<DateTime> AddTelemetry(HiveTelemetryModel model)
{ {
string hiveKey = GetHiveKey(model.HiveID); string hiveKey = GetHiveKey(model.HiveID);
bool hiveExists = await _redisService.CheckIfKeyExists(hiveKey);
if (hiveExists)
{
bool result = await _redisService.UpdateAsync(hiveKey, (HiveModel hive) => bool result = await _redisService.UpdateAsync(hiveKey, (HiveModel hive) =>
{ {
hive.Telemetry = model; hive.Telemetry = model;
}); });
if (result)
{
_logger.LogInformation("Telemetry updated for HiveID: {hiveId}. Updated telemetry timestamp: {timestamp}", model.HiveID, model.Timestamp);
}
else
{
_logger.LogError("Failed to update Telemetry - Redis update issue. HiveID: {hiveId}, Telemetry model: {@telemetry}", model.HiveID, model);
}
await _messageBus.Publish(new TelemetrySentMessage await _messageBus.Publish(new TelemetrySentMessage
{ {
HiveID = model.HiveID, HiveID = model.HiveID,
@ -139,33 +109,44 @@ namespace DevOpsProject.CommunicationControl.Logic.Services
}); });
return model.Timestamp; return model.Timestamp;
} }
else
{
await _messageBus.Publish(new TelemetrySentMessage
{
HiveID = model.HiveID,
Telemetry = model,
IsSuccessfullySent = false
});
throw new HiveNotFoundException($"Hive not found for id: {model.HiveID}");
}
}
public async Task<string> SendHiveControlSignal(string hiveId, Location destination) public async Task<string> SendHiveControlSignal(string hiveId, Location destination)
{ {
var hive = await GetHiveModel(hiveId); var hive = await GetHiveModel(hiveId);
if (hive == null) if (hive == null)
{ {
_logger.LogError("Sending Hive Control signal: Hive not found for HiveID: {hiveId}", hiveId); throw new Exception($"Hive control signal error: cannot find hive with id: {hiveId}");
return null;
} }
bool isSuccessfullySent = false; bool isSuccessfullySent = false;
string hiveMindPath = _communicationControlConfiguration.CurrentValue.HiveMindPath;
try
{
var command = new MoveHiveMindCommand var command = new MoveHiveMindCommand
{ {
CommandType = State.Move, CommandType = State.Move,
Location = destination, Location = destination,
Timestamp = DateTime.Now Timestamp = DateTime.Now
}; };
try
{ var result = await _hiveHttpClient.SendHiveControlCommandAsync(hive.HiveSchema, hive.HiveIP, hive.HivePort,
var result = await _hiveHttpClient.SendHiveControlCommandAsync(hive.HiveSchema, hive.HiveIP, hive.HivePort, hiveMindPath, command); _communicationControlConfiguration.CurrentValue.HiveMindPath, command);
isSuccessfullySent = true; isSuccessfullySent = true;
return result; return result;
} }
finally finally
{
if (isSuccessfullySent)
{ {
await _messageBus.Publish(new MoveHiveMessage await _messageBus.Publish(new MoveHiveMessage
{ {
@ -174,12 +155,6 @@ namespace DevOpsProject.CommunicationControl.Logic.Services
HiveID = hiveId HiveID = hiveId
}); });
} }
else
{
_logger.LogError("Failed to send control command for Hive: {@hive}, path: {path}, \n Command: {@command}", hive, hiveMindPath, command);
}
}
} }
private string GetHiveKey(string hiveId) private string GetHiveKey(string hiveId)

View File

@ -8,7 +8,6 @@ namespace DevOpsProject.CommunicationControl.Logic.Services.Interfaces
Task<HiveModel> GetHiveModel(string hiveId); Task<HiveModel> GetHiveModel(string hiveId);
Task<List<HiveModel>> GetAllHives(); Task<List<HiveModel>> GetAllHives();
Task<HiveOperationalArea> ConnectHive(HiveModel model); Task<HiveOperationalArea> ConnectHive(HiveModel model);
Task<bool> IsHiveConnected(string hiveId);
Task<DateTime> AddTelemetry(HiveTelemetryModel model); Task<DateTime> AddTelemetry(HiveTelemetryModel model);
Task<string> SendHiveControlSignal(string hiveId, Location destination); Task<string> SendHiveControlSignal(string hiveId, Location destination);
} }

View File

@ -27,7 +27,6 @@ namespace DevOpsProject.HiveMind.Logic.Services
// If already moving - stop movement // If already moving - stop movement
if (HiveInMemoryState.IsMoving) if (HiveInMemoryState.IsMoving)
{ {
_logger.LogWarning("Previous movement command terminated. Previous destination: {@destination}, Current Location: {@current}, new destination: {@destination}", HiveInMemoryState.Destination, HiveInMemoryState.CurrentLocation, destination);
StopMovement(); StopMovement();
} }
@ -40,9 +39,8 @@ namespace DevOpsProject.HiveMind.Logic.Services
if (_movementTimer == null) if (_movementTimer == null)
{ {
// TODO: Recalculating position each N seconds // TODO: Recalculating position each N seconds
int intervalFromSeconds = 3; _movementTimer = new Timer(UpdateMovement, null, TimeSpan.Zero, TimeSpan.FromSeconds(3));
_movementTimer = new Timer(UpdateMovement, null, TimeSpan.Zero, TimeSpan.FromSeconds(intervalFromSeconds)); _logger.LogInformation("Movement timer started.");
_logger.LogInformation("Movement timer started. Destination: {@destination}, recalculation interval: {interval}", destination, intervalFromSeconds);
} }
} }
} }
@ -62,13 +60,14 @@ namespace DevOpsProject.HiveMind.Logic.Services
if (AreLocationsEqual(currentLocation.Value, destination.Value)) if (AreLocationsEqual(currentLocation.Value, destination.Value))
{ {
_logger.LogInformation("Reached destination. Current location: {@currentLocation}, Destination: {@destination}", currentLocation, destination);
StopMovement(); StopMovement();
return; return;
} }
Location newLocation = CalculateNextPosition(currentLocation.Value, destination.Value, 0.1f); Location newLocation = CalculateNextPosition(currentLocation.Value, destination.Value, 0.1f);
HiveInMemoryState.CurrentLocation = newLocation; HiveInMemoryState.CurrentLocation = newLocation;
_logger.LogInformation($"Moved closer: {newLocation}");
} }
} }
@ -78,6 +77,7 @@ namespace DevOpsProject.HiveMind.Logic.Services
_movementTimer = null; _movementTimer = null;
HiveInMemoryState.IsMoving = false; HiveInMemoryState.IsMoving = false;
HiveInMemoryState.Destination = null; HiveInMemoryState.Destination = null;
_logger.LogInformation("Movement stopped: Reached destination.");
} }
private static bool AreLocationsEqual(Location loc1, Location loc2) private static bool AreLocationsEqual(Location loc1, Location loc2)

View File

@ -48,8 +48,6 @@ namespace DevOpsProject.HiveMind.Logic.Services
}; };
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
_logger.LogInformation("Attempting to connect Hive. Request: {@request}, URI: {uri}", request, uriBuilder.Uri);
var retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) var retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.WaitAndRetryAsync( .WaitAndRetryAsync(
10, 10,

View File

@ -0,0 +1,19 @@
namespace DevOpsProject.Shared.Exceptions
{
public class HiveNotFoundException : Exception
{
public HiveNotFoundException()
{
}
public HiveNotFoundException(string message)
: base(message)
{
}
public HiveNotFoundException(string message, Exception inner)
: base(message, inner)
{
}
}
}

View File

@ -1,16 +0,0 @@
using DevOpsProject.Shared.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DevOpsProject.Shared.Messages
{
public class HiveReconnectedMessage : BaseMessage
{
public bool IsSuccessfullyReconnected { get; set; }
public HiveModel Hive { get; set; }
public HiveOperationalArea InitialOperationalArea { get; set; }
}
}

View File

@ -32,21 +32,17 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
[HttpGet("hive/{hiveId}")] [HttpGet("hive/{hiveId}")]
public async Task<IActionResult> GetHive(string hiveId) public async Task<IActionResult> GetHive(string hiveId)
{ {
var hiveExists = await _communicationControlService.IsHiveConnected(hiveId);
if (!hiveExists)
{
_logger.LogWarning("Failed to get Hive for HiveID: {hiveId}", hiveId);
return NotFound($"Hive with HiveID: {hiveId} is not found");
}
var hiveModel = await _communicationControlService.GetHiveModel(hiveId); var hiveModel = await _communicationControlService.GetHiveModel(hiveId);
return Ok(hiveModel); return Ok(hiveModel);
} }
[HttpGet("hive")] [HttpGet("hive")]
public async Task<IActionResult> GetHives() public async Task<IActionResult> GetHives()
{ {
var hives = await _communicationControlService.GetAllHives(); var hives = await _communicationControlService.GetAllHives();
return Ok(hives); return Ok(hives);
} }
@ -63,7 +59,6 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
if (request?.Hives == null || !request.Hives.Any()) if (request?.Hives == null || !request.Hives.Any())
return BadRequest("No hive IDs provided."); return BadRequest("No hive IDs provided.");
_logger.LogInformation("Hive moving request accepted by enpdoint. Request: {@request}", request);
foreach (var id in request.Hives) foreach (var id in request.Hives)
{ {
_ = Task.Run(async () => _ = Task.Run(async () =>
@ -74,7 +69,7 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Failed to send control signal for HiveID: {id} \n Request: {@request}", id, request); _logger.LogError(ex, $"Failed to send control signal for HiveID: {id}");
} }
}); });
} }

View File

@ -11,12 +11,10 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
public class HiveController : Controller public class HiveController : Controller
{ {
private readonly ICommunicationControlService _communicationControlService; private readonly ICommunicationControlService _communicationControlService;
private readonly ILogger<HiveController> _logger;
public HiveController(ICommunicationControlService communicationControlService, ILogger<HiveController> logger) public HiveController(ICommunicationControlService communicationControlService)
{ {
_communicationControlService = communicationControlService; _communicationControlService = communicationControlService;
_logger = logger;
} }
[HttpPost("connect")] [HttpPost("connect")]
@ -38,7 +36,6 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
}; };
return Ok(connectResponse); return Ok(connectResponse);
} }
[HttpPost("telemetry")] [HttpPost("telemetry")]
@ -54,9 +51,6 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
Timestamp = DateTime.Now Timestamp = DateTime.Now
}; };
bool isHiveConnected = await _communicationControlService.IsHiveConnected(request.HiveID);
if (isHiveConnected)
{
var telemetryUpdateTimestamp = await _communicationControlService.AddTelemetry(hiveTelemetryModel); var telemetryUpdateTimestamp = await _communicationControlService.AddTelemetry(hiveTelemetryModel);
var telemetryResponse = new HiveTelemetryResponse var telemetryResponse = new HiveTelemetryResponse
{ {
@ -65,12 +59,6 @@ namespace DevOpsProject.CommunicationControl.API.Controllers
return Ok(telemetryResponse); return Ok(telemetryResponse);
} }
else
{
_logger.LogWarning("Failed to write telemetry. Hive with HiveID: {hiveId} is not connected. Request: {@request}", request.HiveID, request);
return NotFound($"Failed to write telemetry. Hive with HiveID: {request.HiveID} is not connected");
}
}
} }
} }

View File

@ -12,5 +12,7 @@ namespace DevOpsProject.CommunicationControl.API.DI
return serviceCollection; return serviceCollection;
} }
} }
} }

View File

@ -1,3 +0,0 @@
{
"API": "http://localhost:8080/api/v1/client"
}

View File

@ -3,9 +3,9 @@ import axios from "axios";
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
// Fetch the center coordinates for the initial map load // Fetch the center coordinates for the initial map load
export const fetchCenterCoordinates = async (apiUrl) => { export const fetchCenterCoordinates = async () => {
try { try {
const response = await axios.get(`${apiUrl}/area`); const response = await axios.get(`${API_BASE_URL}/area`);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error("Error fetching center coordinates:", error); console.error("Error fetching center coordinates:", error);
@ -14,9 +14,9 @@ export const fetchCenterCoordinates = async (apiUrl) => {
}; };
// Fetch all hives and extract their latitude/longitude // Fetch all hives and extract their latitude/longitude
export const fetchHives = async (apiUrl) => { export const fetchHives = async () => {
try { try {
const response = await axios.get(`${apiUrl}/hive`); const response = await axios.get(`${API_BASE_URL}/hive`);
return response.data.map(hive => ({ return response.data.map(hive => ({
id: hive.HiveID, id: hive.HiveID,
@ -31,9 +31,9 @@ export const fetchHives = async (apiUrl) => {
}; };
// Move all hives to a new location // Move all hives to a new location
export const moveHives = async (apiUrl, lat, lon, ids) => { export const moveHives = async (lat, lon, ids) => {
try { try {
await axios.patch(`${apiUrl}/hive`, { await axios.patch(`${API_BASE_URL}/hive`, {
Hives: ids, Hives: ids,
Destination: { Destination: {
Latitude: lat, Latitude: lat,

View File

@ -21,7 +21,6 @@ const MapView = () => {
const mapRef = useRef(null); const mapRef = useRef(null);
const vectorLayerRef = useRef(null); const vectorLayerRef = useRef(null);
const initialized = useRef(false); const initialized = useRef(false);
const apiUrl = useRef(null)
const [hives, setHives] = useState([]); const [hives, setHives] = useState([]);
const [popup, setPopup] = useState({ visible: false, coords: null }); const [popup, setPopup] = useState({ visible: false, coords: null });
const [mouseCoords, setMouseCoords] = useState({ lat: "", lon: "" }); const [mouseCoords, setMouseCoords] = useState({ lat: "", lon: "" });
@ -29,17 +28,11 @@ const MapView = () => {
useEffect(() => { useEffect(() => {
const initializeMap = async () => { const initializeMap = async () => {
const res = await fetch('/config.json')
const data = await res.json()
apiUrl.current = data.API
if (initialized.current) return; if (initialized.current) return;
initialized.current = true; initialized.current = true;
try { try {
const center = await fetchCenterCoordinates(apiUrl.current); const center = await fetchCenterCoordinates();
if (center) { if (center) {
initMap(center.Latitude, center.Longitude); initMap(center.Latitude, center.Longitude);
await fetchAndDrawHives(); await fetchAndDrawHives();
@ -73,7 +66,7 @@ const MapView = () => {
// Fetch hives and draw them on the map // Fetch hives and draw them on the map
const fetchAndDrawHives = async () => { const fetchAndDrawHives = async () => {
try { try {
const data = await fetchHives(apiUrl.current); const data = await fetchHives();
setHives(data); setHives(data);
drawHives(data); drawHives(data);
} catch (error) { } catch (error) {
@ -181,7 +174,7 @@ const MapView = () => {
<Popup <Popup
isVisible={popup.visible} isVisible={popup.visible}
coords={popup.coords} coords={popup.coords}
onConfirm={() => moveHives(apiUrl.current, popup.coords.lat, popup.coords.lon, hives.map(h => h.id))} onConfirm={() => moveHives(popup.coords.lat, popup.coords.lon, hives.map(h => h.id))}
onCancel={() => setPopup({ visible: false })} onCancel={() => setPopup({ visible: false })}
/> />
</div> </div>