Quick way to check if the REST API is alive – GET details from Manifest file
There might be cases when you want to quickly verify if your REST API, that is deployed either on dev, test or prod environments, is reachable altogether. A common way to do this is by building a generic resource that delivers for example the version of the deployed API. You can trigger a request to this resource manually or, even better, have a Jenkings/Hudson job, which runs a checkup job after deployment. In this post, I will present how to implement such a service that reads the implementation details from the application’s manifest file. The API verified, is the one developed in the Tutorial – REST API design and implementation in Java with Jersey and Spring
Software used
- Jersey JAX-RS implementation 2.14
- Spring 4.1.4
- Maven 3.1.1
- JDK 7
REST resource
I have developed two REST resources reading from the Manifest file :
- /manifest – returns the manifest’s main attributes as a key, value pairs
- /manifest/implementation-details – returns only the implementation details from the manifest file
Manifest REST resource
@Path("/manifest") public class ManifestResource { @Autowired ManifestService manifestService; @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getManifestAttributes() throws FileNotFoundException, IOException{ Attributes manifestAttributes = manifestService.getManifestAttributes(); return Response.status(Response.Status.OK) .entity(manifestAttributes) .build(); } @Path("/implementation-details") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getVersion() throws FileNotFoundException, IOException{ ImplementationDetails implementationVersion = manifestService.getImplementationVersion(); return Response.status(Response.Status.OK) .entity(implementationVersion) .build(); } }
Request
GET request example – implementation details
GET http://localhost:8888/demo-rest-jersey-spring/manifest HTTP/1.1 Accept-Encoding: gzip,deflate Accept: application/json Host: localhost:8888 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Response – 200 OK
Response in JSON format
{ "Implementation-Title": "DemoRestWS", "Implementation-Version": "0.0.1-SNAPSHOT", "Implementation-Vendor-Id": "org.codingpedia", "Built-By": "ama", "Build-Jdk": "1.7.0_40", "Manifest-Version": "1.0", "Created-By": "Apache Maven 3.1.1", "Specification-Title": "DemoRestWS", "Specification-Version": "0.0.1-SNAPSHOT" }
The returned values in case of success (HTTP Status 200 OK) contain different default data related to implementation and specification details. These are automatically generated the Manifest file with Maven plugin, which I will present in the next section.
Generate Manifest file with Maven
Since the demo application is a web application, I am using the Apache maven war plugin supported by the Apache Maven Archiver to generate a Manifest file:
maven-war-plugin configuration
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.5</version> <configuration> <warName>${project.artifactId}</warName> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>manifest</goal> </goals> <inherited>true</inherited> </execution> </executions> </plugin>
The addDefaultImplementationEntries and addDefaultSpecificationEntries will generate default implementation, respectively specification details, out of the project properties defined in the pom.xml file:
Default implementation details
Implementation-Title: ${project.name} Implementation-Version: ${project.version} Implementation-Vendor-Id: ${project.groupId} Implementation-Vendor: ${project.organization.name} Implementation-URL: ${project.url}
, respectively:
Default specifiation details
Specification-Title: ${project.name} Specification-Version: ${project.version} Specification-Vendor: ${project.organization.name}
See Apache Maven Archiver for further details.
Notice that in order to generate the Manifest.mf file also in the file system under webapp/META-INF, you need to bind the manifest goal to an execution phase (e.g. package):
Bind manifest goal to package phase
<executions> <execution> <phase>package</phase> <goals> <goal>manifest</goal> </goals> <inherited>true</inherited> </execution> </executions>
Read from Manifest file
Reading from the manifest file occurs in the injected ManifestService class:
ManifestService.java
public class ManifestService { @Autowired ServletContext context; Attributes getManifestAttributes() throws FileNotFoundException, IOException{ InputStream resourceAsStream = context.getResourceAsStream("/META-INF/MANIFEST.MF"); Manifest mf = new Manifest(); mf.read(resourceAsStream); Attributes atts = mf.getMainAttributes(); return atts; } ImplementationDetails getImplementationVersion() throws FileNotFoundException, IOException{ String appServerHome = context.getRealPath("/"); File manifestFile = new File(appServerHome, "META-INF/MANIFEST.MF"); Manifest mf = new Manifest(); mf.read(new FileInputStream(manifestFile)); Attributes atts = mf.getMainAttributes(); ImplementationDetails response = new ImplementationDetails(); response.setImplementationTitle(atts.getValue("Implementation-Title")); response.setImplementationVersion(atts.getValue("Implementation-Version")); response.setImplementationVendorId(atts.getValue("Implementation-Vendor-Id")); return response; } }
To access the MANIFEST.MF file you need to inject the ServletContext, and call one of its methods
- SerlvetContext#getResourceAsStream() – (the preferred way)
- ServletContext#getRealPath() – gets the real path corresponding to the given virtual path. The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. Its biggest problem in this case, if you don’t deploy the .war exploded you won’t have access to the manifest file.
Java EE version
In a JavaEE environment, you would have the ServletContext injected via the @Context annotation:
Java EE implementation version
public class ManifestResource { @Context ServletContext context; @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getManifestAttributes() throws FileNotFoundException, IOException{ InputStream resourceAsStream = context.getResourceAsStream("/META-INF/MANIFEST.MF"); Manifest mf = new Manifest(); mf.read(resourceAsStream); Attributes atts = mf.getMainAttributes(); return Response.status(Response.Status.OK) .entity(atts) .build(); } ... }
Here you have – a quick way to verify that your REST api is reachable.
Resources
- Apache Maven
- Oracle docs – Working with Manifest Files: The Basics
- Stackoverflow
Reference: | Quick way to check if the REST API is alive – GET details from Manifest file from our JCG partner Adrian Matei at the Codingpedia.org blog. |