Skip to content

BloomTech-Labs/labs-api-java-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Labs Java Okta Scaffolding

Purpose:

The purpose of this project is to serve as a foundation, scaffolding, starting point for Labs project that will be having a Java Spring based backend.

Some Useful Notes

For PostgreSQL add the dependency

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
</dependency>

Add the DataSourceConfig class to use PostgreSQL Add lines to application.properties

# Which db to run
local.run.db=H2
# local.run.db=POSTGRESQL

To use PostgreSQL / OKTA locally

Add @PropertySource("file:/Users/lambdajohn/oktafoundationconf.properties") to the OktaFoundationApplication class

Create a file called /Users/lambdajohn/oktafoundationconf.properties with the following line. Note fill in <private> with real values:

spring.security.oauth2.resourceserver.jwt.issuer-uri=<private>
okta.oauth2.client-id=<private>
okta.oauth2.issuer=<private>
SPRING.DATASOURCE.URL=jdbc:postgresql://localhost:5432/oktafoundationdb?password=password&sslmode=prefer&user=postgres`

The Hierarchy of where the values are found OS environment variables. Application properties packaged inside your jar @PropertySource annotation on your Main Class

Use pgAdmin to create the database only before running your application!


Connect H2 Console to Local Postgres

Following this example fill in the fields on the h2console

Saved Settings: Generic PostgreSQL
Setting Name:   Generic PostgreSQL

Driver Class: org.postgresql.Driver
JDBC URL:  jdbc:postgresql://localhost:5432/oktafoundationdb
User Name: postgres
Password:  password

Deploy to Heroku using Maven

Setup Heroku

Note: fill in <private> with real values

heroku login
heroku create jrmmba-oktafoundation
heroku addons:create heroku-postgresql:hobby-dev -a jrmmba-oktafoundation
heroku config -a jrmmba-oktafoundation

heroku config:set spring.security.oauth2.resourceserver.jwt.issuer-uri=<private>
heroku config:set okta.oauth2.client-id=<private>
heroku config:set okta.oauth2.issuer=<private>

Use the Heroku GUI to access log

Now In Java

Add the plugin for heroku
<finalName>jrmmba-oktafoundation</finalName>

<!-- Heroku Maven Plugin Configuration -->
<plugin>
    <groupId>com.heroku.sdk</groupId>
    <artifactId>heroku-maven-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <appName>${project.build.finalName}</appName>
        <includeTarget>false</includeTarget>
        <includes>
            <include>${project.build.directory}/${project.build.finalName}.jar</include>
        </includes>
        <jdkVersion>${java.version}</jdkVersion>
        <processTypes>
            <web>java $JAVA_OPTS -Dserver.port=$PORT -jar target/${project.build.finalName}.jar</web>
        </processTypes>
    </configuration>
</plugin>

Add SimpleCorsFilter.java to handle deploying and CORS issues

In application.properties add spring.h2.console.settings.web-allow-others=true

To actually deploy, go to

Note You need to do this each time code is changed!

  • Maven Tab
  • Turn on Skip Test Mode
  • Maven Goals
  • mvn clean heroku:deploy -X

Connect H2 Console to Heroku Postgres

jdbc:postgresql://ec2-52-4-177-4.compute-1.amazonaws.com/d3bgb040dnfiod

On Heroku Find data from Heroku Config Var for DATABASE_URL. For example

postgres://username      :password                                                        @hostname                                 :5432/database name
postgres://knpiphpcrmdjaf:faf7655d32f2361fb57a5e9d96d1e38a11c532c1070960f49fb70bf080a3b409@ec2-54-242-43-231.compute-1.amazonaws.com:5432/dc61i9dr7csv7k
H2Console - http://jrmmba-foundation.herokuapp.com/h2-console

Following this example fill in the fields on the h2console

Saved Settings: Generic PostgreSQL
Setting Name:   Generic PostgreSQL

