%! TeX program = lualatex
\documentclass[a4paper,11pt]{article} 
% packages
\usepackage{censor}
\StopCensoring
\usepackage{fontspec}
\setmainfont{EB Garamond}
% for tironian et fallback
% % \directlua{luaotfload.add_fallback
% % ("emojifallback",
% %      {"Noto Serif:mode=harf"}
% % )}
% % \setmainfont{EB Garamond}[RawFeature={fallback=emojifallback}]

\setmonofont[Scale=MatchLowercase]{Deja Vu Sans Mono}
\usepackage[a4paper,left=2cm,right=2cm,top=\dimexpr15mm+1.5\baselineskip,bottom=2cm]{geometry}
\setlength{\parindent}{0pt}

\usepackage{fancyhdr}       % Headers and footers 
\fancyhead[R]{\normalfont \leftmark}
\fancyhead[L]{}
\pagestyle{fancy}

\usepackage{microtype}      % Slightly tweak font spacing for aesthetics
\usepackage[english]{babel} % Language hyphenation and typographical rules
\usepackage{xcolor}
\definecolor{linkblue}{RGB}{0, 64, 128}
\usepackage[final, colorlinks = false, urlcolor = linkblue]{hyperref} 
% \newcommand{\secref}[1]{\textbf{§~\nameref{#1}}}
\newcommand{\secref}[1]{\textbf{§\ref{#1}~\nameref{#1}}}
\usepackage{array}
\usepackage{amsmath}

\usepackage{changepage}     % adjust margins on the fly


\usepackage{minted}
\usemintedstyle{algol_nu}

\usepackage{pgfplots}
\pgfplotsset{width=\textwidth,compat=1.9}

\usepackage{caption}
\newenvironment{code}{\captionsetup{type=listing}}{}
\captionsetup[listing]{skip=0pt}
\setlength{\abovecaptionskip}{5pt}
\setlength{\belowcaptionskip}{5pt}

\usepackage[yyyymmdd]{datetime}
\renewcommand{\dateseparator}{--}

\usepackage{enumitem}

\usepackage{titlesec}

\author{Andrew Hayes}

\begin{document}
\begin{titlepage}
    \begin{center}
        \hrule
        \vspace*{0.6cm}
        \huge \textbf{CT417}
        \vspace*{0.6cm}
        \hrule
        \LARGE
        \vspace{0.5cm}
            Software Engineering III
        \vspace{0.5cm}
        \hrule

        \vfill
        \vfill

        \hrule
        \begin{minipage}{0.495\textwidth} 
            \vspace{0.4em}
            \raggedright
            \normalsize 
            Name: Andrew Hayes \\
            E-mail: \href{mailto://a.hayes18@universityofgalway.ie}{\texttt{a.hayes18@universityofgalway.ie}}  \hfill\\
            Student ID: 21321503 \hfill
        \end{minipage}
        \begin{minipage}{0.495\textwidth} 
            \raggedleft
            \vspace*{0.8cm}
            \Large
            \today
            \vspace*{0.6cm}
        \end{minipage}
        \medskip\hrule 
    \end{center}
\end{titlepage}

\pagenumbering{roman}
\newpage
\tableofcontents
\newpage
\setcounter{page}{1}
\pagenumbering{arabic}

\section{Introduction}
\subsection{Lecturer Contact Details}
\begin{itemize}
    \item   Dr. Effirul Ramlan.
    \item   Email: \href{mailto://effirul.ramlan@universityofgalway.ie}{\texttt{effirul.ramlan@universityofgalway.ie}}.
    \item   Will attempt to reply to emails immediately between the hours of 09:00 \& 20:00 from Week 01 to
            Week 12.
    \item   Discord server: \url{https://discord.gg/CRAtHv9uNg}.
\end{itemize}

\subsection{Grading}
\begin{itemize}
    \item   Continuous Assessment: 40\%.
            \begin{itemize}
                \item   You will work in pairs on a software project with three key submissions across the 12 weeks.
                        Each deliverable will align with the topics covered in the course up to that point, allowing 
                        for continuous progress assessment.
                \item   AS-01: Set up musicFinder and configure the CI/CD pipeline (Week 4).
                \item   AS-02: Testing, Security, \& Expanded Application (Week 8).
                \item   AS-03: Refactoring \& Application Deployment.
            \end{itemize}

    \item   Final Exam: 60\%.
            \begin{itemize}
                \item   Typical 2-hour exam paper covering materials from Week 1 to Week 12, with nothing out of the ordinary --
                        ``You can be sure of that''.
                    \item   ``There is a question on Agile on your final'' -- key differences between agile \& DevOps table.
            \end{itemize}
\end{itemize}

\section{Revision}
\subsection{What is Software?}
\textbf{Software} consists of:
\begin{enumerate}[label=\roman*.]
    \item   Instruction (computer programs) that when executed provide desired features, function, \& performance.
    \item   Data structures (Arrays, Objects, Lists, Dictionaries, Maps, etc.) that enable programs to manipulate information.
    \item   Descriptive information in both hard copy \& virtual format describing the operation \& use.
\end{enumerate}

\subsection{Functional vs Non-Functional Requirements}
\begin{table}[h!]
    \centering

    \begin{tabular}{|>{\arraybackslash}p{0.5\textwidth}|>{\arraybackslash}p{0.5\textwidth}|}
        \hline
        \textbf{Functional Requirement}                                             & \textbf{Non-Functional Requirement} \\
        \hline
        Describes the actions with which the user's work is concerned               & Describes the experience of the user while doing the work \\
        \hline
        A feature or function that can be captured in use-cases                     & A global constraint (and therefore difficult to capture in use-cases) \\
        \hline
        A behaviour that can be analysed via sequence diagrams or state machines    & A software quality \\
        \hline
        can be usually traced back to a single module / class / function            & Usually cannot be implemented in a single module or even program \\
        \hline
    \end{tabular}
    \caption{Functional vs Non-Functional Requirements}
\end{table}

Typical non-functional requirements include: availability, maintainability, performance, privacy, reliablility, scalability, \& security.

\subsection{What is Software Engineering?}
\textbf{Software Engineering} is the field of computer science that deals with the building of software systems that are so large or so complex
that they are built by a team or teams of engineers.
Software Engineering encompasses a process, a collection of methods, \& an array of tools that allow professionals to build high-quality software.
\\\\
\textbf{DevOps} outlines a software development process that increases the delivery of higher quality software by integrating the efforts of the development 
\& IT operation teams.
$$
    \text{DevOps} = \text{Software Engineering} + \text{IT Operations}
$$

\subsection{What are Software Development Life Cycles?}
\textbf{Software Development Life Cycles (SDLC)} refers to a process used by software engineers to design, develop, \& test software.
Each approach focuses on a different aspect of development, from planning to continuous improvement.

\subsection{What is a Framework?}
A \textbf{software framework} is an abstraction in which common code providing generic functionality can be selectively 
overridden or specialised by user providing specific functionality.
\\\\
\textbf{Low-code} is a method of designing \& developing applications using an intuitive GUI \& embedded functionality that reduce 
traditional professional code writing requirements.
\textbf{No-code} is similar to low-code, but for non-technical business users as it allows them to develop software / applications without
having to write a single line of code.

\subsection{Agile \& DevOps}
\subsubsection{What is Agile?}
\textbf{Agile} is a method of software development consisting of:
\begin{itemize}
    \item   \textbf{Iterative \& Incremental Development:} Software is developed in small, workable increments.
    \item   \textbf{Customer-Centric:} Constant feedback from customers to refine requirements.
    \item   \textbf{Frequent Delivery:} Rapid releases of smaller, functional product versions.
    \item   \textbf{Adaptability:} Agile responds to change quickly
\end{itemize}

\subsubsection{Agile Principles}
\begin{itemize}
    \item   \textbf{Individuals \& Interactions:} over processes \& tools.
    \item   \textbf{Working Software:} over comprehensive documentation.
    \item   \textbf{Customer Collaboration:} over contract negotiation.
    \item   \textbf{Responding to Change:} over following a plan.
    \item   \textbf{Quote:} ``The highest priority is to satisfy the customer through early \& continuous delivery of valuable software.''
\end{itemize}

\subsubsection{Agile Frameworks}
Agile methodologies \& frameworks include:
\begin{itemize}
    \item   \textbf{Scrum:} Divides work into sprints (2-4 weeks) with regular stand-ups \& reviews.
    \item   \textbf{Kanban:} Focuses on visualising workflow \& limiting Work-In-Progress (WIP).
    \item   \textbf{XP (eXtreme Programming):} Emphasises technical excellence \& frequent releases.
    \item   \textbf{Lean Development:} Focuses on minimising waste \& maximising value.
\end{itemize}

\subsubsection{What is DevOps?}
\textbf{DevOps} is a culture \& set of practices that integrated development (Dev) \& operations (Ops).
It involves collaboration \& automation between developers \& IT operations for faster delivery of high-quality software.
It also involves continuous integration/continuous delivery (CI/CD) to automate code testing \& deployment.

$$
    \text{DevOps} = \text{Development} + \text{Operations}
$$

\subsubsection{DevOps Core Practices}
DevOps core practices include:
\begin{itemize}
    \item   \textbf{CI/CD Pipelines:} Automating the building, testing, \& deployment of code.
    \item   \textbf{Infrastructure as Code (IaC):} Managing infrastructure through code (e.g., Terraform, Ansible).
    \item   \textbf{Monitoring \& Logging:} Ensures system reliability through real-time tracking \& analysis.
    \item   \textbf{Collaboration \& Communication:} Cross-functional teams sharing ownership of development \& operations tasks.
\end{itemize}

\subsubsection{Key Differences between Agile \& DevOps}
\begin{table}[h!]
    \centering

    \begin{tabular}{|>{\arraybackslash}p{0.5\textwidth}|>{\arraybackslash}p{0.5\textwidth}|}
        \hline
        \textbf{Agile}                                                              & \textbf{DevOps} \\
        \hline
        Focus on frequent customer feedback                                         & Focus on collaboration between Dev \& Ops teams \\
        \hline
        Iteration done through iterative cycles                                     & Iteration done through rapid feedback loops \\
        \hline
        Scope of smaller, incremental changes                                       & Scope of large-scale projects \\
        \hline
        Uses task management software (e.g. Jira)                                   & Uses automation tools (e.g. Jenkins) \\
        \hline
        Scrum, XP frameworks                                                        & Kanban, DevOps lifecycle frameworks \\
        \hline
    \end{tabular}
    \caption{Key Differences between Agile \& DevOps}
\end{table}

\textbf{Agile} focuses on iterative development \& customer feedback, with a short feedback loop.
\textbf{DevOps} focuses on automating delivery, collaboration, \& integration between Dev \& Ops teams, integrating the entire process for faster releases.

\subsubsection{Why DevOps Complements Agile}
Agile improvements development velocity, but DevOps extends the concept to deployment \& maintenance.
Both are customer-focused, but DevOps ensures rapid \& reliable deployment in addition to development.
DevOps fills gaps Agile doesn't cover, like operations, infrastructure, \& automation.
Agile helps development teams iterate \& adapt to changing requirements, while DevOps bridges the gap between developers \& IT operations.

\subsubsection{Benefits of Agile \& DevOps}
\begin{itemize}
    \item   Faster, more frequent delivery of features.
    \item   Improved communication \& collaboration between teams. 
    \item   Reduced risk of deployment errors.
    \item   Ability to adapt to customer feedback \& market changes rapidly.
    \item   Higher-quality software \& reduced time-to-market.
\end{itemize}
 
\section{Version Control}
\subsection{What is Version Control?}
\textbf{Version Control} is a system that records changes to a file or set of files over time, allowing you to recall or access specific versions
at a later date.
It is also known as \textit{revision control} or \textit{source control}.
It allows you to keep track of changes, by whom, \& when they occurred.
Some of the popular version control programs include Git, CVS, Subversion, Team Foundation Server, \& Mercurial.
\\\\
It allows us to:
\begin{itemize}
    \item   Backup the source code and be able to rollback to a previous version.
    \item   Keep a record of who did what and when (know who to praise \& who to fire).
    \item   Collaborate with the team (know who to praise \& who to fire).
    \item   Troubleshoot issues by analysing the change history to figure out what caused the problem.
    \item   Analyse statistics such as who is being the most productive etc.
\end{itemize}

\subsection{What files should be checked in to Version Control?}
Any file that influences the software build should be checked into version control.
This includes configuration files, file encodings, binary settings, etc.
Furthermore, anything that is needed to setup the project from a clean checkout / fork should also be included in the version 
control, such as source code, documentation, manuals, image files, datasets, etc.
\\\\
You should not check in any binary files such as JAR files or any other ``build'' files, any intermediate files from build / 
compilation such as \verb|.pyc| or \verb|.o| files, any files which contain an absolute path, or personal preference /
personal settings files.

\subsection{Centralised Version Control -- Subversion}
\begin{figure}[H]
    \centering
    \includegraphics[width=0.8\textwidth]{images/centralised_vcs.png}
    \caption{Centralised Version Control System Diagram}
\end{figure}

\textbf{Subversion} is a centralised version control system in which code is centralised in a repository which can be checked out 
to get a working copy on your local machine.
In general, you don't have the entire repository checked out in Subversion, just a specific branch.
Changes are committed back to the central repository, ``normally'' with useful comments, and a change log is maintained 
of who did what \& when.

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/svn_trunk.png}
    \caption{Trunk in Subversion}
\end{figure}

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/svn_branch.png}
    \caption{Branching in Subversion}
\end{figure}

When you check out the project in subversion, you will get the \verb|HEAD| revision.
When you invoke the command \mintinline{shell}{svn update}, you are updating your local copy to the \verb|HEAD| version
as well.
Branches should eventually be merged back into the trunk with \mintinline{shell}{svn commit}.
The trunk must build afterwards.
The commit is a process of storing changes from your private workplace to the central server.
After the commit, your changes are made available to the rest of the team;
other developers can retrieve these changes by updating their working copy.
Committing is an \textbf{atomic operation}: either the whole commit succeeds, or it is entirely rolled back -- users never
see a half-finished commit.

\begin{figure}[H]
    \centering
    \includegraphics[width=0.8\textwidth]{images/svn_sequential_merge.png}
    \caption{Sequential Merge in Subversion}
\end{figure}

\begin{figure}[H]
    \centering
    \includegraphics[width=0.8\textwidth]{images/svn_conflict1.png}
    \caption{Type 1 Merge Conflict in Subversion}
\end{figure}

\begin{figure}[H]
    \centering
    \includegraphics[width=0.8\textwidth]{images/svn_conflict2.png}
    \caption{Type 2 Merge Conflict in Subversion}
\end{figure}

\subsection{Distributed Version Control -- Git}
\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/distributed_vcs.png}
    \caption{Distributed Version Control System Diagram}
\end{figure}

Git encourages branching for every feature, regardless of size.
After successful completion of the new feature, the branch is merged into the trunk.
Each developer gets their own local repository, meaning that developers don't need a network connection 
to commit changes, inspect previous version, or compare \verb|diff|s.
If the production trunk / branch is broken, developers can continue working uninhibited.

\subsubsection{GitHub}
\textbf{GitHub} is a web-based hosted service for Git repositories.
It allows you to host remote Git repositories and has a wealth of community-based services that makes it ideal for open-source projects.
It is a publishing tool, a version control system, \& a collaboration platform.

\subsubsection{Git Commands}
\begin{itemize}
    \item   \mintinline{shell}{git clone}: download (``clone'') the source code from the remote repository.
    \item   \mintinline{shell}{git fetch}: fetches the latest version from the repository that you've cloned but doesn't synchronise with all commits
            in the repository.
    \item   \mintinline{shell}{git pull}: pulls the latest version from the repository that you've cloned and synchronises with all commits
            in the repository. Equivalent to running \mintinline{shell}{git fetch} \& \mintinline{shell}{git merge}.
    \item   \mintinline{shell}{git push}: pushes the changes that you have committed to your local branch to the remote repository.
\end{itemize}

\subsubsection{Pull Requests}
A \textbf{pull request} is when you ask another developer to merge your feature branch into their repository.
Everyone can review the code \& decide whether or not it should be included in the master branch.
The pull request is an invitation to discuss pulling your code into the master branch, i.e. it is a forum for discussing changes.

\section{Build Tools}
\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/example_cd.png}
    \caption{Example of a Continuous Software Development System}
\end{figure}

The \textbf{build} is a process which covers all the steps required to create a deliverable of your software.
E.g., in Java:
\begin{enumerate}
    \item   Generating sources.
    \item   Compiling sources.
    \item   Compiling test sources.
    \item   Executing tests.
    \item   Packaging (\verb|.JAR|, \verb|.WAR|, \verb|EJB|).
    \item   Running health checks.
    \item   Generating reports.
\end{enumerate}

\textbf{Build tools} are software utilities that automate the tasks of compiling, linking, \& packaging source code into 
executable application or libraries.
Build tools help with:
\begin{itemize}
    \item   \textbf{Automation:} build tools help to automate repetitive tasks such as compiling code, running tests, 
            packaging binaries, \& even deploying applications.
    \item   \textbf{Consistency:} build tools ensure that every build process (e.g., dev, test, prod) is identical, 
            minimising human error.
    \item   \textbf{Efficiency:} build tools speed up development by automating builds whenever code is pushed or merged 
            into a repository.
\end{itemize}

Popular build tools include:
\begin{itemize}
    \item   \textbf{Maven} is a software build tool which can manage the project build, reporting, \& documentation,
            primarily used for Java development and supported by most Java IDEs.
            It features dependency management, project structure standardisation, \& automatic builds.
    \item   \textbf{Gradle} is a build tool that supports multiple languages including Java, Kotlin, \& Groovy.
            Its features include being highly customisable and being faster than Maven due to its incremental builds \&
            caching.
            It's preferred for modern Java-based CI/CD pipelines and supports both Android \& general Java applications.
    \item   \textbf{Node Package Manager (NPM)} is a build tool for JavaScript / Node.js that features dependency 
            management \& building for JavaScript applications.
            It is used to build web-based frontend applications or backend applications in a CI/CD pipeline.
\end{itemize}

Other popular build tools include Yarn for JavaScript, PyBuilder or tox for Python, MSBuild for C\#/.NET, \& Rake for Ruby.

\subsection{Build Tools in CI/CD Pipelines}
\textbf{Continuous Integration (CI)} automatically integrates \& tests code on each commit.
\textbf{Continuous Deployment/Delivery (CD)} automatically deploys tested code to production or staging.
Build tools serve many roles in CI/CD pipelines:
\begin{itemize}
    \item   \textbf{Integration:} when changes are pushed to the repository, the CI tool (e.g., GitHub Actions) triggers the
            build tool to compile \& package the application.
    \item   \textbf{Build Automation:} the build tool automatically handles downloading dependencies, compiling the code, 
            \& running tests.
            It ensures that the same version of the application is built every time.
    \item   \textbf{Testing:} many build tools, such as Maven, integrate with testing frameworks (e.g., JUnit, Selenium) to
            run automated tests after the build.
    \item   \textbf{Deployment:} the packaged application can be deployed to a server, containerised (e.g., with Docker),
            or distributed using CD tools.
\end{itemize}

Build tools automate the process of building \& testing code with each integration to the repository, i.e.
\textbf{Continuous Integration}.
They ensure new changes don't break existing code by running automated tests as part of the build process and exhibit 
\textit{fail-fast} behaviour: if a test or build fails, the developer is notified immediately.
\\\\
After a successful build \& testing, the build tools package the code, ready for deployment, i.e. 
\textbf{Continuous Deployment}.
\textbf{Artifact creation} is when the builds create deployable artifacts (e.g., JAR files, WAR files, Docker images).
The pipeline can then engage in \textbf{automated deployment} by deploying the artifact to a server, cloud, or container.
\\\\
An example build tool workflow in a CI/CD pipeline with GitHub Actions may look like the following:
\begin{enumerate}
    \item   \textbf{Code Push:} a developer pushes new code to the GitHub repository.
    \item   \textbf{CI Tool Trigger:} GitHub Actions detects the change and triggers the pipeline.
    \item   \textbf{Dependency Resolution:} the build tool (e.g., Maven) fetches dependencies from repositories.
    \item   \textbf{Compile \& Build:} the build tool compiles \& packages the code into executable binaries (e.g., JAR, WAR).
    \item   \textbf{Testing:} run unit \& integration tests automatically.
    \item   \textbf{Package \& Deploy:} the build tool creates the package, and the CI/CD pipeline deploys it to staging or 
            production.
\end{enumerate}

\subsection{Maven}
\textbf{Maven} is a software build tool which can manage the project build, reporting, \& documentation, primarily used for
Java development and supported by most Java IDEs.
It is widely used in Spring Boot projects.
\begin{enumerate}
    \item   Compile source code.
    \item   Copy resources.
    \item   Compile \& run tests.
    \item   Package projects.
    \item   Deploy project.
    \item   Cleanup files.
\end{enumerate}

Developers wanted:
\begin{itemize}
    \item   to make the build process easy.
    \item   a standard way to build projects.
    \item   a clear definition of what the project consists of.
    \item   an easy way to publish project information and a way to share JARs across several projects.
\end{itemize}

The result is a tool that developers can use to build \& manage any Java-based project.
It embraces the idea of ``convention over configurations''.

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/mvn_dir_structure.png}
    \caption{Maven Default Directory Structure}
\end{figure}

The command \mintinline{shell}{mvn package} compiles all the Java files, runs any tests, and packages the 
deliverable code \& resources into \verb|target/my-app-1.0.jar**|.
\\\\
The \verb|pom.xml| file is an XML document that contains all the information that Maven requires to automate 
a build of your software.
The \verb|pom.xml| is automatically updated on demand, but can be manually configured as well.
The POM provides all the configuration for a single project:
\begin{itemize}
    \item   General configuration covers the project's name, its owner, \& its dependencies to other projects.
    \item   One can also configure individual phases of the build process, which are implemented as plugins.
            E.g., one can configure the \verb|compiler-plugin| to use Java 1.5 for compilation, or specify
            packaging the project even if some unit tests fail.
\end{itemize}

Larger projects should be divided into several modules, or sub-projects each with its own POM.
All root POM can compile all the modules with a single command.
POMs can also inherit configuration from other POMs; all POMs inherit from the super-POM by default.
The super-POM provides default configuration, such as default source, default directories, default plugins,
etc.

\subsubsection{Plugins}
Maven build projects based on convention; it expects files to be in a certain place, which is very useful 
when developing in teams.

\begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{images/mvn_conv_dir_structure.png}
    \caption{Maven Conventional Directory Structure}
\end{figure}

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{images/mvn_pom.png}
    \caption{Maven \texttt{pom.xml}}
\end{figure}

A Maven \textbf{plugin} is an extension or add-on module that enhances the functionality of Apache Maven.
Maven plugins provide additional capabilities \& tasks that can be executed during the build process or as part of 
project lifecycle management.
These plugins are typically packages as JAR (Java Archive) files and can be easily added to a Maven project's
configuration.
\\\\
The \textbf{core plugins} are plugins corresponding to default core phases (e.g., clean, compile).
They may also have multiple goals.

\subsubsection{Build Lifecycle}
The process for building \& distributing a particular project is clearly defined. 
It comprises a list of named phases that can be used to give order to goal execution.
Goals provided by plugins can be associated with different phases of the lifecycle.
e.g., by default, the goal \verb|compiler:compile| is associated with the compile phase, while the goal
\verb|surefire:test| is associated with the test phase.
\mintinline{shell}{mvn test} will cause Maven to run all goals associated with each of the phases up to \& including
the test phase.

\subsubsection{Dependency Management}
\textbf{Dependency management} is a central feature in Maven.
The dependency mechanism is organised around a co-ordinate system identifying individual artefacts such as software 
libraries or modules (e.g., JUnit).
If your project depends on a JAR file, Maven will automatically retrieve it for you, and store it in the user's local
repository.
If the JAR file depends on other libraries, Maven will ensure these are also included: these are known as 
\textbf{transitive dependencies}.
This wasn't always a part of Maven, so it's a huge benefit.
\\\\
Dependency management features supported include:
\begin{itemize}
    \item   Management: you can specify library version that transitive dependencies should use.
    \item   Scope: include dependencies appropriate for the current stage of the build, i.e., compile, test, run, etc.
    \item   Exclude dependencies: if project X depends on Project Y, and Project Y depends on Project Z, you can choose
            to exclude Project Z from your build.
\end{itemize}

\subsubsection{Local \& Remote Repository}
The remote repository \url{https://mvnrepository.com/} contains libraries for almost everything: cloud computing,
date \& time utilities, HTML parsers, mail clients, etc.
Once you specify the correct details in the POM file, Maven will automatically fetch the library for you on build.
\\\\
The local Maven repository can be found at \verb|~/.m2/|.
Maven will search the local repository first and then search third-party repositories if it does not find what it's looking
for.
You can create your own repository and share it within your organisation.

\subsection{Spring Boot}
\textbf{Spring Boot} is a framework for building standalone Java applications with embedded servers that streamlines Java
application development.
It provides pre-configured, out-of-the-box functionality to avoid boilerplate code.
It reduces configuration \& setup, focuses on \textit{convention over configuration}, and is compatible with microservices
architecture, REST APIs, \& monolithic apps.

\subsubsection{Spring vs Spring Boot}
\textbf{Spring} is a comprehensive framework for building any Java application requiring more manual configuration \& 
management of dependencies \& application context.
Spring Boot is an extension of the Spring framework aimed at simplifying development, configuration, \& deployment, 
especially for microservices \& cloud-based applications.

\begin{table}[h!]
    \centering

    \begin{tabular}{|>{\arraybackslash}p{0.5\textwidth}|>{\arraybackslash}p{0.5\textwidth}|}
        \hline
        \textbf{Spring}                                                 & \textbf{Spring Boot} \\
        \hline
        Requires an external embedded server (e.g, Tomcat, Jetty, etc.) & Comes with an embedded server (Tomcat/Jetty)\\
        \hline
        Highly flexible but requires more setup effort                  & Simplifies Spring projects, reducing setup time \\
        \hline
        Best for complex, large-scale applications                      & Ideal for microservices \& fast prototypes \\
        \hline
        Requires WAR file and deployment on external server             & Packaged as JAR with an embedded server for easy deployment \\
        \hline
    \end{tabular}
    \caption{Technical Differences between Spring \& Spring Boot}
\end{table}

Choose Spring when:
\begin{itemize}
    \item   Your project requires extensive customisations.
    \item   You're building a complex enterprise application where flexibility \& modularity are necessary.
    \item   You have a team experiences in managing detailed configurations.
\end{itemize}

Choose Spring Boot when:
\begin{itemize}
    \item   You're building microservices or need quick iterations in development.
    \item   You want an all-in-one solution with auto-configuration.
    \item   Your focus is on simplicity \& speed without worrying about configuration details.
\end{itemize}

\begin{table}[h!]
    \centering

    \begin{tabular}{|>{\arraybackslash}p{0.5\textwidth}|>{\arraybackslash}p{0.5\textwidth}|}
        \hline
        \textbf{Spring}                                                     & \textbf{Spring Boot} \\
        \hline
        Framework for building complex enterprise-level Java applications   & Simplified framework to quickly build microservices or standalone apps \\
        \hline
        Slower to set up due to configuration                               & Faster development with minimal setup \\
        \hline
        Provides maximum flexibility \& customisation                       & Less flexibility, focuses on ease of use \\
        \hline
        Suitable for large-scale, complex, highly customised apps           & Suitable for small/medium projects, microservices, \& rapid development \\
        \hline
    \end{tabular}
    \caption{High-Level Differences between Spring \& Spring Boot}
\end{table}

\subsection{GitHub Actions}
\textbf{GitHub Actions} automates your workflow by triggering events such as \verb|push|, \verb|pull_request|, \&
\verb|release|.
It easily integrates with other tools like Docker, AWS, Heroku, etc.
Key components of GitHub Actions include:
\begin{itemize}
    \item   \textbf{Workflows} are defined in YAML in the \verb|.github/workflows/| folder and are triggered by events such 
            as \verb|push|, \verb|pull_request|, etc.
    \item   \textbf{Jobs} define units of work that run on a \textbf{runner} (e.g., \verb|ubuntu_latest|,
            \verb|macos-latest|).
            They can be run sequentially or in parallel.
    \item   Each job consists of a series of \textbf{steps}, e.g., checking out the code, building, testing, etc.
    \item   \textbf{Runners} include GitHub-hosted runners (e.g., Ubuntu, macOS) but you can also have self-hosted runners 
            to run on your own infrastructure.
    \item   \textbf{GitHub Secrets} can be used to securely store sensitive information (e.g., API keys) and are accessible 
            in workflows as \mintinline{yaml}{secrets.MY_SECRET_KEY}.
\end{itemize}

\textbf{Composite actions} can be used to define reusable workflows.

\section{Containerisation}
\textbf{Containerisation} is a method of packaging software \& all of its dependencies so that it can run
uniformly \& consistently across any infrastructure.
Containers are isolated environments in which applications run, ensuring consistent behaviour across different
environments (e.g., development, testing, production).

\begin{figure}[H]
    \centering \includegraphics[width=\textwidth]{images/containers_vs_vms.png}
    \caption{Virtual Machines vs Containers }
\end{figure}

Containers virtualise the operating system, while virtual machines virtualise the hardware.
Containers share the OS kernel but isolate the application \& its dependencies.

\begin{table}[h!]
    \centering

    \begin{tabular}{|>{\arraybackslash}p{0.5\textwidth}|>{\arraybackslash}p{0.5\textwidth}|}
        \hline
        \textbf{Virtual Machines}                                           & \textbf{Containers} \\
        \hline
        Heavy \& resource-intensive                                         & Lightweight, share the OS kernel \\
        \hline
        Requires an entire OS for each VM                                   & Faster startup, less overhead \\
        \hline
        Slower startup \& resource usage                                    & More efficient resource usage\\
        \hline
    \end{tabular}
    \caption{Virtual Machines vs Containers}
\end{table}

Reasons for using containerisation include:
\begin{itemize}
    \item   \textbf{Portability:} containers ensure that applications run the same regardless of the environment.
    \item   \textbf{Scalability:} containers can be scaled easily, making them ideal for microservice architectures.
    \item   \textbf{Efficiency:} containers are lightweight and use fewer resources than traditional VMs.
    \item   \textbf{Isolation:} each container is isolated, meaning multiple containers can run on the same host
            without interference.
    \item   \textbf{Faster deployment:} containers can be started in seconds, enabling fast deployments \& rollbacks.
\end{itemize}

\subsection{Docker}
\textbf{Docker} is an open-source platform for building, deploying, \& managing containerised applications.
It simplifies container creation \& management, and provides a consistent environment for development, testing, \&
production.
Advantages of using Docker include:
\begin{itemize}
    \item   \textbf{Consistency across environments:} Docker ensures that the application runs the same regardless
            of where it's deployed.
            Eliminates the ``works on my machine'' problem by providing a consistent environment across all 
            stages of development.
    \item   \textbf{Isolation:} containers provide process isolation, so multiple applications or microservices can
            run side-by-side without interfering with each other.
    \item   \textbf{Scalability:} containers are lightweight and can be easily scaled horizontally (i.e., 
            replicating containers to handle more traffic).
    \item   \textbf{Efficiency:} compared to virtual machines, containers use fewer resources since they share
            the host machine's kernel, making them much faster to start and stop.
    \item   \textbf{Portability:} applications packaged in Docker containers can be easily moved across
            environments, cloud platforms, \& OSes, ensuring smooth \& reliable deployments.
    \item   \textbf{Easy integration:} seamlessly integrates with CI/CD tools \& workflows.
\end{itemize}

Key terms in Docker include:
\begin{itemize}
    \item   \textbf{Image:} a lightweight, standalone, executable package that includes everything an application 
            needs (code, runtime, libraries, dependencies).
    \item   \textbf{Container:} a runtime instance of an image.
            While images are static, containers are dynamic and can be started, stopped, or moved across environments.
    \item   \textbf{Dockerfile:} a text file with instructions to build a docker image.
            It defines the steps to configure an environment, install dependencies, and set up the application.
    \item   \textbf{Docker Hub:} a cloud-based repository for finding \& sharing container images, both public \&
            private.
\end{itemize}

\begin{figure}[H]
    \centering \includegraphics[width=\textwidth]{images/docker_overview.png}
    \caption{Docker Architecture Overview}
\end{figure}

Key Docker components include:
\begin{itemize}
    \item   \textbf{Docker Engine:} the runtime that runs \& manages containers.
    \item   \textbf{Docker Hub:} a public repository where users can publish \& share container images.
    \item   \textbf{Dockerfile:} a text files that contains instructions on how to build a Docker image.
\end{itemize}

\subsubsection{Building \& Running Applications in Docker Containers}
The dockerfile structure is as follows:
\begin{itemize}
    \item   \mintinline{dockerfile}{FROM}: the base image (e.g., \verb|openjdk:17| for Java applications).
    \item   \mintinline{dockerfile}{WORKDIR}: the directory inside the container where the application will reside.
    \item   \mintinline{dockerfile}{COPY}: copies files from the host system into the container.
    \item   \mintinline{dockerfile}{RUN}: executes commands (e.g., installing dependencies).
    \item   \mintinline{dockerfile}{CMD}: defines the default command to run when the container starts (e.g., 
            \mintinline{shell}{java -jar app.jar}).
\end{itemize}

\begin{code}
\begin{minted}[linenos, breaklines, frame=single]{dockerfile}
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/musicFinder-1.0 jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
\end{minted}
\caption{Example Dockerfile for a Spring Boot Application}
\end{code}

To build the Docker image from the Dockerfile:
\begin{minted}[linenos, breaklines, frame=single]{shell}
docker build -t my-app .
\end{minted}

The Docker container can then be run, mapping the container's port 8080 to the host's port 8080:
\begin{minted}[linenos, breaklines, frame=single]{shell}
docker run -p 8080:8080 my-app
\end{minted}

\subsubsection{Docker Best Practices}
\begin{itemize}
    \item   \textbf{Keep images lightweight:} use minimal base images (e.g., \verb|alpine|) to reduce the size of 
            the final image, leading to faster build times \& fewer security vulnerabilities.
    \item   \textbf{Multi-stage builds:} separate the build environment from the final image to reduce size \&
            improve performance.
            \begin{minted}[linenos, breaklines, frame=single]{dockerfile}
FROM maven:3.8-jdk-11 AS builder
WORKDIR /build
COPY . .
RUN mvn clean package

FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /build/target/app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
            \end{minted}

    \item   \textbf{Use \texttt{.dockerignore}:} similar to \verb|.gitignore|, it prevents unnecessary files from
            being copied into the container, optimising build times.

    \item   \textbf{Tagging:} tag your images \mintinline{shell}{docker build -t my-app:v1} for version control \&
            easier management of deployments.

    \item   Security best practices include:
            \begin{itemize}
                \item   Regularly update base images to avoid security vulnerabilities.
                \item   Avoid running containers as root.
                \item   Scan your Docker images for vulnerabilities using tools like Clair or Anchore.
            \end{itemize}
\end{itemize}

\subsubsection{Common Docker Commands}
\begin{itemize}
    \item   Listing containers:
            \begin{itemize}
                \item   \mintinline{shell}{docker ps}: list running containers.
                \item   \mintinline{shell}{docker ps -a}: list all containers, including stopped ones.
            \end{itemize}

    \item   Stopping / removing containers:
            \begin{itemize}
                \item   \mintinline{shell}{docker stop container_id}: stops a running container.
                \item   \mintinline{shell}{docker rm container_id}: removes a stopped container.
            \end{itemize}

    \item   Viewing logs:
            \begin{itemize}
                \item   \mintinline{shell}{docker logs container_id}: shows the logs of a container.
            \end{itemize}

    \item   Entering a running container:
            \begin{itemize}
                \item   \mintinline{shell}{docker exec -it container_id /bin/bash}: opens a shell inside the running
                        container.
            \end{itemize}
\end{itemize}

\begin{figure}[H]
    \centering \includegraphics[width=\textwidth]{images/common_docker_cmds.png}
    \caption{Some Common Docker Commands}
\end{figure}

\subsubsection{Practical Docker Example with Spring Boot}
Prerequisites:
\begin{itemize}
    \item   Java 17 SDK.
    \item   Docker (running).
    \item   Maven.
    \item   Sprint Boot CLI (Optional, but useful for scaffolding projects).
\end{itemize}

\begin{enumerate}
    \item   Initialise a Spring Boot project with Maven using Spring Initializr to generate the project structure.
    \item   Create the Song Suggester Logic in \verb|src/main/java/com/example/songsuggester/SongSuggesterController.java|:
            \begin{minted}[linenos, breaklines, frame=single]{dockerfile}
package com.example.songsuggester;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.json.JSONObject;
import java.util.Random;

@RestController
public class SongSuggesterController {
    @GetMapping("/suggest")
    public String suggestSong() {
        String apiUrl = "https://itunes.apple.com/search?term=pop&limit=10";
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(apiUrl, String.class);

        // Parse the JSON response
        JSONObject jsonObject = new JSONObject(result);
        var tracks = jsonObject.getJSONArray("results");

        // Randomize the selection
        Random rand = new Random();
        int randomIndex = rand.nextInt(tracks.length());
        var randomTrack = tracks.getJSONObject(randomIndex);

        // Extract the song and artist name
        String song = randomTrack.getString("trackName");
        String artist = randomTrack.getString("artistName");

        return "Today's song suggestion: " + song + " by " + artist;
    }
}
            \end{minted}

    \item   Build and run the Spring Boot application:
            \begin{enumerate}[label=\roman*.]
                \item   Navigate to the project folder.
                \item   Run the Maven build command:
                        \begin{minted}[linenos, breaklines, frame=single]{dockerfile}
mvn clean install
                        \end{minted}
                \item   Start the Spring Boot application:
                        \begin{minted}[linenos, breaklines, frame=single]{dockerfile}
mvn spring-boot:run
                        \end{minted}
                \item   Access the application by navigating to \url{http://localhost:8080/suggest} in your browser.
            \end{enumerate}

            \item   In the root of your project directory, create a Dockerfile:
                    \begin{minted}[linenos, breaklines, frame=single]{dockerfile}
# Use an official OpenJDK runtime as a parent image
FROM openjdk:17-jdk-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the project JAR file into the container
COPY target/song-suggester-0.0.1-SNAPSHOT.jar app.jar

# Expose the port the app runs on
EXPOSE 8080

# Run the JAR file
ENTRYPOINT ["java", "-jar", "app.jar"]
                    \end{minted}

    \item   Build the Docker image from the Dockerfile:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
docker build -t song-suggester .
            \end{minted}

    \item   Run the Docker container:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
docker run -p 8080:8080 song-suggester
            \end{minted}
\end{enumerate}

\subsection{Container Orchestration}
\textbf{Container orchestration} automates the management, deployment, scaling, \& networking of containers.
It's crucial when dealing with a large number of containers running across multiple environments because as the
number of containers grows, manually managing them becomes unfeasible.
\\\\
Key components of container orchestration include:
\begin{itemize}
    \item   \textbf{Scheduling:} automatically assigns containers to hots machines based on resource availability.
    \item   \textbf{Scaling:} dynamically adds or removes containers based on demand.
    \item   \textbf{Networking:} manages the communication between containers and ensures that they can interact
            securely.
    \item   \textbf{Load balancing:} distributes traffic across multiple containers to optimise resource usage.
    \item   \textbf{Service discovery:} automatically detects and connects services running in different containers.
\end{itemize}

Orchestration benefits DevOps in the following ways:
\begin{itemize}
    \item   \textbf{Automation:} simplifies repetitive tasks such as deployment, scaling, \& rollback.
    \item   \textbf{High availability:} distributes workloads across different machines, ensuring that services
            remain available.
    \item   \textbf{Fault tolerance:} automatically restarts or replaces failed containers and reroutes traffic
            to healthy containers.
    \item   \textbf{Scalability:} orchestrators can dynamically scale the number of running containers to handle
            increased traffic.
\end{itemize}

Challenges with container orchestration include:
\begin{itemize}
    \item   \textbf{Complexity:} orchestration platforms can introduce signification complexity, especially for
            small teams.
    \item   \textbf{Learning curve:} tools like Kubernetes have a steep learning curve for new users.
    \item   \textbf{Resource overhead:} orchestrators can consume considerable resources, particularly when
            managing large-scale systems.
    \item   \textbf{Networking:} configuring secure \& reliable networking between containers can be challenging.
\end{itemize}

Popular container orchestration tools include:
\begin{itemize}
    \item   \textbf{Kubernetes:}
            \begin{itemize}
                \item   Most widely used container orchestration platform.
                \item   Manages containerised application across clusters of machines.
                \item   Handles self-healing, automated rollouts, \& scaling.
            \end{itemize}
    \item   \textbf{Docker Swarm:}
            \begin{itemize}
                \item   Built-in Docker tool for orchestration.
                \item   Easier to set up but less feature-rich than Kubernetes.
                \item   Ideal for smaller setups with Docker-native capabilities.
            \end{itemize}
    \item   \textbf{Apache Mesos:}
            \begin{itemize}
                \item   General-purpose distributed systems platform that supports container orchestration.
                \item   Suitable for large-scale environments requiring both container \& non-container workloads.
            \end{itemize}
\end{itemize}

\subsubsection{Kubernetes}
The Kubernetes architecture consists of a master node \& worker nodes:
\begin{itemize}
    \item   \textbf{Master Node:} manages the Kubernetes cluster.
            \begin{itemize}
                \item   \textbf{API Server:} entry point for REST operations.
                \item   \textbf{Scheduler:} assigns containers to nodes.
                \item   \textbf{Controller Manager:} ensures the desired state of the system.
            \end{itemize}
    \item   \textbf{Worker Nodes:} hosts running containerised applications.
            \begin{itemize}
                \item   \textbf{Kubelet:} ensures containers are running on a node.
                \item   \textbf{Pod:} smallest deployable unit consisting of one or more containers, with shared
                        storage \& network resources.
                \item   \textbf{Kube-Proxy:} handles networking within Kubernetes.
            \end{itemize}
\end{itemize}

Key Kubernetes concepts include:
\begin{itemize}
    \item   \textbf{Service:} an abstraction that defines a logical set of pods \& a policy for accessing them.
    \item   \textbf{Deployment:} manages pod scaling \& rolling updates for your application.
    \item   \textbf{Namespace:} provides scope for resources within a Kubernetes cluster, helping organise \& 
            manage resources.
\end{itemize}

The steps to run Kubernetes locally are as follows:
\begin{enumerate}
    \item   \textbf{Install Minikube:} Minikube allows you to run Kubernetes on a single node.
            \begin{minted}[linenos, breaklines, frame=single]{shell}
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
\end{minted}
    \item   Install \verb|kubectl|:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
            \end{minted}
            Verify the installation by running \mintinline{shell}{kubectl version}.
    \item   Running Kubernetes:
            \begin{itemize}
                \item   Use the following commands to start interacting with your Kubernetes cluster:
                \begin{minted}[linenos, breaklines, frame=single]{shell}
kubectl cluster-info
kubectl get nodes
                \end{minted}
                You can deploy containers \& pods using:
                \begin{minted}[linenos, breaklines, frame=single]{shell}
kubectl apply -f <your-deployment-file>.yaml
                \end{minted}
            \end{itemize}
    \item   Manage Kubernetes with Helm (optional):
            \begin{itemize}
                \item   \textbf{Helm} is a package manager for Kubernetes that makes deployment easier.
                \item   To install Helm:
                        \begin{minted}[linenos, breaklines, frame=single]{shell}
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
                        \end{minted}
                \item   You can then start deploying applications using Helm Charts.
            \end{itemize}
\end{enumerate}

To deploy the \verb|song-suggester| app with Kubernetes:
\begin{enumerate}
    \item   Create a Docker image for the \verb|suggest-music| app:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
docker build -t song-suggester .
            \end{minted}
    \item   Deploy the Docker container in a Kubernetes pod:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
kubectl create deployment song-suggester --image=song-suggester
            \end{minted}
    \item   Expose the app using a service to make it accessible outside the Kubernetes cluster:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
kubectl expose deployment song-suggester -type=LoadBalancer -- port=8080
            \end{minted}
    \item   Scale the application to run multiple instances:
            \begin{minted}[linenos, breaklines, frame=single]{shell}
kubectl scale deployment song-suggester --replicas=5
            \end{minted}
\end{enumerate}


\end{document}
