Skip to content

This repository contains java projects created during an internship. Projects have been refined by me after a time.

Notifications You must be signed in to change notification settings

lucasmalara/internship

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 

Repository files navigation

INTERNSHIP ADB

This repository contains projects that are an outcome of my work placement (as a part of my first-cycle studies) in ADB POLSKA SP. Z O.O. (ZIELONA GORA OFFICE) that took place in July 2021. In the process of work placement I have been introduced to foundations of Spring framework. The culmination of work was to implement an example of simple REST API.

Note that this is not original repository I was working on during work placement. Projects included here has been improved in terms of code quality after self-reviewing the code. However, the general idea of the projects remained the same. Dependencies were updated since the creation of each project, but only up to a certain point.

TABLE OF CONTENT

EX1-BEANS

This project was focused on presentation of application of inversion of control (IoC) using simple Spring Beans that were managed by a Spring Container implemented as a AnnotationConfigApplicationContext class. The application is also writing in and reading out specific information to/from a created properties file at app running. The file looks as follows:

#Wed Jul 07 09:31:52 CEST 2021
date=2021-07-07
java-version=11.0.11
program-version=1.0

where date is computed locally by current date - java.time.LocalDate().now and java-version is an sdk version.

Table Of Content

  • Project Details
  • Dependencies

Project Details

Dependencies

ArtifactId Version
spring-context 5.3.23

EX2-BEANS

This project was focused on using dependency injection in action by defining a Spring Bean with a priority using @Primary annotation and also by specifying beans' name attribute. The injection takes place in a method parameter of the other bean. The project also presented an idea of two cooling systems implementations: Fridge class and Air Conditioning class.

Table Of Content

  • Project Details
  • Dependencies

Project Details

  • Java 11 (LTS)
  • Spring Boot 2
  • Maven

Dependencies

ArtifactId Version
spring-boot-starter 2.7.5
spring-boot-autoconfigure 2.7.5

EX3-SCHEDULING

This project has shown how to schedule a task with Spring using @Scheduled annotation. The task was focused on sending GET requests to chosen Web API and process each response.

UPDATE 12.11.2023: API seems to be no longer maintained.


  • (Expected) Processed response:
    RANDOM_FACT_HERE

Random facts are printed on console every 8s.

Table Of Content

  • Project Details
  • Dependencies

Project Details

  • Java 11 (LTS)
  • Spring Boot 2
  • Maven
  • API Docs

Dependencies

ArtifactId Version
spring-boot-starter 2.7.5
spring-boot-autoconfigure 2.7.5

EX4-STREAM-API-JUNIT-TESTS

This project was focused on both usage of stream API and unit testing with JUnit Jupiter framework. The purpose of the project has been satisfied based on an abstract implementation of dogs and cats.

Table Of Content

  • Project Details
  • Class Hierarchy Tree
  • Dependencies

Project Details

Class Hierarchy Tree

  • Object (java.lang)
    • Enum (java.lang)
      • Hairiness
      • CatHunterSense
      • DogCommand
    • Animal
      • Cat
      • Dog
    • AnimalUtils
    • AbstractCollection (java.util)
      • AbstractList (java.util)
        • ArrayList (java.util)
          • CustomizedArrayList

Dependencies

ArtifactId Version
lombok 1.18.24
JUnit Jupiter API 5.9.0
JUnit Jupiter Params 5.9.0

EX5-EXPERIMENTAL-GET-MAPPING

This project started as an experiment. It was focused on creating first basic Web API. Mapping was only provided for GET method. The concept of the project can be described as:

  • User sends a request with a parameter key name and (optionally) defined value.
  • API sends a response determined by the provided value of the key.
  • If the value of the key is undefined, equals to stranger or it DOES NOT MATCH specified regex, API returns general response (or error response in some cases).
  • Personalized responses' ids are incremented by 1 and all general responses' ids are always 0.
  • Incrementation is stopped being followed once application has been shut down.
  • Values of the key are being formatted before the API returns a response. Read further for details.

The general idea is that user can introduce themselves in a request and then API returns a welcome message as a response.

The application produces data in json format.

Table Of Content

  • Project Details
  • API Reference
  • RegEx Details
  • About Further Formatting name
  • API Response Examples
  • Dependencies

Project Details

  • Java 11 (LTS)
  • Spring Boot 2
  • Maven
  • Runs Tomcat on default configuration (port 8080)

API Reference

  GET /meeting
  GET /meeting?name=String
Key Value Description
name String Optional. Your name. stranger by default.

RegEx Details

RegEx to match for the key name