Driver Class: org.postgresql.Driver
JDBC URL:  jdbc:postgresql://ec2-54-242-43-231.compute-1.amazonaws.com:5432/dc61i9dr7csv7k
User Name: knpiphpcrmdjaf
Password:  faf7655d32f2361fb57a5e9d96d1e38a11c532c1070960f49fb70bf080a3b409

Deploy to Heroku using GitHub and Continuous Integration (CI)

Note that once this is set up, each time you push to the chosen branch on GitHub,

your application will get updated on Heroku and restart

see: https://stackoverflow.com/questions/39197334/automated-heroku-deploy-from-subfolder

In the root folder of your application you will find a Procfile. Change the name of your JAR file to match the application's name of Heroku application

In the Web Interface of Heroku

Under Deploy -> Connect to GitHub select repository (must have admin rights to repo)

Now only if not deploying from the root folder!

Now under Settings -> Reveal Config Vars
    Create a config var PROJECT_PATH = foundation
        The subdirectory where your application lives. If the application lives at the root, skip this step.
        The application lives in the folder where POM.XML file is.
Under Settings -> BuildPack
    add heroku/java by clicking on Java Button
    add https://github.com/timanovsky/subdir-heroku-buildpack.git. Move it to the top buildpack
        You may wish to fork the subdir-heroku-buildpack to your own repositories

Now for everyone

Back under Deploy -> Connect to GitHub -> Automatic deploys
    pick the branch you want to deploy
    Click on enable automatic deploys

Next time you deploy to your chosen branch, Heroku will get automatically updated!


Problem:

Heroku restarts your application once every 24 hours. It does this automatically; you have no control over it. This is a good thing and is similar to my mantra of restart your computer at least once a day!

However, if you leave your code as originally deployed (with creating the database turned on seeddata active), when Heroku restarts your application, any data changes made in the last 24 hours get wiped out. So much for presient data.

Solution:

Deploy your application as normal using postgresql

When you first deploy your application, in application.properties, you have the following set

spring.jpa.hibernate.ddl-auto=create
spring.datasource.initialization-mode=always

And you may have a SeedData class.

Make sure your application is running properly.

Now add the following config vars to your Heroku app

Config Var Value
spring_jpa_hibernate_ddl-auto update
spring_datasource_initialization-mode never
command_line_runner_enabled false

So, now when your application is restarted by Heroku, the values will be read from the config vars overriding what is in application.properties and so seed data is not active and you can keep your old data!


Introduction

This is a basic database scheme with users, user emails, and user roles. This Java Spring REST API application will provide endpoints for clients to read various data sets contained in the application's data. This application will also form the basis of a user authentication application developed elsewhere in the course

Database layout

The table layout is similar to the initial version with the following exceptions:

  • The join table userroles is explicitly created. This allows us to add additional columns to the join table
  • Since we are creating the join table ourselves, the Many to Many relationship that formed the join table is now two Many to One relationships
  • All tables now have audit fields

Thus the new table layout is as follows

  • User is the driving table.
  • Useremails have a Many-To-One relationship with User. Each User has many user email combinations. Each user email combination has only one User.
  • Roles have a Many-To-Many relationship with Users.

Image of Database Layout

Using the provided seed data, expand each endpoint below to see the output it generates.

