Skip to content

Commit

Permalink
Merge branch 'console-ci-machine' of github.com:arvi3411301/graphql-e…
Browse files Browse the repository at this point in the history
…ngine into console-ci-machine
  • Loading branch information
arvi3411301 committed Dec 7, 2018
2 parents 066995a + e66ae23 commit 5694c0c
Show file tree
Hide file tree
Showing 518 changed files with 36,523 additions and 5,709 deletions.
3 changes: 3 additions & 0 deletions .circleci/ciignore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
set -eo pipefail
ROOT="$(readlink -f ${BASH_SOURCE[0]%/*}/../)"

# succeed until the script is fixed: https://github.com/hasura/graphql-engine/issues/1161
exit

# always build tagged builds
if [[ ! -z "$CIRCLE_TAG" ]]; then
echo "Skipping check for tags"
Expand Down
31 changes: 29 additions & 2 deletions .circleci/test-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ fi

if [ "$RUN_WEBHOOK_TESTS" == "true" ] ; then

echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & WEBHOOK #########################>\n"
echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & WEBHOOK (GET) #########################>\n"

export HASURA_GRAPHQL_AUTH_HOOK="https://localhost:9090/"
init_ssl
Expand All @@ -182,14 +182,41 @@ if [ "$RUN_WEBHOOK_TESTS" == "true" ] ; then

pytest -vv --hge-url="$HGE_URL" --pg-url="$HASURA_GRAPHQL_DATABASE_URL" --hge-key="$HASURA_GRAPHQL_ACCESS_KEY" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"

kill -INT $PID
sleep 4
combine_hpc_reports

echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & WEBHOOK (POST) #########################>\n"
export HASURA_GRAPHQL_AUTH_HOOK_MODE="POST"

"$GRAPHQL_ENGINE" serve >> "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!

wait_for_port 8080

pytest -vv --hge-url="$HGE_URL" --pg-url="$HASURA_GRAPHQL_DATABASE_URL" --hge-key="$HASURA_GRAPHQL_ACCESS_KEY" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"

rm /etc/ssl/certs/webhook.crt
update-ca-certificates

kill -INT $PID
sleep 4
combine_hpc_reports

echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & HTTPS INSECURE WEBHOOK ########>\n"
echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & HTTPS INSECURE WEBHOOK (GET) ########>\n"
export HASURA_GRAPHQL_AUTH_HOOK_MODE="GET"

"$GRAPHQL_ENGINE" serve >> "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!

wait_for_port 8080

pytest -vv --hge-url="$HGE_URL" --pg-url="$HASURA_GRAPHQL_DATABASE_URL" --hge-key="$HASURA_GRAPHQL_ACCESS_KEY" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" --test-webhook-insecure test_webhook_insecure.py

kill -INT $PID
sleep 4
combine_hpc_reports

echo -e "\n<########## TEST GRAPHQL-ENGINE WITH ACCESS KEY & HTTPS INSECURE WEBHOOK (POST) ########>\n"
export HASURA_GRAPHQL_AUTH_HOOK_MODE="POST"

"$GRAPHQL_ENGINE" serve >> "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ npm-debug.log
*.DS_Store
.tern-project
test-server-output
.vscode
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<a href="https://twitter.com/intent/follow?screen_name=HasuraHQ"><img src="https://img.shields.io/badge/Follow-HasuraHQ-blue.svg?style=flat&logo=twitter"></a>
<a href="https://eepurl.com/dBUfJ5"><img src="https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat"></a>

Hasura GraphQL Engine is a blazing-fast GraphQL server that gives you **instant, realtime GraphQL APIs over Postgres**, with [**webhook triggers**](event-triggers.md) on database events for asynchronous business logic.
Hasura GraphQL Engine is a blazing-fast GraphQL server that gives you **instant, realtime GraphQL APIs over Postgres**, with [**webhook triggers**](event-triggers.md) on database events, and [**remote schemas**](remote-schemas.md) for business logic.

Hasura helps you build GraphQL apps backed by Postgres or incrementally move to GraphQL for existing applications using Postgres.

