spark在服务器运行示例_创建示例HTTPS服务器以获取乐趣和收益
spark在服務(wù)器運(yùn)行示例
通常,在開發(fā)或/和針對真實(shí)場景進(jìn)行測試期間,我們(開發(fā)人員)面臨著運(yùn)行成熟的HTTPS服務(wù)器的需求,可能同時進(jìn)行一些模擬。 在JVM平臺上,除非您知道適合此工作的正確工具,否則它過去并不是一件容易的事。 在這篇文章中,我們將使用出色的Spray框架和Scala語言創(chuàng)建一個完全可操作的HTTPS服務(wù)器的框架。
首先,我們需要分別生成x509證書和私鑰。 幸運(yùn)的是,使用openssl命令行工具非常容易。
openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes正如我們在JVM平臺上一樣,我們的基本目標(biāo)是擁有Java密鑰庫 ( JKS ),這是安全證書的存儲庫。 但是,要將我們新生成的證書導(dǎo)入JKS ,我們必須以PKCS#12格式導(dǎo)出它,然后從中創(chuàng)建密鑰庫。 同樣,在resque上使用openssl 。
openssl pkcs12 -export -in certificate.crt -inkey certificate.key -out server.p12 -name sample-https-server -password pass:change-me-please請注意,存檔服務(wù)器.p12受密碼保護(hù)。 現(xiàn)在,最后一步涉及JDK發(fā)行版中的命令行工具keytool 。
keytool -importkeystore -srcstorepass change-me-please -destkeystore sample-https-server.jks -deststorepass change-me-please -srckeystore server.p12 -srcstoretype PKCS12 -alias sample-https-server結(jié)果是受密碼保護(hù)的sample-https-server.jks密鑰庫,我們可以在HTTPS服務(wù)器應(yīng)用程序中使用它來配置SSL上下文。 Spray有非常好的文檔和大量示例,其中一個示例SslConfiguration ,我們可以用來配置KeyManager , TrustManager和SSLContext 。
trait SslConfiguration {// If there is no SSLContext in scope implicitly, the default SSLContext is // going to be used. But we want non-default settings so we are making // custom SSLContext available here.implicit def sslContext: SSLContext = {val keyStoreResource = "/sample-https-server.jks"val password = "change-me-please"val keyStore = KeyStore.getInstance("jks")keyStore.load(getClass.getResourceAsStream(keyStoreResource), password.toCharArray)val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")keyManagerFactory.init(keyStore, password.toCharArray)val trustManagerFactory = TrustManagerFactory.getInstance("SunX509")trustManagerFactory.init(keyStore)val context = SSLContext.getInstance("TLS")context.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, new SecureRandom)context}// If there is no ServerSSLEngineProvider in scope implicitly, // the default one is going to be used. But we would like to configure// cipher suites and protocols so we are making a custom ServerSSLEngineProvider// available here.implicit def sslEngineProvider: ServerSSLEngineProvider = {ServerSSLEngineProvider { engine =>engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_128_CBC_SHA"))engine.setEnabledProtocols(Array( "TLSv1", "TLSv1.1", "TLSv1.2" ))engine}} }這里有幾點(diǎn)要強(qiáng)調(diào)。 首先,使用以前創(chuàng)建的我們自己的密鑰庫(為方便起見,我們將其存儲為類路徑資源):
val keyStoreResource = "/sample-https-server.jks" val password = "change-me-please"另外,我們僅配置TLS ( TLS v1.0 , TLS v1.1和TLS v1.2 ),不支持SSLv3 。 除此之外,我們僅啟用一種密碼: TLS_RSA_WITH_AES_128_CBC_SHA 。 這樣做主要是為了說明,因?yàn)樵诖蠖鄶?shù)情況下,可以啟用所有受支持的密碼。
engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_128_CBC_SHA")) engine.setEnabledProtocols(Array( "TLSv1", "TLSv1.1", "TLSv1.2" ))這樣,我們就可以創(chuàng)建一個真正的HTTPS服務(wù)器了,這要?dú)w功于Spray框架只有幾行:
class HttpsServer(val route: Route = RestService.defaultRoute) extends SslConfiguration {implicit val system = ActorSystem()implicit val timeout: Timeout = 3 seconds val settings = ServerSettings(system).copy(sslEncryption = true)val handler = system.actorOf(Props(new RestService(route)), name = "handler")def start(port: Int) = Await.ready(IO(Http) ? Http.Bind(handler, interface = "localhost", port = port, settings = Some(settings)), timeout.duration)def stop() = {IO(Http) ? Http.CloseAllsystem.stop(handler)} }任何根本不執(zhí)行任何操作的HTTPS服務(wù)器不是很有用。 這就是路由屬性發(fā)揮作用的地方:使用Spray路由擴(kuò)展,我們將映射(或路由)傳遞給HTTP服務(wù)參與者 ( RestService )直接處理請求。
class RestService(val route: Route) extends HttpServiceActor with ActorLogging {def receive = runRoute {route} }使用默認(rèn)路由就是:
object RestService {val defaultRoute = path("") {get {complete {"OK!\n"}}} }基本上,這就是我們所需要的,我們的HTTPS服務(wù)器已準(zhǔn)備好進(jìn)行測試! 運(yùn)行它的最簡單方法是使用Scala應(yīng)用程序。
object HttpsServer extends App {val server = new HttpsServerserver.start(10999) }盡管是用Scala編寫的,但我們可以輕松地將其嵌入到任何Java應(yīng)用程序中(對于Java開發(fā)人員來說,使用一些非標(biāo)準(zhǔn)的命名約定),例如:
public class HttpsServerRunner {public static void main(String[] args) {final HttpsServer server = new HttpsServer(RestService$.MODULE$.defaultRoute());server.start(10999);} }一旦啟動并運(yùn)行(最簡單的方法是sbt run ),就可以從瀏覽器或使用curl命令行客戶端訪問我們簡單的HTTPS服務(wù)器的公開默認(rèn)路由( -k命令行參數(shù)關(guān)閉SSL證書驗(yàn)證) :
$ curl -ki https://localhost:10999HTTP/1.1 200 OK Server: spray-can/1.3.3 Date: Sun, 04 Oct 2015 01:25:47 GMT Content-Type: text/plain; charset=UTF-8 Content-Length: 4OK!或者,可以將證書與curl命令一起傳遞,以便進(jìn)行完整的SSL證書驗(yàn)證,例如:
$ curl -i --cacert src/main/resources/certificate.crt https://localhost:10999HTTP/1.1 200 OK Server: spray-can/1.3.3 Date: Sun, 04 Oct 2015 01:28:05 GMT Content-Type: text/plain; charset=UTF-8 Content-Length: 4OK!一切看起來不錯,但是我們可以使用HTTPS服務(wù)器作為集成測試套件的一部分來驗(yàn)證/存根/模擬,例如,與第三方服務(wù)的交互嗎? 答案是肯定的,這要?dú)w功于JUnit規(guī)則。 讓我們看一下HttpsServerRule的最簡單實(shí)現(xiàn):
class HttpsServerRule(@BeanProperty val port: Int, val route: Route) extends ExternalResource {val server = new HttpsServer(route)override def before() = server.start(port)override def after() = server.stop() }object HttpsServerRule {def apply(port: Int) = new HttpsServerRule(port, RestService.defaultRoute);def apply(port: Int, route: Route) = new HttpsServerRule(port, route); }我們默認(rèn)實(shí)現(xiàn)的JUnit測試用例使用了出色的RestAssured庫,該庫提供了Java DSL,可輕松測試REST服務(wù)。
public class DefaultRestServiceTest {@Rule public HttpsServerRule server = HttpsServerRule$.MODULE$.apply(65200);@Testpublic void testServerIsUpAndRunning() {given().baseUri("https://localhost:" + server.getPort()).auth().certificate("/sample-https-server.jks", "change-me-please").when().get("/").then().body(containsString("OK!"));} }可以肯定的是,您無法對默認(rèn)實(shí)現(xiàn)執(zhí)行任何操作,因此提供自定義選項(xiàng)是必須的選擇。 幸運(yùn)的是,我們很早就通過接受路線來解決了這一問題。
object CustomRestService {val route = path("api" / "user" / IntNumber) { id =>get {complete {"a@b.com"}}} }這是一個測試用例:
public class CustomRestServiceTest {@Rule public HttpsServerRule server = HttpsServerRule$.MODULE$.apply(65201, CustomRestService$.MODULE$.route());@Testpublic void testServerIsUpAndRunning() {given().baseUri("https://localhost:" + server.getPort()).auth().certificate("/sample-https-server.jks", "change-me-please").when().get("/api/user/1").then().body(containsString("a@b.com"));} }事實(shí)證明,創(chuàng)建完整的HTTPS服務(wù)器一點(diǎn)也不難,而且一旦您知道執(zhí)行此操作的正確工具,它就會變得非常有趣。 Spray框架是那些魔術(shù)工具之一。 你們中許多人都知道, Spray將被Akka HTTP取代, Akka HTTP最近已經(jīng)發(fā)布了1.0版本,但目前缺乏很多功能(包括HTTPS支持),這使Spray作為可行的選擇。
- 完整的項(xiàng)目可以在Github上找到 。
翻譯自: https://www.javacodegeeks.com/2015/10/creating-sample-https-server-for-fun-and-profit.html
spark在服務(wù)器運(yùn)行示例
總結(jié)
以上是生活随笔為你收集整理的spark在服务器运行示例_创建示例HTTPS服务器以获取乐趣和收益的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jboss eap 7_EAP 7 Al
- 下一篇: bios设置图解教程电脑如何bios