http://localhost:2019/useremails/useremails
[
    {
        "useremailid": 5,
        "useremail": "[email protected]",
        "user": {
            "userid": 4,
            "username": "admin",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 3,
                        "name": "DATA"
                    }
                },
                {
                    "role": {
                        "roleid": 1,
                        "name": "ADMIN"
                    }
                },
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                }
            ]
        }
    },
    {
        "useremailid": 6,
        "useremail": "[email protected]",
        "user": {
            "userid": 4,
            "username": "admin",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 3,
                        "name": "DATA"
                    }
                },
                {
                    "role": {
                        "roleid": 1,
                        "name": "ADMIN"
                    }
                },
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                }
            ]
        }
    },
    {
        "useremailid": 8,
        "useremail": "[email protected]",
        "user": {
            "userid": 7,
            "username": "cinnamon",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                },
                {
                    "role": {
                        "roleid": 3,
                        "name": "DATA"
                    }
                }
            ]
        }
    },
    {
        "useremailid": 9,
        "useremail": "[email protected]",
        "user": {
            "userid": 7,
            "username": "cinnamon",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                },
                {
                    "role": {
                        "roleid": 3,
                        "name": "DATA"
                    }
                }
            ]
        }
    },
    {
        "useremailid": 10,
        "useremail": "[email protected]",
        "user": {
            "userid": 7,
            "username": "cinnamon",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                },
                {
                    "role": {
                        "roleid": 3,
                        "name": "DATA"
                    }
                }
            ]
        }
    },
    {
        "useremailid": 12,
        "useremail": "[email protected]",
        "user": {
            "userid": 11,
            "username": "barnbarn",
            "primaryemail": "[email protected]",
            "roles": [
                {
                    "role": {
                        "roleid": 2,
                        "name": "USER"
                    }
                }
            ]
        }
    }
]
http://localhost:2019/useremails/useremail/8
{
    "useremailid": 8,
    "useremail": "[email protected]",
    "user": {
        "userid": 7,
        "username": "cinnamon",
        "primaryemail": "[email protected]",
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            },
            {
                "role": {
                    "roleid": 3,
                    "name": "DATA"
                }
            }
        ]
    }
}
DELETE http://localhost:2019/useremails/useremail/8
No Body Data

Status OK
PUT http://localhost:2019/useremails/useremail/9/email/[email protected]

OUTPUT

Status OK
http://localhost:2019/useremails/useremail/9
{
    "useremailid": 9,
    "useremail": "[email protected]",
    "user": {
        "userid": 7,
        "username": "cinnamon",
        "primaryemail": "[email protected]",
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            },
            {
                "role": {
                    "roleid": 3,
                    "name": "DATA"
                }
            }
        ]
    }
}
POST http://localhost:2019/useremails/user/14/email/[email protected]

OUTPUT

Status CREATED

Location Header: http://localhost:2019/useremails/useremail/15
http://localhost:2019/useremails/useremail/15
{
    "useremailid": 15,
    "useremail": "[email protected]",
    "user": {
        "userid": 14,
        "username": "misskitty",
        "primaryemail": "[email protected]",
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            }
        ]
    }
}