^(?!.*[\r\n])[\da-zA-Z ]+$

To match this regex it is necessary that:

  • Provided String IS NOT BLANK.
  • Provided String contains only latin letter(s) in lower or UPPER case or/and number(s) between 0 and 9 or/and space character(s).
  • Provided String has a single line.

About Further Formatting name

  • Let's say we provide value: %20L%20u%20%20c%20%20%20as%20%20 where %20 is encoding for a space character.
  • Value is being validated. In this case, validation is successful.
  • Now it's time for formatting. To simplify how it works, it can be said that:
    • We split validated String to multiple strings by each occurred space character.
    • We take each String that DOES NOT contain a space character, and we append it to the output.
    • After each, EXCEPT LAST appended String, we append a singular space character additionally.
    • Formatted output looks like this: L u c as.

In short, it can be said that every formatted value starts and ends with a latin letter or with a number, and between any pair (if exists) of the space characters, there is at least one latin letter or a number.

API Response Examples

General:

{
  "id": 0,
  "message": "Hello stranger. It's nice to meet you."
}

Examples:

  • GET /meeting?name=L%20u%20c%20as
{
  "id": 1,
  "message": "Hello L u c as. It's nice to meet you."
}
  • GET /meeting?name=0Lucas3
{
  "id": 2,
  "message": "Hello 0Lucas3. It's nice to meet you."
}
  • GET /meeting?name=10
{
  "id": 3,
  "message": "Hello 10. It's nice to meet you."
}

Note that it is still possible to force the API to return an error response.

Dependencies

ArtifactId Version
lombok 1.18.24
spring-boot-starter-web 2.7.5
spring-boot-autoconfigure 2.7.5

EX6-H2-STUDENTS

This project was focused on defining Entity class and Spring Data JPA repositories implementation. It was built additionally with Spring Component class, Spring Configuration class and Spring Service class. Configuration class implements CommandLineRunner interface and its method for providing execution of business logic defined in the service class, while the component class is responsible for value injection from properties file using @Value annotation. The value is used to define a number of students to create and add to the repository. Each student is created randomly using data from Datafaker library. For the presentation needs of findBySurname(String) method, it has been guaranteed that for n-students, there are exactly ⌊0,3*n⌋ students named Lopez. Each student id is autogenerated during entity creation. Created entities can be managed by H2 DBMS. Properties file for this project looks as follows:

instances.number=15

server.port=8080

spring.jpa.open-in-view=false

spring.h2.console.enabled=true
spring.h2.console.path=/h2

spring.datasource.url=jdbc:h2:mem:students
spring.datasource.driverClassName=org.h2.Driver

spring.datasource.username=sa
spring.datasource.password=

Table Of Content

  • Project Details
  • Screenshots
  • Dependencies

Project Details

Screenshots

h2 login window

database structure

students records

information on console

Dependencies:

ArtifactId Version
datafaker 1.7.0
lombok 1.18.24
spring-context 5.3.23
spring-boot 2.7.5
spring-boot-starter-web 2.7.5
spring-boot-starter-data-jpa 2.7.5
h2 2.1.214

EX7-RESTAPI-H2-BUSSES

This project was focused on simple REST API implementation. The project is built from the following components:

  • Spring Configuration class
  • Spring Rest Controller class
  • Spring Service class
  • Spring Data JPA repository
  • Spring Rest Controller Adviser class
  • Exception classes
  • Response Body class
  • Model class
  • Entity class
  • Utility classes

Utility classes delivers following functionalities:

  • Bus conversion. Mapping entities to model representation (and vice versa).
  • Data generator for busses.
  • Validation for String values.
  • Shuffling data to ensure pseudo-random results.

Handled exceptions using @ExceptionsHandler annotation:

  • BusNotFound - thrown, if it could not find a bus with given id.
  • BusAlreadyExists - thrown, if it could not add a bus with given id (id already taken)
  • And others

The application consumes and produces data in json format.

Table Of Content

  • Project Details
  • API Reference
  • RegEx Details
  • API Response Examples
  • Screenshots
  • Dependencies

Project Details

API Reference

1. GET

  GET /busses
  GET /busses?engine=String
Key Value Description
engine String Optional. Type of bus engine. Must match one of Enum's String value.
  GET /busses/{id}

where id is a value of a non-negative integer.


2. POST

  POST /busses
  • Request body pattern:
{
  "id": int,
  "brand": String,
  "model": int || String,
  "seats": int || null,
  "standingRoom": int || null,
  "length": int || null,
  "engine": String
}
  • where int is a non-negative integer.
  • null values are converted to 0s.
  • each int can be expressed as a String as well.