Expand All @@ -28,14 +28,15 @@ Read more at [hasura.io](https://hasura.io) and the [docs](https://docs.hasura.i

* **Make powerful queries**: Built-in filtering, pagination, pattern search, bulk insert, update, delete mutations
* **Realtime**: Convert any GraphQL query to a live query by using subscriptions
* **Merge remote schemas**: Access custom GraphQL schemas for business logic via a single GraphQL Engine endpoint. [**Read more**](remote-schemas.md).
* **Trigger webhooks or serverless functions**: On Postgres insert/update/delete events ([read more](event-triggers.md))
* **Works with existing, live databases**: Point it to an existing Postgres database to instantly get a ready-to-use GraphQL API
* **Fine-grained access control**: Dynamic access control that integrates with your auth system (eg: auth0, firebase-auth)
* **High-performance & low-footprint**: ~15MB docker image; ~50MB RAM @ 1000 req/s; multi-core aware
* **Admin UI & Migrations**: Admin UI & Rails-inspired schema migrations
* **Postgres** ❤️: Supports Postgres types (PostGIS/geo-location, etc.), turns views to *graphs*, trigger stored functions or procedures with mutations

Read more at [https://hasura.io](https://hasura.io) and the [docs](https://docs.hasura.io).
Read more at [hasura.io](https://hasura.io) and the [docs](https://docs.hasura.io).

## Table of contents
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
Expand All @@ -47,7 +48,7 @@ Read more at [https://hasura.io](https://hasura.io) and the [docs](https://docs.
- [Architecture](#architecture)
- [Client-side tooling](#client-side-tooling)
- [Add business logic](#add-business-logic)
- [Custom resolvers](#custom-resolvers)
- [Remote schemas](#remote-schemas)
- [Trigger webhooks on database events](#trigger-webhooks-on-database-events)
- [Demos](#demos)
- [Realtime applications](#realtime-applications)
Expand Down Expand Up @@ -87,7 +88,7 @@ guides](https://docs.hasura.io/1.0/graphql/manual/getting-started/index.html) or

The Hasura GraphQL Engine fronts a Postgres database instance and can accept GraphQL requests from your client apps. It can be configured to work with your existing auth system and can handle access control using field-level rules with dynamic variables from your auth system.

You can also place the engine behind a central GraphQL proxy that fronts multiple GraphQL APIs via schema stitching.
You can also merge remote GraphQL schemas and provide a unified GraphQL API.

![Hasura GraphQL Engine architecture](assets/hasura-arch.svg)

Expand All @@ -97,18 +98,22 @@ Hasura works with any GraphQL client. We recommend using [Apollo Client](https:/

## Add business logic

### Custom resolvers
GraphQL Engine provides easy-to-reason, scalable and performant methods for adding custom business logic to your backend:

Add custom resolvers in addition to Hasura GraphQL engine. Ideal for delegating
to HTTP APIs, making direct calls to another data-source or writing business
logic in code - [read more](community/boilerplates/custom-resolvers).
### Remote schemas

Add custom resolvers in a remote schema in addition to Hasura's Postgres-based GraphQL schema. Ideal for use-cases like implementing a payment API, or querying data that is not in your database - [read more](remote-schemas.md).

### Trigger webhooks on database events

Add asynchronous business logic that is triggered based on database events.
Ideal for notifications, data-pipelines from Postgres or asynchronous
processing - [read more](event-triggers.md).

### Derived data or data transformations

Transform data in Postgres or run business logic on it to derive another dataset that can be queried using GraphQL Engine - [read more](https://docs.hasura.io/1.0/graphql/manual/queries/derived-data.html).

## Demos

Check out all the example applications in the
Expand All @@ -118,20 +123,20 @@ Check out all the example applications in the

- Group Chat application built with React, includes a typing indicator, online users & new
message notifications.
- [Try it out](https://chat-example-trial-roar.herokuapp.com/)
- [Try it out](https://realtime-chat.demo.hasura.app/)
- [Tutorial](community/examples/realtime-chat)
- [Browse APIs](https://hasura-realtime-group-chat.herokuapp.com/)
- [Browse APIs](https://realtime-chat.demo.hasura.app/console)

- Live location tracking app that shows a running vehicle changing current GPS
coordinates moving on a map.
- [Try it out](https://hasura.github.io/realtime-location-app/)
- [Try it out](https://realtime-location-tracking.demo.hasura.app/)
- [Tutorial](community/examples/realtime-location-tracking)
- [Browse APIs](https://realtime-backend.herokuapp.com/)
- [Browse APIs](https://realtime-location-tracking.demo.hasura.app/console)

- A realtime dashboard for data aggregations on continuously changing data.
- [Try it out](https://shahidh.in/hasura-realtime-poll/)
- [Try it out](https://realtime-poll.demo.hasura.app/)
- [Tutorial](community/examples/realtime-poll)
- [Browse APIs](https://hasura-realtime-poll.herokuapp.com/)
- [Browse APIs](https://realtime-poll.demo.hasura.app/console)

### Videos

Expand Down Expand Up @@ -185,8 +190,7 @@ badge to your applications built using Hasura. ❤️
## License

The core GraphQL Engine is available under the [GNU Affero General Public
License v3](https://www.gnu.org/licenses/agpl-3.0.en.html) (AGPL-3.0), the same
license as [MongoDB](https://www.mongodb.com/community/licensing). We have
License v3](https://www.gnu.org/licenses/agpl-3.0.en.html) (AGPL-3.0). We have
written more about what you can and cannot do under AGPL
[here](https://github.com/hasura/graphql-engine/wiki/License-Explained).

Expand Down
2 changes: 1 addition & 1 deletion assets/hasura-arch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/remote-schemas-arch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion cli/Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cli/Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@
[prune]
go-tests = true
unused-packages = true

[[constraint]]
branch = "master"
name = "github.com/oliveagle/jsonpath"
2 changes: 2 additions & 0 deletions cli/commands/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var ravenVersions = []mt.Version{

var testMetadata = map[string][]byte{
"metadata": []byte(`query_templates: []
remote_schemas: []
tables:
- array_relationships: []
delete_permissions: []
Expand All @@ -40,6 +41,7 @@ tables:
update_permissions: []
`),
"empty-metadata": []byte(`query_templates: []
remote_schemas: []
tables: []
`),
}
Expand Down
2 changes: 1 addition & 1 deletion cli/migrate/database/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type Driver interface {
UnLock() error

// Run applies a migration to the database. migration is garantueed to be not nil.
Run(migration io.Reader, fileType string) error
Run(migration io.Reader, fileType, fileName string) error

// Reset Migration Query Args
ResetQuery()
Expand Down
30 changes: 27 additions & 3 deletions cli/migrate/database/hasuradb/hasuradb.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

yaml "github.com/ghodss/yaml"
"github.com/hasura/graphql-engine/cli/migrate/database"
"github.com/oliveagle/jsonpath"
"github.com/parnurzeal/gorequest"
log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -48,6 +49,7 @@ type HasuraDB struct {
settings []database.Setting
migrations *database.Migrations
migrationQuery HasuraInterfaceBulk
jsonPath map[string]string
isLocked bool
logger *log.Logger
}
Expand Down Expand Up @@ -146,6 +148,7 @@ func (h *HasuraDB) Lock() error {
Type: "bulk",
Args: make([]interface{}, 0),
}
h.jsonPath = make(map[string]string)
h.isLocked = true
return nil
}
Expand Down Expand Up @@ -173,14 +176,33 @@ func (h *HasuraDB) UnLock() error {

// Handle migration version here
if horror.Path != "" {
jsonData, err := json.Marshal(h.migrationQuery)
if err != nil {
return err
}
var migrationQuery interface{}
err = json.Unmarshal(jsonData, &migrationQuery)
if err != nil {
return err
}
res, err := jsonpath.JsonPathLookup(migrationQuery, horror.Path)
if err == nil {
queryData, err := json.MarshalIndent(res, "", " ")
if err != nil {
return err
}
horror.migrationQuery = string(queryData)
}
re1, err := regexp.Compile(`\$.args\[([0-9]+)\]*`)
if err != nil {
return err
}

result := re1.FindAllStringSubmatch(horror.Path, -1)
if len(result) != 0 {

migrationNumber, ok := h.jsonPath[result[0][1]]
if ok {
horror.migrationFile = migrationNumber
}
}
}
return horror.Error(h.config.isCMD)
Expand All @@ -189,7 +211,7 @@ func (h *HasuraDB) UnLock() error {
return nil
}

func (h *HasuraDB) Run(migration io.Reader, fileType string) error {
func (h *HasuraDB) Run(migration io.Reader, fileType, fileName string) error {
migr, err := ioutil.ReadAll(migration)
if err != nil {
return err
Expand All @@ -207,6 +229,7 @@ func (h *HasuraDB) Run(migration io.Reader, fileType string) error {
},
}
h.migrationQuery.Args = append(h.migrationQuery.Args, t)
h.jsonPath[fmt.Sprintf("%d", len(h.migrationQuery.Args)-1)] = fileName

case "meta":
var t []interface{}
Expand All @@ -218,6 +241,7 @@ func (h *HasuraDB) Run(migration io.Reader, fileType string) error {

for _, v := range t {
h.migrationQuery.Args = append(h.migrationQuery.Args, v)
h.jsonPath[fmt.Sprintf("%d", len(h.migrationQuery.Args)-1)] = fileName
}
}
return nil
Expand Down
20 changes: 13 additions & 7 deletions cli/migrate/database/hasuradb/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ type HasuraColumn struct {

type HasuraError struct {
// MigrationFile is used internally for hasuractl
MigrationFile string `json:"migrationFile,omitempty"`
Path string `json:"path"`
ErrorMessage string `json:"error"`
Internal *SQLInternalError `json:"internal,omitempty"`
Message string `json:"message,omitempty"`
Code string `json:"code"`
migrationFile string
migrationQuery string
Path string `json:"path"`
ErrorMessage string `json:"error"`
Internal *SQLInternalError `json:"internal,omitempty"`
Message string `json:"message,omitempty"`
Code string `json:"code"`
}

type SQLInternalError struct {
Expand All @@ -87,7 +88,12 @@ type PostgresError struct {
func (h *HasuraError) CMDError() error {
var errorStrings []string
errorStrings = append(errorStrings, fmt.Sprintf("[%s] %s (%s)", h.Code, h.ErrorMessage, h.Path))
errorStrings = append(errorStrings, fmt.Sprintf("File: '%s'", h.MigrationFile))
if h.migrationFile != "" {
errorStrings = append(errorStrings, fmt.Sprintf("File: '%s'", h.migrationFile))
}
if h.migrationQuery != "" {
errorStrings = append(errorStrings, fmt.Sprintf("%s", h.migrationQuery))
}
if h.Internal != nil {
// postgres error
errorStrings = append(errorStrings, fmt.Sprintf("[%s] %s: %s", h.Internal.Error.StatusCode, h.Internal.Error.ExecStatus, h.Internal.Error.Message))
Expand Down
3 changes: 2 additions & 1 deletion cli/migrate/database/testing/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ func TestRunUp(t *testing.T, d database.Driver) {
version int64
migrationData []byte
migrationType string
migrationFile string
}{
{version: 1, migrationData: []byte("/* foobar migration */"), migrationType: "sql"},
{version: 3, migrationData: []byte("/* foobar migration */"), migrationType: "sql"},
}

for i, v := range tt {
err := d.Run(bytes.NewReader(v.migrationData), v.migrationType)
err := d.Run(bytes.NewReader(v.migrationData), v.migrationType, v.migrationFile)
if err != nil {
t.Fatalf("TestRun: expected err not to be nil in index %d", i)
}
Expand Down
2 changes: 1 addition & 1 deletion cli/migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ func (m *Migrate) runMigrations(ret <-chan interface{}) error {
case *Migration:
migr := r.(*Migration)
if migr.Body != nil {
if err := m.databaseDrv.Run(migr.BufferedBody, migr.FileType); err != nil {
if err := m.databaseDrv.Run(migr.BufferedBody, migr.FileType, migr.FileName); err != nil {
return err
}

Expand Down
5 changes: 3 additions & 2 deletions cli/migrate/source/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ func (f *File) Open(url string, logger *log.Logger) (source.Driver, error) {
continue // ignore files that we can't parse
}

if !nf.migrations.Append(m) {
return nil, fmt.Errorf("unable to parse file %v", fi.Name())
err = nf.migrations.Append(m)
if err != nil {
return nil, err
}
}
}
Expand Down
Loading

0 comments on commit 5694c0c

Please sign in to comment.