http://localhost:2019/roles/roles
[
    {
        "roleid": 1,
        "name": "ADMIN",
        "users": [
            {
                "user": {
                    "userid": 4,
                    "username": "admin",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 5,
                            "useremail": "[email protected]"
                        },
                        {
                            "useremailid": 6,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            }
        ]
    },
    {
        "roleid": 2,
        "name": "USER",
        "users": [
            {
                "user": {
                    "userid": 14,
                    "username": "misskitty",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 15,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            },
            {
                "user": {
                    "userid": 13,
                    "username": "puttat",
                    "primaryemail": "[email protected]",
                    "useremails": []
                }
            },
            {
                "user": {
                    "userid": 11,
                    "username": "barnbarn",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 12,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            },
            {
                "user": {
                    "userid": 7,
                    "username": "cinnamon",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 9,
                            "useremail": "[email protected]"
                        },
                        {
                            "useremailid": 10,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            },
            {
                "user": {
                    "userid": 4,
                    "username": "admin",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 5,
                            "useremail": "[email protected]"
                        },
                        {
                            "useremailid": 6,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            }
        ]
    },
    {
        "roleid": 3,
        "name": "DATA",
        "users": [
            {
                "user": {
                    "userid": 4,
                    "username": "admin",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 5,
                            "useremail": "[email protected]"
                        },
                        {
                            "useremailid": 6,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            },
            {
                "user": {
                    "userid": 7,
                    "username": "cinnamon",
                    "primaryemail": "[email protected]",
                    "useremails": [
                        {
                            "useremailid": 9,
                            "useremail": "[email protected]"
                        },
                        {
                            "useremailid": 10,
                            "useremail": "[email protected]"
                        }
                    ]
                }
            }
        ]
    }
]
http://localhost:2019/roles/role/3
{
    "roleid": 3,
    "name": "DATA",
    "users": [
        {
            "user": {
                "userid": 4,
                "username": "admin",
                "primaryemail": "[email protected]",
                "useremails": [
                    {
                        "useremailid": 5,
                        "useremail": "[email protected]"
                    },
                    {
                        "useremailid": 6,
                        "useremail": "[email protected]"
                    }
                ]
            }
        },
        {
            "user": {
                "userid": 7,
                "username": "cinnamon",
                "primaryemail": "[email protected]",
                "useremails": [
                    {
                        "useremailid": 9,
                        "useremail": "[email protected]"
                    },
                    {
                        "useremailid": 10,
                        "useremail": "[email protected]"
                    }
                ]
            }
        }
    ]
}
http://localhost:2019/roles/role/name/data
{
    "roleid": 3,
    "name": "DATA",
    "users": [
        {
            "user": {
                "userid": 4,
                "username": "admin",
                "primaryemail": "[email protected]",
                "useremails": [
                    {
                        "useremailid": 5,
                        "useremail": "[email protected]"
                    },
                    {
                        "useremailid": 6,
                        "useremail": "[email protected]"
                    }
                ]
            }
        },
        {
            "user": {
                "userid": 7,
                "username": "cinnamon",
                "primaryemail": "[email protected]",
                "useremails": [
                    {
                        "useremailid": 9,
                        "useremail": "[email protected]"
                    },
                    {
                        "useremailid": 10,
                        "useremail": "[email protected]"
                    }
                ]
            }
        }
    ]
}
POST http://localhost:2019/roles/role

DATA

{
    "name" : "ANewRole"
}

OUTPUT

Status CREATED

Location Header: http://localhost:2019/roles/role/16
http://localhost:2019/roles/role/name/anewrole
{
    "roleid": 16,
    "name": "ANEWROLE",
    "users": []
}
PUT http://localhost:2019/roles/role/16

DATA

{
    "name" : "ANewRole"
}

OUTPUT

Status OK

http://localhost:2019/users/users
[
    {
        "userid": 4,
        "username": "admin",
        "primaryemail": "[email protected]",
        "useremails": [
            {
                "useremailid": 5,
                "useremail": "[email protected]"
            },
            {
                "useremailid": 6,
                "useremail": "[email protected]"
            }
        ],
        "roles": [
            {
                "role": {
                    "roleid": 3,
                    "name": "DATA"
                }
            },
            {
                "role": {
                    "roleid": 1,
                    "name": "ADMIN"
                }
            },
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            }
        ]
    },
    {
        "userid": 7,
        "username": "cinnamon",
        "primaryemail": "[email protected]",
        "useremails": [
            {
                "useremailid": 9,
                "useremail": "[email protected]"
            },
            {
                "useremailid": 10,
                "useremail": "[email protected]"
            }
        ],
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            },
            {
                "role": {
                    "roleid": 3,
                    "name": "DATA"
                }
            }
        ]
    },
    {
        "userid": 11,
        "username": "barnbarn",
        "primaryemail": "[email protected]",
        "useremails": [
            {
                "useremailid": 12,
                "useremail": "[email protected]"
            }
        ],
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            }
        ]
    },
    {
        "userid": 13,
        "username": "puttat",
        "primaryemail": "[email protected]",
        "useremails": [],
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            }
        ]
    },
    {
        "userid": 14,
        "username": "misskitty",
        "primaryemail": "[email protected]",
        "useremails": [
            {
                "useremailid": 15,
                "useremail": "[email protected]"
            }
        ],
        "roles": [
            {
                "role": {
                    "roleid": 2,
                    "name": "USER"
                }
            }
        ]
    }
]
http://localhost:2019/users/user/7
{
    "userid": 7,
    "username": "cinnamon",
    "primaryemail": "[email protected]",
    "useremails": [
        {
            "useremailid": 9,
            "useremail": "[email protected]"
        },
        {
            "useremailid": 10,
            "useremail": "[email protected]"
        }
    ],
    "roles": [
        {
            "role": {
                "roleid": 2,
                "name": "USER"
            }
        },
        {
            "role": {
                "roleid": 3,
                "name": "DATA"
            }
        }
    ]
}
http://localhost:2019/users/user/name/cinnamon
{
    "userid": 7,
    "username": "cinnamon",
    "primaryemail": "[email protected]",
    "useremails": [
        {
            "useremailid": 9,
            "useremail": "[email protected]"
        },
        {
            "useremailid": 10,
            "useremail": "[email protected]"
        }
    ],
    "roles": [
        {
            "role": {
                "roleid": 2,
                "name": "USER"
            }
        },
        {
            "role": {
                "roleid": 3,
                "name": "DATA"
            }
        }
    ]
}
http://localhost:2019/users/user/name/like/da
[]
POST http://localhost:2019/users/user