3. PUT

  PUT /busses/{id}

where id is a value of a non-negative integer.

  • Request body pattern:
{
  "id": int,
  "brand": String,
  "model": int || String,
  "seats": int || null,
  "standingRoom": int || null,
  "length": int || null,
  "engine": String
}
  • where int is a non-negative integer.
  • null values are converted to 0s.
  • each int can be expressed as a String as well.

4. DELETE

  DELETE /busses/{id}

where id is a value of a non-negative integer.


RegEx Details

RegEx to match for id, seats, standingRoom and length:

^\d+$

Just a number or sequence of numbers between 0 and 9.


RegEx to match for brand:

^(?!.*[_\r\n])[a-zA-Z]([-a-zA-Z ]*[a-zA-Z])?$

To match this regex it is necessary that:

  • Provided String IS NOT BLANK.
  • Provided String starts and ends with any latin letter in lower or UPPER case.
  • Provided String has a single line.
  • Every, except FIRST and LAST, index of provided String can be:
    • A latin letter in lower or UPPER case.
    • A space character.
    • A dash: .

RegEx to match for model:

^(?!.*[_\r\n])\w([-\w ]*\w)?$

To match this regex it is necessary that:

  • Provided String IS NOT BLANK.
  • Provided String starts and ends with a latin letter in lower or UPPER case or with any number between 0 and 9.
  • Provided String has a single line.
  • Every, except FIRST and LAST, index of provided String can be:
    • A latin letter in lower or UPPER case.
    • Any number between 0 and 9.
    • A space character.
    • A dash: .

RegEx to match for engine

^((?i)\bdiesel\b+?|(?i)\belectric\b+?)*$

To match this regex it is necessary to provide either diesel or electric in CASE-INSENSITIVE variant and in a SINGLE OCCURRENCE. That means each letter of either word can be independently in UPPER or lower case.

API Response Examples

Let's consider valid requests at first.

  • GET /busses

  • HTTP status: 200 OK

  • Response:

[
  {
    "id": "1",
    "brand": "Kia Motors",
    "model": "Prototype 2000",
    "seats": 35,
    "standingRoom": 29,
    "length": 16,
    "engine": "DIESEL"
  },
  {
    "id": "2",
    "brand": "Daewoo Bus",
    "model": "Quadrillion",
    "seats": 45,
    "standingRoom": 10,
    "length": 6,
    "engine": "ELECTRIC"
  },
  .,
  .,
  .,
  {
    "id": "10",
    "brand": "Kia Motors",
    "model": "Focus",
    "seats": 33,
    "standingRoom": 28,
    "length": 18,
    "engine": "DIESEL"
  }
]

  • GET /busses?engine=ELECTRIC

  • HTTP status: 200 OK

  • Response:

[
  {
    "id": "2",
    "brand": "Daewoo Bus",
    "model": "Quadrillion",
    "seats": 45,
    "standingRoom": 10,
    "length": 6,
    "engine": "ELECTRIC"
  },
  {
    "id": "4",
    "brand": "Renault",
    "model": "See-sharp",
    "seats": 55,
    "standingRoom": 26,
    "length": 12,
    "engine": "ELECTRIC"
  },
  .,
  .,
  .,
  {
    "id": "7",
    "brand": "Scania AB",
    "model": "Light",
    "seats": 66,
    "standingRoom": 12,
    "length": 15,
    "engine": "ELECTRIC"
  }
]

  • GET /busses/3

  • HTTP status: 200 OK

  • Response:

{
  "id": "3",
  "brand": "Kia Motors",
  "model": "Megane",
  "seats": 41,
  "standingRoom": 27,
  "length": 10,
  "engine": "DIESEL"
}

  • POST /busses

Request body:

{
  "id": 20,
  "brand": "myBrand",
  "model": "myModel",
  "seats": 50,
  "standingRoom": 14,
  "length": 8,
  "engine": "eLeCtRiC"
}
  • Http status: 201 Created
  • Response:
{
  "id": "20",
  "brand": "myBrand",
  "model": "myModel",
  "seats": 50,
  "standingRoom": 14,
  "length": 8,
  "engine": "ELECTRIC"
}

  • PUT /busses/20

Request body:

{
  "id": "21",
  "brand": "updatedBrand",
  "model": "updatedModel",
  "seats": 49,
  "standingRoom": 0,
  "length": 9,
  "engine": "diesel"
}
  • Http status: 200 OK
  • Response:
{
  "id": "20",
  "brand": "updatedBrand",
  "model": "updatedModel",
  "seats": 49,
  "standingRoom": 0,
  "length": 9,
  "engine": "DIESEL"
}

