Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas-goebel authored Feb 22, 2024
0 parents commit 4827a50
Show file tree
Hide file tree
Showing 56 changed files with 7,105 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/code-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Code Analysis

on:
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
branches:
- master
schedule:
- cron: '0 0 * * *' # Runs the job at 00:00 UTC every day

jobs:
app-integration-test:
uses: eliona-smart-building-assistant/app-integration-tests/.github/workflows/code-analysis.yml@main
secrets: inherit
17 changes: 17 additions & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Integration Test

on:
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
branches:
- master
schedule:
- cron: '0 0 * * *' # Runs the job at 00:00 UTC every day

jobs:
app-integration-test:
uses: eliona-smart-building-assistant/app-integration-tests/.github/workflows/app-integration-test.yml@main
secrets: inherit
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.iml
.idea/**
apiserver/.openapi-generator/**
apiserver/api/**
apiserver/*_service.go
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This file is part of the eliona project.
# Copyright © 2022 LEICOM iTEC AG. All Rights Reserved.
# ______ _ _
# | ____| (_)
# | |__ | |_ ___ _ __ __ _
# | __| | | |/ _ \| '_ \ / _` |
# | |____| | | (_) | | | | (_| |
# |______|_|_|\___/|_| |_|\__,_|
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

FROM eliona/base-golang:latest-1-alpine AS build

RUN apk add git

WORKDIR /
COPY . ./

RUN go mod download

RUN DATE=$(date) && \
GIT_COMMIT=$(git rev-list -1 HEAD) && \
go build -ldflags "-X 'template/apiservices.BuildTimestamp=$DATE' -X 'template/apiservices.GitCommit=$GIT_COMMIT'" -o ../app

FROM eliona/base-alpine:latest AS target

COPY --from=build /app ./
COPY conf/*.sql ./conf/
COPY resources/ ./resources/
COPY openapi.yaml ./
COPY metadata.json ./

ENV TZ=Europe/Zurich
CMD [ "/app" ]
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 Leicom ITEC AG

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# App Template

This template is a part of the Eliona App SDK. It can be used to create an app stub for an Eliona environment.

## Configuration

The app needs environment variables and database tables for configuration. To edit the database tables the app provides an own API access.


### Registration in Eliona ###

To start and initialize an app in an Eliona environment, the app has to be registered in Eliona. For this, entries in database tables `public.eliona_app` and `public.eliona_store` are necessary.

This initialization can be handled by the `reset.sql` script.


### Environment variables

<mark>Todo: Describe further environment variables tables the app needs for configuration</mark>

- `CONNECTION_STRING`: configures the [Eliona database](https://github.com/eliona-smart-building-assistant/go-eliona/tree/main/db). Otherwise, the app can't be initialized and started (e.g. `postgres://user:pass@localhost:5432/iot`).

- `INIT_CONNECTION_STRING`: configures the [Eliona database](https://github.com/eliona-smart-building-assistant/go-eliona/tree/main/db) for app initialization like creating schema and tables (e.g. `postgres://user:pass@localhost:5432/iot`). Default is content of `CONNECTION_STRING`.

- `API_ENDPOINT`: configures the endpoint to access the [Eliona API v2](https://github.com/eliona-smart-building-assistant/eliona-api). Otherwise, the app can't be initialized and started. (e.g. `http://api-v2:3000/v2`)

- `API_TOKEN`: defines the secret to authenticate the app and access the Eliona API.

- `API_SERVER_PORT`(optional): define the port the API server listens. The default value is Port `3000`. <mark>Todo: Decide if the app needs its own API. If so, an API server have to implemented and the port have to be configurable.</mark>

- `LOG_LEVEL`(optional): defines the minimum level that should be [logged](https://github.com/eliona-smart-building-assistant/go-utils/blob/main/log/README.md). The default level is `info`.

### Database tables ###

<mark>Todo: Describe other tables if the app needs them.</mark>

The app requires configuration data that remains in the database. To do this, the app creates its own database schema `template` during initialization. To modify and handle the configuration data the app provides an API access. Have a look at the [API specification](https://eliona-smart-building-assistant.github.io/open-api-docs/?https://raw.githubusercontent.com/eliona-smart-building-assistant/app-template/develop/openapi.yaml) how the configuration tables should be used.

- `template.configuration`: Contains configuration of the app. Editable through the API.

- `template.asset`: Provides asset mapping. Maps broker's asset IDs to Eliona asset IDs.

**Generation**: to generate access method to database see Generation section below.


## References

### App API ###

The app provides its own API to access configuration data and other functions. The full description of the API is defined in the `openapi.yaml` OpenAPI definition file.

- [API Reference](https://eliona-smart-building-assistant.github.io/open-api-docs/?https://raw.githubusercontent.com/eliona-smart-building-assistant/app-template/develop/openapi.yaml) shows details of the API

**Generation**: to generate api server stub see Generation section below.


### Eliona assets ###

This app creates Eliona asset types and attribute sets during initialization.

The data is written for each device, structured into different subtypes of Elinoa assets. The following subtypes are defined:

- `Info`: Static data which provides information about a device like address and firmware info.
- `Status`: Device status information, like battery level.
- `Input`: Current values reported by sensors.
- `Output`: Values that are to be passed back to the provider.

### Continuous asset creation ###

Assets for all devices connected to the Template account are created automatically when the configuration is added.

To select which assets to create, a filter could be specified in config. The schema of the filter is defined in the `openapi.yaml` file.

Possible filter parameters are defined in the structs in `broker.go` and marked with `eliona:"attribute_name,filterable"` field tag.

To avoid conflicts, the Global Asset Identifier is a manufacturer's ID prefixed with asset type name as a namespace.

### Dashboard ###

An example dashboard meant for a quick start or showcasing the apps abilities can be obtained by accessing the dashboard endpoint defined in the `openapi.yaml` file.

## Tools

### Generate API server stub ###

For the API server the [OpenAPI Generator](https://openapi-generator.tech/docs/generators/openapi-yaml) for go-server is used to generate a server stub. The easiest way to generate the server files is to use one of the predefined generation script which use the OpenAPI Generator Docker image.

```
.\generate-api-server.cmd # Windows
./generate-api-server.sh # Linux
```

### Generate Database access ###

For the database access [SQLBoiler](https://github.com/volatiletech/sqlboiler) is used. The easiest way to generate the database files is to use one of the predefined generation script which use the SQLBoiler implementation.

```
.\generate-db.cmd # Windows
./generate-db.sh # Linux
```

### Generate asset type descriptions ###

For generating asset type descriptions from field-tag-annotated structs, [asse-from-struct tool](https://github.com/eliona-smart-building-assistant/dev-utilities) can be used.
9 changes: 9 additions & 0 deletions apiserver/.openapi-generator-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# If the API changes please remove these lines and merge the generated files with the existing ones.

api/**
README.md
70 changes: 70 additions & 0 deletions apiserver/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* App template API
*
* API to access and configure the app template
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/

package apiserver

import (
"context"
"net/http"
)

// ConfigurationAPIRouter defines the required methods for binding the api requests to a responses for the ConfigurationAPI
// The ConfigurationAPIRouter implementation should parse necessary information from the http request,
// pass the data to a ConfigurationAPIServicer to perform the required actions, then write the service results to the http response.
type ConfigurationAPIRouter interface {
DeleteConfigurationById(http.ResponseWriter, *http.Request)
GetConfigurationById(http.ResponseWriter, *http.Request)
GetConfigurations(http.ResponseWriter, *http.Request)
PostConfiguration(http.ResponseWriter, *http.Request)
PutConfigurationById(http.ResponseWriter, *http.Request)
}

// CustomizationAPIRouter defines the required methods for binding the api requests to a responses for the CustomizationAPI
// The CustomizationAPIRouter implementation should parse necessary information from the http request,
// pass the data to a CustomizationAPIServicer to perform the required actions, then write the service results to the http response.
type CustomizationAPIRouter interface {
GetDashboardTemplateByName(http.ResponseWriter, *http.Request)
}

// VersionAPIRouter defines the required methods for binding the api requests to a responses for the VersionAPI
// The VersionAPIRouter implementation should parse necessary information from the http request,
// pass the data to a VersionAPIServicer to perform the required actions, then write the service results to the http response.
type VersionAPIRouter interface {
GetOpenAPI(http.ResponseWriter, *http.Request)
GetVersion(http.ResponseWriter, *http.Request)
}

// ConfigurationAPIServicer defines the api actions for the ConfigurationAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type ConfigurationAPIServicer interface {
DeleteConfigurationById(context.Context, int64) (ImplResponse, error)
GetConfigurationById(context.Context, int64) (ImplResponse, error)
GetConfigurations(context.Context) (ImplResponse, error)
PostConfiguration(context.Context, Configuration) (ImplResponse, error)
PutConfigurationById(context.Context, int64, Configuration) (ImplResponse, error)
}

// CustomizationAPIServicer defines the api actions for the CustomizationAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type CustomizationAPIServicer interface {
GetDashboardTemplateByName(context.Context, string, string) (ImplResponse, error)
}

// VersionAPIServicer defines the api actions for the VersionAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type VersionAPIServicer interface {
GetOpenAPI(context.Context) (ImplResponse, error)
GetVersion(context.Context) (ImplResponse, error)
}
Loading

0 comments on commit 4827a50

Please sign in to comment.