Skip to content

Commit

Permalink
Merged the API repo
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Dec 12, 2023
2 parents 87d7c39 + e1be483 commit 92466d7
Show file tree
Hide file tree
Showing 24 changed files with 1,563 additions and 22 deletions.
31 changes: 15 additions & 16 deletions .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.302'
include-prerelease: true
- name: Build
run: dotnet build --configuration Release src/DroneFlightLogDb.sln
- name: Run unit tests and generate code coverage
run: dotnet test src/DroneFlightLogDb.sln /p:CollectCoverage=true /p:CoverletOutput=coverage/ /p:CoverletOutputFormat=lcov
- name: Generage Coveralls code coverage
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: src/DroneFlightLog.Data.Tests/coverage/coverage.info
- uses: actions/checkout@v1
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: "7.0.302"
include-prerelease: true
- name: Build
run: dotnet build --configuration Release src/DroneFlightLog.sln
- name: Run unit tests and generate code coverage
run: dotnet test src/DroneFlightLog.sln /p:CollectCoverage=true /p:CoverletOutput=coverage/ /p:CoverletOutputFormat=lcov
- name: Generage Coveralls code coverage
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: src/DroneFlightLog.Data.Tests/coverage/coverage.info
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DroneFlightLogDb
# DroneFlightLog