As we can see, once value is assigned to id, the property became immutable.


  • DELETE /busses/20

  • Http status: 204 No Content

  • Response:


The response has no content.


Now we are going to consider what happens if we do something wrong.


  • GET /busses/engine=myEngine

  • myEngine DOES NOT MATCH declared regex

  • HTTP status: 422 Unprocessable Entity

  • Response:

{
  "code": 3,
  "message": "Null not allowed."
}

  • GET /busses/{id}
  • PUT /busses/{id}
  • DELETE /busses/{id}

Path variable: myId

  • myId DOES NOT MATCH declared regex, hence repository does not contain a bus with such id.
  • HTTP status: 404 Not Found
  • Response:
{
  "code": 1,
  "message": "Bus with id: [myId] not found."
}

Path variable: 0

  • We assume repository DOES NOT CONTAIN a bus with id: 0
  • HTTP status: 404 Not Found
  • Response:
{
  "code": 1,
  "message": "Bus with id: [0] not found."
}

  • POST /busses

Request body:

{
  "id": "20",
  "brand": "newBrand",
  "model": "newModel",
  "seats": 25,
  "standingRoom": 10,
  "length": 4,
  "engine": "DIESEL"
}
  • HTTP status: 409 Conflict
  • Response:
{
  "code": 2,
  "message": "Bus with id: [20] already exists."
}

since we recently added a bus with id=20.


Request body:

{
  "id": "a",
  "brand": "newBrand",
  "model": "newModel",
  "seats": 25,
  "standingRoom": 10,
  "length": 4,
  "engine": "DIESEL"
}
  • HTTP status: 422 Unprocessable Entity
  • Response:
{
  "code": 3,
  "message": "Null not allowed."
}

since a DOES NOT MATCH declared regex.


Now we assume that bus with id=40 does not exist yet.

Request body:

{
  "id": "40",
  "brand": "?",
  "model": "!",
  "seats": 25,
  "standingRoom": 10,
  "length": 4,
  "engine": "DIESEL"
}
  • HTTP status: 422 Unprocessable Entity
  • Response:
{
  "code": 3,
  "message": "not-null property references a null or transient value : com.internship.adb.busses.persistence.entity.BusEntity.brand"
}

since ? and ! DOES NOT MATCH declared regex.


Request body:

{
  "id": "40",
  "brand": "newBrand",
  "model": "newModel",
  "seats": "b",
  "standingRoom": "c",
  "length": "d",
  "engine": "DIESEL"
}
  • HTTP status: 400 Bad Request
  • Response:
{
  "code": 3,
  "message": "JSON parse error: Cannot deserialize value of type `int` from String \"b\": not a valid `int` value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `int` from String \"b\": not a valid `int` value\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 5, column: 12] (through reference chain: com.internship.adb.busses.model.BusModel[\"seats\"])"
}

since b and c and d DOES NOT MATCH declared regex.


Request body:

{
  "id": "40",
  "brand": "newBrand",
  "model": "newModel",
  "seats": 25,
  "standingRoom": 10,
  "length": 4,
  "engine": true
}
  • HTTP status: 422 Unprocessable Entity
  • Response:
{
  "code": 3,
  "message": "Null not allowed."
}

since String value of true DOES NOT MATCH declared regex.


Request body:

{
  "brand": "newBrand",
  "model": "newModel",
  "seats": 25,
  "standingRoom": 10,
  "length": 4,
  "engine": "DIESEL"
}
  • HTTP status: 422 Unprocessable Entity
  • Response:
{
  "code": 3,
  "message": "Null not allowed."
}

since there is no occurrence of required json property. In this case it is no occurrence of id.


Missing Request Body:

  • HTTP status: 400 Bad Request
  • Response:
{
    "code": 3,
    "message": "Required request body is missing: public org.springframework.http.ResponseEntity<com.internship.adb.busses.model.BusModel> com.internship.adb.busses.controller.BusController.addBus(com.internship.adb.busses.model.BusModel)"
}

since request body is required.

Screenshots

h2 login window

database structure

busses records

Dependencies

ArtifactId Version
lombok 1.18.24
spring-boot-starter-web 2.7.5
spring-boot-starter-data-jpa 2.7.5
h2 2.1.214
hibernate-core 5.6.12.Final

Author

@lucasmalara

About

This repository contains java projects created during an internship. Projects have been refined by me after a time.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages