TDP024 Enterprise Systems
Ht1 2024
# Byggsystem - Lab 2
Att använda ett system för att underlätta byggandet av mjukvara är väldigt användbart.
Ett av de mest populära verktygen för detta är Maven.
Med Maven kan man man göra byggprocessen mycket enklare, hålla koll på beroenden, garantera att alla bygger produkten på samma sätt, köra tester samt generera dokumentation.
I laborationen ska ni se hur man använder Maven genom att bygga upp ett projekt.
Maven är skapat med Java i åtanke, men liksom med de flesta andra byggsystem kan man även bygga andra språk.
Mycket av det som Maven gör handlar om att exekvera plugins och genom dessa kan man även integrera flera språk i byggprocessen.
## Dokumentation
- Bra överblick över maven: [http://jenkov.com/tutorials/maven/maven-tutorial.html](http://jenkov.com/tutorials/maven/maven-tutorial.html)
- Build Lifecycle: [https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
- Utveckla plugins: [https://maven.apache.org/guides/plugin/guide-java-plugin-development.html](https://maven.apache.org/guides/plugin/guide-java-plugin-development.html)
- Hantera flera moduler: [http://books.sonatype.com/mvnex-book/reference/multimodule.html](http://books.sonatype.com/mvnex-book/reference/multimodule.html)
- För att köra maven/mvn i SU-salar och thinlinc kör:
module add prog/maven/2.8.2
## Uppgift
Ni ska nu använda maven för att bygga ett system, hantera beroenden, utveckla en plugin samt konfigurera systemet för olika miljöer.
Ifall ni redan har ett befintligt projekt så får ni gärna använda det, så länge det går att använda för att uppnå laborationskraven.
Ifall ni inte har ett passande projekt kan ni använda er den koden som vi ger er, det finns en java-klient och en go-server.
Servern hittar ni här: [git@gitlab.liu.se:large-scale-dev/ci-sample-project.git](git@gitlab.liu.se:large-scale-dev/ci-sample-project.git).
Koden för javaprojektet är given längre ner, men ni kommer att få skapa mapp-strukturen själva.
Använder ni java-klienten kommer ni behöva starta go-serveren för att kunna köra alla tester, dock behöver inte go-servern vara del av ert Maven-projekt.
Hur man bygger go-koden kan ni se i projektets README.md.
För att bygga något i Maven är det smidigast att använda sig av en plugin.
En som fungerar bra att använda är: [https://github.com/raydac/mvn-golang](https://github.com/raydac/mvn-golang).
Man kan även åstadkomma detta genom att exekvera shell-skript från maven, eller utveckla en egen plugin.
### Krav på systemet
För detta projekt ska ni nu skriva en mavenkonfiguration som uppfyller följande krav:
- Huvudprojektet som ni ska strukturera ska ha minst en module.
Om ni använder er egen kod får ni strukturera upp detta som ni själva vill.
Använder ni koden som vi tillhandahåller så kan servern och klienten vara två separata moduler (dock inget krav).
Huvudprojektet ska vara förälder till de(n) module(rna).
- Genom att köra `mvn package` ska systemet bygga och packetera koden.
För javakod ska detta innebära att t.ex. skapa en jar-fil.
För andra språk får ni själva avgöra vad som är bäst, för go kan ni exempelvis skapa en binär.
- Ifall man kör `mvn test` ska enhetstesten för alla moduler köras.
- Alla beroenden ska hanteras i pom-filerna.
Genom att använda maven för att hantera beroenden slipper du själv se till att alltid ha rätt version nedladdad.
- Genom att köra `mvn verify` ska man köra integrationstester.
Har ni en server i projektet så ska den startas innan testet, och avslutas efter.
-
### För högre betyg
Mycket av maven kretsar kring just plugins, så nu ska ni se själva utveckla en plugin för att se hur detta fungerar.
Er plugin ska användas i compile-fasen.
- Er plugin behöver endast bestå av en Mojo.
- Den ska ta in ett filnamn som parameter.
- Ni ska utföra någon operation med hjälp av denna filen. T.ex. läsa in den, exekvera den eller skriva till den.
### Redovisning
Uppgiften redovisas genom att demonstrera för en assistent och förklarar de olika aspekterna av ditt ihopsatta ci-system och visar hur det fungerar som helhet.
Demonstrera hur du har strukturerat projektet, och varje del i din POM.
### Kod
Observera att TimeRetriever och TimeRetrieverTest har dependencies som måste hanteras.
_HelloMaven.java_:
package se.liu.ida.hello;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
public class HelloMaven {
public static void main(String[] args) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet( "http://localhost:8080/list");
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed: status code 200 != " + response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
httpClient.getConnectionManager().shutdown();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
_TimeRetriever.java_:
package se.liu.ida.hello;
import org.joda.time.LocalTime;
import org.apache.log4j.Logger;
public class TimeRetriever {
public static String getTimeMessage() {
Logger logger = Logger.getLogger(HelloMaven.class);
LocalTime localTime = new LocalTime();
logger.info("Requested time string: " + localTime.toString());
return "TODO list: " + localTime.toString();
}
}
_TimeRetrieverTest.java_:
package se.liu.ida.hello;
import static org.junit.Assert.*;
import junit.framework.TestCase;
import org.joda.time.LocalTime;
public class TimeRetrieverTest extends TestCase {
public TimeRetrieverTest(String name) {
super(name);
}
public void testTimeRetriever() throws Exception {
LocalTime before = new LocalTime();
String testString = "TODO list: " + before.toString();
String actualString = TimeRetriever.getTimeMessage();
assertTrue(testString.compareTo(actualString) <= 0);
}
}
_StatusIT.java_:
package se.liu.ida.hello;
import static org.junit.Assert.*;
import junit.framework.TestCase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
public class StatusIT extends TestCase {
private static String serverURL = "http://localhost:8080/list";
public StatusIT(String name) {
super(name);
}
public void testStatusCode() throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(serverURL);
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
assertTrue(response.getStatusLine().getStatusCode() == 200);
}
}
Mainfunktionen ligger alltså i klassen _HelloMaven_.
Den använder sig av _TimeRetriever.java_
_TimeRetrieverTest.java_ testar TimeRetriever klassen.
_StatusIT.java_ kör ett integrationstest mot servern.
### Resources
Konfigurationsfilen för log4j kan ses nedan.
Raden `log4j.appender.R.File=logs/dev.log` kommer behöva ändras för att profilerna ska kunna välja logfil (högre betyg).
_log4j.properties_:
log4j.rootLogger=DEBUG, R
log4j.appender.R=org.apache.log4j.FileAppender
log4j.appender.R.File=logs/dev.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Sidansvarig: Anders Fröberg
Senast uppdaterad: 2021-08-23