[![Build Status](https://github.com/davewalker5/DroneFlightLogDb/workflows/.NET%20Core%20CI%20Build/badge.svg)](https://github.com/davewalker5/DroneFlightLogDb/actions)
[![GitHub issues](https://img.shields.io/github/issues/davewalker5/DroneFlightLogDb)](https://github.com/davewalker5/DroneFlightLogDb/issues)
Expand All @@ -13,23 +13,42 @@

DroneFlightLogDb implements the entities and business logic for a SQL-based drone flight logbook, providing facilities for recording and querying the following data:

* Operator details
* Drones, models and manufacturers
* Flights, flight locations and flight properties
- Operator details
- Drones, models and manufacturers
- Flights, flight locations and flight properties

## Getting Started

Please see the [Wiki](https://github.com/davewalker5/DroneFlightLogDb/wiki) for details on how to reference and use the Drone Flight Log business logic and how to get started with a database to hold the data.

## Authors

- **Dave Walker** - *Initial work* - [LinkedIn](https://www.linkedin.com/in/davewalker5/)
- **Dave Walker** - _Initial work_ - [LinkedIn](https://www.linkedin.com/in/davewalker5/)

<<<<<<< HEAD

## Feedback

To file issues or suggestions, please use the [Issues](https://github.com/davewalker5/DroneFlightLogDb/issues) page for this project on GitHub.
# To file issues or suggestions, please use the [Issues](https://github.com/davewalker5/DroneFlightLogDb/issues) page for this project on GitHub.

## Credits

Implementation of authentication using JWT is based on the following tutorial:

- https://github.com/cornflourblue/aspnet-core-3-jwt-authentication-api
- https://jasonwatmore.com/post/2019/10/11/aspnet-core-3-jwt-authentication-tutorial-with-example-api#users-controller-cs

## Feedback

To file issues or suggestions, please use the [Issues](https://github.com/davewalker5/DroneFlightLog.Api/issues) page for this project on GitHub.

> > > > > > > api/master
## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
<<<<<<< HEAD

=======

> > > > > > > api/master
4 changes: 4 additions & 0 deletions docker/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:latest
COPY droneflightlog.api-1.2.0.0 /opt/droneflightlog.api-1.2.0.0
WORKDIR /opt/droneflightlog.api-1.2.0.0/bin
ENTRYPOINT [ "./DroneFlightLog.Api" ]
97 changes: 97 additions & 0 deletions docker/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# droneflightlogapisqlite

The [DroneFlightLogDb](https://github.com/davewalker5/DroneFlightLogDb) and [DroneFlightLog.Api](https://github.com/davewalker5/DroneFlightLog.Api) GitHub projects implement the entities, business logic and a REST service for a SQL-based drone flight logbook, providing facilities for recording and querying the following data:

- Operator details
- Drones, models and manufacturers
- Flights, flight locations and flight properties

The droneflightlogapisqlite image contains a build of the logic and REST service for a SQLite database.

## Getting Started

### Prerequisities

In order to run this image you'll need docker installed.

- [Windows](https://docs.docker.com/windows/started)
- [OS X](https://docs.docker.com/mac/started/)
- [Linux](https://docs.docker.com/linux/started/)

### Usage

#### Container Parameters

The following "docker run" parameters are recommended when running the droneflightlogapisqlite image:

| Parameter | Value | Purpose |
| --------- | ------------------------------------------ | ------------------------------------------------------- |
| -d | - | Run as a background process |
| -v | /local:/var/opt/droneflightlog.api-1.0.0.4 | Mount the host folder containing the SQLite database |
| -p | 5001:80 | Expose the container's port 80 as port 5001 on the host |
| --rm | - | Remove the container automatically when it stops |

For example:

```shell
docker run -d -v /local:/var/opt/droneflightlog.api-1.0.0.4/ -p 5001:80 --rm davewalker5/droneflightlogapisqlite:latest
```

The "/local" path given to the -v argument is described, below, and should be replaced with a value appropriate for the host running the container. Similarly, the port number "5001" can be replaced with any available port on the host.

#### Volumes

The description of the container parameters, above, specifies that a folder containing the SQLite database file for the Drone Flight Log is mounted in the running container, using the "-v" parameter.

That folder should contain a SQLite database that has been created using the instructions in the [Drone Flight Log wiki](https://github.com/davewalker5/DroneFlightLogDb/wiki).

Specifically, the following should be done:

- [Create the SQLite database](https://github.com/davewalker5/DroneFlightLogDb/wiki/Using-a-SQLite-Database)
- [Add a user to the database](https://github.com/davewalker5/DroneFlightLogDb/wiki/REST-API)

The folder containing the "droneflightlog.db" file can then be passed to the "docker run" command using the "-v" parameter.

#### Running the Image

To run the image, enter the following command, substituting "/local" for the host folder containing the SQLite database, as described:

```shell
docker run -d -v /local:/var/opt/droneflightlog.api-1.0.0.4/ -p 5001:80 --rm davewalker5/droneflightlogapisqlite:latest
```

Once the container is running, browse to the following URL on the host:

http://localhost:5001

You should see the Swagger API documentation for the API.

## Built With

The droneflightlogapisqlite image was been built with the following:

| Aspect | Version |
| -------------- | ---------------------- |
| .NET Core CLI | 3.1.101 |
| Target Runtime | linux-x64 |
| Docker Desktop | 19.03.5, build 633a0ea |

## Find Us

- [DroneFlightLogDb on GitHub](https://github.com/davewalker5/DroneFlightLogDb)
- [DroneFlightLog.Api on GitHub](https://github.com/davewalker5/DroneFlightLog.Api)

## Versioning

For the versions available, see the [tags on this repository](https://github.com/davewalker5/DroneFlightLog.Api/tags).

## Authors

- **Dave Walker** - _Initial work_ - [LinkedIn](https://www.linkedin.com/in/davewalker5/)

See also the list of [contributors](https://github.com/davewalker5/DroneFlightLog.Api/contributors) who
participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE](https://github.com/davewalker5/DroneFlightLog.Api/blob/master/LICENSE) file for details.
79 changes: 79 additions & 0 deletions src/DroneFlightLog.Api/Controllers/AddressesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.Threading.Tasks;
using System.Web;
using DroneFlightLog.Data.Entities;
using DroneFlightLog.Data.Exceptions;
using DroneFlightLog.Data.Interfaces;
using DroneFlightLog.Data.Sqlite;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace DroneFlightLog.Api.Controllers
{
[Authorize]
[ApiController]
[ApiConventionType(typeof(DefaultApiConventions))]
[Route("[controller]")]
public class AddressesController : Controller
{
private readonly IDroneFlightLogFactory<DroneFlightLogDbContext> _factory;

public AddressesController(IDroneFlightLogFactory<DroneFlightLogDbContext> factory)
{
_factory = factory;
}

[HttpGet]
[Route("{id}")]
public async Task<ActionResult<Address>> GetAddressAsync(int id)
{
Address address;

try
{
address = await _factory.Addresses.GetAddressAsync(id);
}
catch (AddressNotFoundException)
{
return NotFound();
}

return address;
}

[HttpGet]
[Route("{number}/{postcode}/{country}")]
public async Task<ActionResult<Address>> FindAddressAsync(string number, string postcode, string country)
{
string decodedNumber = HttpUtility.UrlDecode(number);
string decodedPostcode = HttpUtility.UrlDecode(postcode);
string decodedCountry = HttpUtility.UrlDecode(country);
Address address = await _factory.Addresses.FindAddressAsync(decodedNumber, decodedPostcode, decodedCountry);

if (address == null)
{
return NotFound();
}

return address;
}

[HttpPost]
[Route("")]
public async Task<ActionResult<Address>> CreateModelAsync([FromBody] Address template)
{
Address address;

try
{
address = await _factory.Addresses.AddAddressAsync(template.Number, template.Street, template.Town, template.County, template.Postcode, template.Country);
await _factory.Context.SaveChangesAsync();
}
catch (AddressExistsException)
{
return BadRequest();
}

return address;
}
}
}
122 changes: 122 additions & 0 deletions src/DroneFlightLog.Api/Controllers/DronesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DroneFlightLog.Data.Entities;
using DroneFlightLog.Data.Exceptions;
using DroneFlightLog.Data.Interfaces;
using DroneFlightLog.Data.Sqlite;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace DroneFlightLog.Api.Controllers
{
[Authorize]
[ApiController]
[ApiConventionType(typeof(DefaultApiConventions))]
[Route("[controller]")]
public class DronesController : Controller
{
private readonly IDroneFlightLogFactory<DroneFlightLogDbContext> _factory;

public DronesController(IDroneFlightLogFactory<DroneFlightLogDbContext> factory)
{
_factory = factory;
}

[HttpGet]
[Route("")]
public async Task<ActionResult<List<Drone>>> GetDronesAsync()
{
List<Drone> drones = await _factory.Drones.GetDronesAsync(null).ToListAsync();

if (!drones.Any())
{
return NoContent();
}

return drones;
}

[HttpGet]
[Route("model/{modelId}")]
public async Task<ActionResult<List<Drone>>> GetDronesForModelAsync(int modelId)
{
List<Drone> drones = await _factory.Drones.GetDronesAsync(modelId).ToListAsync();

if (!drones.Any())
{
return NoContent();
}

return drones;
}

[HttpGet]
[Route("{id}")]
public async Task<ActionResult<Drone>> GetDroneAsync(int id)
{
Drone drone;

try
{
drone = await _factory.Drones.GetDroneAsync(id);
}
catch (DroneNotFoundException)
{
return NotFound();
}

return drone;
}

[HttpPut]
[Route("")]
public async Task<ActionResult<Drone>> UpdateDroneAsync([FromBody] Drone template)
{
Drone drone;

try
{
drone = await _factory.Drones.UpdateDroneAsync(template.Id, template.Name, template.SerialNumber, template.ModelId);
await _factory.Context.SaveChangesAsync();
}
catch (ModelNotFoundException)
{
return BadRequest();
}
catch (DroneExistsException)
{
return BadRequest();
}
catch (DroneNotFoundException)
{
return NotFound();
}

return drone;
}

[HttpPost]
[Route("")]
public async Task<ActionResult<Drone>> CreateDroneAsync([FromBody] Drone template)
{
Drone drone;

try
{
drone = await _factory.Drones.AddDroneAsync(template.Name, template.SerialNumber, template.ModelId);
await _factory.Context.SaveChangesAsync();
}
catch (ModelNotFoundException)
{
return BadRequest();
}
catch (DroneExistsException)
{
return BadRequest();
}

return drone;
}
}
}
Loading

0 comments on commit 92466d7

Please sign in to comment.