DATA

{
    "username": "Mojo",
    "primaryemail": "[email protected]",
    "password" : "Coffee123",
    "useremails": [
        {
            "useremail": "[email protected]"
        },
        {
            "useremail": "[email protected]"
        }
        ],
    "roles": [
        {
            "role": {
                "roleid": 1
            }
        },
        {
            "role": {
                "roleid": 2
            }
        }
    ]
}

OUTPUT

No Body Data

Location Header: http://localhost:2019/users/user/17
Status 201 Created
http://localhost:2019/users/user/name/mojo
PUT http://localhost:2019/users/user/14

DATA

{
    "username": "stumps",
    "primaryemail": "[email protected]",
    "password" : "EarlGray123",
    "useremails": [
        {
            "useremail": "[email protected]"
        },
        {
            "useremail": "[email protected]"
        }
        ],
    "roles": [
        {  
            "role": {
                "roleid": 3
            }
        },
        {  
            "role": {
                "roleid": 1
            }
        }
    ]
}

OUTPUT

No Body Data

Status OK
http://localhost:2019/users/user/name/stumps
{
    "userid": 16,
    "username": "stumps",
    "primaryemail": "[email protected]",
    "useremails": [
        {
            "useremailid": 19,
            "useremail": "[email protected]"
        },
        {
            "useremailid": 20,
            "useremail": "[email protected]"
        }
    ],
    "roles": [
        {
            "role": {
                "roleid": 1,
                "name": "ADMIN"
            }
        },
        {
            "role": {
                "roleid": 3,
                "name": "DATA"
            }
        }
    ]
}
PATCH http://localhost:2019/users/user/7

DATA

{
    "username": "cinabun",
    "primaryemail": "[email protected]",
    "useremails": [
    {
            "useremail": "[email protected]"
    },
    {
            "useremail": "[email protected]"
    },
    {
            "useremail": "[email protected]"
    }
    ]
}

OUTPUT

No Body Data

Status OK
http://localhost:2019/users/user/name/cinabun
{
    "userid": 7,
    "username": "cinabun",
    "primaryemail": "[email protected]",
    "useremails": [
        {
            "useremailid": 21,
            "useremail": "[email protected]"
        },
        {
            "useremailid": 22,
            "useremail": "[email protected]"
        },
        {
            "useremailid": 23,
            "useremail": "[email protected]"
        }
    ],
    "roles": [
        {
            "role": {
                "roleid": 2,
                "name": "USER"
            }
        },
        {
            "role": {
                "roleid": 3,
                "name": "DATA"
            }
        }
    ]
}
DELETE http://localhost:2019/users/user/14
No Body Data

Status OK

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published