The following tutorial will demo how to write a simple web application using spring mvc and thymeleaf and read the jenkin job rss feed and how to include the certificate.
Spring mvc maven project
Run the following command on your project workspace, and select the plugin project number from the console. In my case i’m enter 39 for Thymeleaf Spring Maven Archetype project.
C:workspace> mvn archetype:generate -DgroupId=com.mingch.jenkin
POM
Add the following dependencies into your pom.xml
<!– RSS –> <dependency> <groupId>rome</groupId> <artifactId>rome</artifactId> <version>1.0</version> </dependency>
RSS Service
I’m going to create a interface that implement a method called getFeed().
public interface RssService {
public String getFeed();
}
Next, create the implementation
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
@Service
public class RssServiceImpl implements RssService {
private URL url = null;
private XmlReader xmlReader = null;
@Override
public String getFeed() {
return getRSS("https://your.jenkin.com/jenkins/view/Sample/job/buildAutomation/rssAll");
}
private String getRSS(String jengkinURL) {
String status = null;
try {
url = new URL(jengkinURL);
xmlReader = new XmlReader(url);
SyndFeed feeder = new SyndFeedInput().build(xmlReader);
for (Iterator iterator = feeder.getEntries().iterator();
iterator.hasNext();) {
SyndEntry syndEntry = (SyndEntry) iterator.next();
status = syndEntry.getTitle() + " " + syndEntry.getUpdatedDate();
return status;
}
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(xmlReader!=null){
xmlReader.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
return status;
}
}
Create a controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.com.mingch.jenkin.service.RssService;
@Controller
public class RssParseController {
@Autowired private RssService service;
@RequestMapping(value = "/rss", method = RequestMethod.GET)
public String homeForm(Model model) {
model.addAttribute("message", service.getFeed());
return "index";
}
}
Create a html page
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <title></title> <meta name="description" content="Spring mvc rss demo"/> <meta name="viewport" content="width=device-width,initial-scale=1"/> <link rel="stylesheet" href="../../css/style.css" th:href="@{/css/style.css}"/> <script src="../../js/libs/modernizr-2.0.6.min.js" th:src="@{/js/libs/modernizr-2.0.6.min.js}"></script> </head> <body> <div id="container"> <header> </header> <h1>RSS Feed Result</h1> <p th:text="${message}">This result will be replace</p> <footer> </footer> </div> <!–! end of #container –> <script> /*<![CDATA[*/ //Embbeded Javascript /*]]>*/ </script> </body> </html>
Troubleshooting
Since the jenkin job i have is using https and required certificate install. If run directly will encounter the following error.
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
...
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1319)
... 47 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 53 more
Solution
There are number of solution out there, but i’ll use InstallCert for this article. Let’s assume you’re using eclipse to do the development. Copy the InstallCert into your Eclipse.
Right click the InstallCert.java from your eclipse, run as -> run configuration, select the Argument tab, and from the Program arguments, enter the url and port(optional) Example:
jenkin.mingch.com
Next, save and run it and you should see something in your console and prompt you enter ‘q’ or [1]:
Loading KeyStore C:Program Files (x86)Javajdk1.7.0_01jrelibsecuritycacerts...
Opening connection to jenkin.mingch.com:443...
Starting SSL handshake...
No errors, certificate is already trusted
Server sent 1 certificate(s):
1 Subject EMAILADDRESS=unixadmin@mingch.com, CN=jenkin.mingch.com, OU=IT, O=Mingch, L=Malaysia, ST=Uusimaa, C=FI
Issuer CN=ABCD, DC=Mingch, DC=com
sha1 e4 35 f6 e0 35 ff 68 b2 8a 5d a3 3e 13 a7 aa d6 1a 7c b3 26
md5 ed 09 1b 01 21 a1 eb 97 ec 99 58 a3 be ce 6e cb
Enter certificate to add to trusted keystore or 'q' to quit: [1]
1
[
[
Version: V3
Subject: EMAILADDRESS=unixadmin@mingch.com, CN=jenkin.mingch.com, OU=IT, O=Mingch, L=Malaysia, ST=Uusimaa, C=FI
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 2048 bits
modulus:
296031928721559679517258810240027831904135579618397714513304166376520826022110817004642216963
080481243881401281469959894885206701786521732245991497513049231510629100795993968243090881927408
304764280969987913067715142194243212360731036613503835870683551121486842092549584223796060447496
088831426917570525998140862383089785609022893006995600927719714682169123710809858254012653611037
586220550612750430273492632392736743104499336904658326920627732459493566684887556582571138091211
955580476620899519880993444825206307655002604101771732976349839262679998056565662409451823824346
67680370351417208065633296182200268460130237
public exponent: 65537
Validity: [From: Mon Oct 17 16:36:34 SGT 2011,
To: Wed Oct 16 16:36:34 SGT 2013]
Issuer: CN=ABCD, DC=Mingch, DC=com
SerialNumber: [ 2742efad 00000000 69d6]
Certificate Extensions: 9
[1]: ObjectId: 1.3.6.1.4.1.311.21.10 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 0E 30 0C 30 0A 06 08 2B 06 01 05 05 07 03 01 ..0.0...+.......
[2]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[
accessMethod: caIssuers
accessLocation: URIName: ldap:///CN=ABCD,CN=AIA,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=Mingch,DC=com?cACertificate?base?objectClass=certificationAuthority
,
accessMethod: caIssuers
accessLocation: URIName: http://abcd.mingch.com/CertEnroll/abcd.Mingch_ABCD.crt
]
]
[3]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 6B 7F BE 64 5D 7D 5B 96 AC D4 A1 94 C4 A5 C3 14 k..d].[.........
0010: FA C5 75 8F ..u.
]
]
[4]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4C 1C 36 4B F0 C8 68 57 F5 42 0C CD 13 78 1A CE L.6K..hW.B...x..
0010: A6 F1 78 91 ..x.
]
]
[5]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
[6]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
serverAuth
]
[8]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
DigitalSignature
Key_Encipherment
]
[9]: ObjectId: 1.3.6.1.4.1.311.21.7 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 2F 30 2D 06 25 2B 06 01 04 01 82 37 15 08 E0 ./0-.%+.....7...
0010: BE 59 87 BD 8D 4C 85 81 8F 39 84 B9 FA 03 83 8E .Y...L...9......
0020: A1 32 81 34 86 E1 DB 6B 94 F0 41 02 01 67 02 01 .2.4...k..A..g..
0030: 04 .
]
Algorithm: [SHA1withRSA]
Signature:
0000: 06 FD 8C 0A 24 55 FD C9 34 ED FE B9 46 04 E2 93 ....$U..4...F...
0010: B6 46 8E 5D B4 C8 69 CA 05 E2 2A E8 C9 AD 4A 1F .F.]..i...*...J.
0020: 97 00 94 59 02 6B BC 1B 90 EA C7 48 AF 16 FA A8 ...Y.k.....H....
0030: 0F D5 F0 48 74 97 6A 4C 80 E8 53 22 13 52 2D 26 ...Ht.jL..S".R-&
0040: B4 E6 99 2C E3 0E 89 70 2C A9 DC 16 EC 56 24 B4 ...,...p,....V$.
0050: 9A 29 40 78 F0 A4 65 0F DE 50 B1 81 15 BB D0 DF .)@x..e..P......
0060: B2 C1 88 E9 FC B3 6A 59 6F A6 56 E8 C7 80 49 52 ......jYo.V...IR
0070: 0E 9E F9 22 9F 06 39 88 81 E7 FA F2 9C A9 E0 AB ..."..9.........
0080: 5C 8C 93 B8 20 5C 95 F2 DA 20 FF 07 1F 3D 2E DB ... ... ...=..
0090: 4A 59 E7 99 40 43 08 9F 9C FB 06 71 02 44 0D B4 JY..@C.....q.D..
00A0: B5 DF 69 22 27 DD 59 2E B7 E3 00 A4 A8 5B F2 CF ..i"'.Y......[..
00B0: 6C 93 C8 21 5C 00 57 B3 80 8E F6 BE AB A3 99 F3 l..!.W.........
00C0: E6 EA 02 60 60 01 37 54 B6 F7 89 39 2D AA 0A AA ...``.7T...9-...
00D0: 33 16 7F B5 FC 3B 29 35 87 8E 34 85 48 F7 71 66 3....;)5..4.H.qf
00E0: 8C BC 8F 19 C6 7B EA BC 89 46 05 B7 8F 53 57 F8 .........F...SW.
00F0: 6D A8 FE 33 F0 70 AC 53 B1 BC E7 BA 2F 6E 73 D9 m..3.p.S..../ns.
]
Added certificate to keystore 'jssecacerts' using alias 'jenkin.mingch.com-1'
Finally
When you had reach this stage, there is a file called jssecacerts will created under your project. You need to copy this file and put under your [java_home]/jre/lib/security folder. Re-run your application again you should success at this time.