├── .gitignore
├── .netflixoss
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── OSSMETADATA
├── README.md
├── build.gradle
├── buildViaTravis.sh
├── codequality
├── HEADER
└── checkstyle.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
└── Interceptors-Flow.jpg
├── installViaTravis.sh
├── karyon2-admin-plugins
├── karyon-admin-healthcheck-plugin
│ ├── build.gradle
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ ├── com
│ │ │ └── netflix
│ │ │ │ └── adminresources
│ │ │ │ └── HealthcheckResource.java
│ │ │ └── netflix
│ │ │ └── adminresources
│ │ │ └── HealthCheckPlugin.java
│ │ └── test
│ │ ├── java
│ │ └── netflix
│ │ │ └── adminresources
│ │ │ └── HealthCheckResourceTest.java
│ │ └── resources
│ │ └── log4j.properties
├── karyon2-admin-eureka-plugin
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── netflix
│ │ │ └── adminresources
│ │ │ ├── pages
│ │ │ └── EurekaPage.java
│ │ │ └── resources
│ │ │ └── EurekaResource.java
│ │ └── resources
│ │ └── webadmin
│ │ └── eureka
│ │ ├── index.ftl
│ │ └── index.js
└── karyon2-admin-healthcheck-plugin
│ ├── build.gradle
│ └── src
│ ├── main
│ └── java
│ │ └── netflix
│ │ └── adminresources
│ │ ├── HealthCheckPlugin.java
│ │ └── HealthCheckResource.java
│ └── test
│ └── java
│ └── netflix
│ └── adminresources
│ └── HealthCheckResourceTest.java
├── karyon2-admin-web
├── README.md
├── build.gradle
└── src
│ ├── main
│ ├── java
│ │ ├── com
│ │ │ └── google
│ │ │ │ └── inject
│ │ │ │ └── grapher
│ │ │ │ └── KaryonAbstractInjectorGrapher.java
│ │ └── netflix
│ │ │ └── adminresources
│ │ │ ├── pages
│ │ │ ├── AdminPageResource.java
│ │ │ ├── EnvPage.java
│ │ │ ├── GuiceGraphPage.java
│ │ │ ├── GuicePage.java
│ │ │ ├── GuiceProvisionPage.java
│ │ │ ├── JarsPage.java
│ │ │ ├── JmxPage.java
│ │ │ ├── KaryonGrapherModule.java
│ │ │ └── PropertiesPage.java
│ │ │ ├── resources
│ │ │ ├── AllPropsResource.java
│ │ │ ├── EnvironmentResource.java
│ │ │ ├── GuiceResource.java
│ │ │ ├── JarsInfoResource.java
│ │ │ ├── JsonGrapher.java
│ │ │ ├── KaryonAdminResponse.java
│ │ │ ├── KaryonWebAdminModule.java
│ │ │ ├── MaskedResourceHelper.java
│ │ │ ├── PairResponse.java
│ │ │ ├── PropertiesHelper.java
│ │ │ ├── PropertiesResource.java
│ │ │ ├── jmx
│ │ │ │ ├── DynaTreeNode.java
│ │ │ │ ├── JMXResource.java
│ │ │ │ └── JmxService.java
│ │ │ └── model
│ │ │ │ ├── Property.java
│ │ │ │ └── PropertySource.java
│ │ │ └── tableview
│ │ │ ├── DataTableHelper.java
│ │ │ ├── PropsTableView.java
│ │ │ └── TableViewResource.java
│ └── resources
│ │ ├── css
│ │ └── d3.flameGraph.css
│ │ ├── js
│ │ ├── d3.flameGraph.js
│ │ └── d3.tip.js
│ │ └── webadmin
│ │ ├── archprops
│ │ ├── index.ftl
│ │ └── index.js
│ │ ├── env
│ │ ├── index.ftl
│ │ └── index.js
│ │ ├── guice
│ │ ├── index.ftl
│ │ └── index.js
│ │ ├── guicegraph
│ │ ├── index.ftl
│ │ └── index.js
│ │ ├── guiceprovision
│ │ ├── index.ftl
│ │ └── index.js
│ │ ├── home.ftl
│ │ ├── home.js
│ │ ├── jars
│ │ ├── index.ftl
│ │ └── index.js
│ │ └── jmx
│ │ ├── index.ftl
│ │ ├── index.js
│ │ ├── view.ftl
│ │ └── view.js
│ └── test
│ ├── java
│ └── netflix
│ │ └── adminresources
│ │ ├── WebAdminTest.java
│ │ └── tableview
│ │ └── PropsTableViewTest.java
│ └── log4j.properties
├── karyon2-admin
├── README.md
├── build.gradle
└── src
│ ├── main
│ ├── java
│ │ └── netflix
│ │ │ ├── admin
│ │ │ ├── AdminConfigImpl.java
│ │ │ ├── AdminContainerConfig.java
│ │ │ ├── AdminExplorerManager.java
│ │ │ ├── AdminFreemarkerTemplateProvider.java
│ │ │ ├── AdminUtils.java
│ │ │ ├── DefaultGlobalContextOverride.java
│ │ │ ├── DefaultRedirectRules.java
│ │ │ ├── GlobalModelContextOverride.java
│ │ │ └── RedirectRules.java
│ │ │ └── adminresources
│ │ │ ├── AbstractAdminPageInfo.java
│ │ │ ├── AdminPage.java
│ │ │ ├── AdminPageInfo.java
│ │ │ ├── AdminPageRegistry.java
│ │ │ ├── AdminResourcesContainer.java
│ │ │ ├── AdminResourcesFilter.java
│ │ │ ├── KaryonAdminModule.java
│ │ │ ├── LoggingFilter.java
│ │ │ └── RedirectFilter.java
│ └── resources
│ │ ├── admin-explorers.properties
│ │ └── baseserver-explorer.properties
│ └── test
│ ├── java
│ └── netflix
│ │ ├── admin
│ │ ├── AdminPageRegistryTest.java
│ │ └── AdminUtilsTest.java
│ │ └── adminresources
│ │ ├── AdminResourceTest.java
│ │ └── AuthFilter.java
│ └── resources
│ └── log4j.properties
├── karyon2-archaius
├── README.md
├── build.gradle
└── src
│ └── main
│ └── java
│ └── netflix
│ └── karyon
│ └── archaius
│ ├── ArchaiusBootstrap.java
│ ├── ArchaiusBootstrapModule.java
│ ├── DefaultPropertiesLoader.java
│ └── PropertiesLoader.java
├── karyon2-core
├── README.md
├── build.gradle
└── src
│ ├── main
│ └── java
│ │ └── netflix
│ │ └── karyon
│ │ ├── ShutdownListener.java
│ │ ├── health
│ │ ├── AlwaysHealthyHealthCheck.java
│ │ ├── HealthCheckHandler.java
│ │ └── HealthCheckInvocationStrategy.java
│ │ └── transport
│ │ ├── KaryonTransport.java
│ │ ├── RequestRouter.java
│ │ ├── http
│ │ ├── HttpInterceptorKey.java
│ │ ├── HttpInterceptorSupport.java
│ │ ├── HttpKeyEvaluationContext.java
│ │ ├── HttpRequestHandler.java
│ │ ├── HttpRequestHandlerBuilder.java
│ │ ├── MethodConstraintKey.java
│ │ ├── QueryStringDecoder.java
│ │ ├── RegexUriConstraintKey.java
│ │ ├── ServletStyleUriConstraintKey.java
│ │ └── SimpleUriRouter.java
│ │ └── interceptor
│ │ ├── AbstractAttacher.java
│ │ ├── AbstractInterceptorSupport.java
│ │ ├── DuplexInterceptor.java
│ │ ├── InboundInterceptor.java
│ │ ├── InterceptorExecutor.java
│ │ ├── InterceptorHolder.java
│ │ ├── InterceptorKey.java
│ │ ├── InterceptorSupport.java
│ │ ├── KeyEvaluationContext.java
│ │ └── OutboundInterceptor.java
│ └── test
│ └── java
│ └── netflix
│ └── karyon
│ └── server
│ ├── MockChannelHandlerContext.java
│ ├── http
│ ├── InterceptorConstraintTestBase.java
│ ├── MethodConstraintTest.java
│ ├── RegExConstraintTest.java
│ └── ServletStyleConstraintTest.java
│ └── interceptor
│ ├── InterceptorExecutorTest.java
│ ├── MockKey.java
│ ├── TestableDuplexInterceptor.java
│ ├── TestableInboundInterceptor.java
│ ├── TestableOutboundInterceptor.java
│ └── TestableRequestRouter.java
├── karyon2-eureka
├── README.md
├── build.gradle
└── src
│ └── main
│ └── java
│ └── netflix
│ └── karyon
│ └── eureka
│ ├── DefaultEurekaKaryonStatusBridge.java
│ ├── EurekaHealthCheckHandler.java
│ ├── EurekaKaryonStatusBridge.java
│ └── KaryonEurekaModule.java
├── karyon2-examples
├── README.md
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── netflix
│ │ └── karyon
│ │ └── examples
│ │ ├── hellonoss
│ │ ├── README.md
│ │ ├── common
│ │ │ ├── LoggingInterceptor.java
│ │ │ ├── auth
│ │ │ │ ├── AuthInterceptor.java
│ │ │ │ ├── AuthenticationService.java
│ │ │ │ └── AuthenticationServiceImpl.java
│ │ │ └── health
│ │ │ │ └── HealthCheck.java
│ │ └── server
│ │ │ ├── jersey
│ │ │ ├── HealthcheckResource.java
│ │ │ ├── HelloworldResource.java
│ │ │ ├── JerseyHelloWorldApp.java
│ │ │ └── README.md
│ │ │ ├── rxnetty
│ │ │ ├── MyApplicationRunner.java
│ │ │ ├── README.md
│ │ │ └── RxNettyHandler.java
│ │ │ └── simple
│ │ │ ├── HelloWorldEndpoint.java
│ │ │ ├── README.md
│ │ │ ├── SimpleRouter.java
│ │ │ ├── annotation
│ │ │ ├── README.md
│ │ │ └── SimpleRoutingApp.java
│ │ │ └── module
│ │ │ ├── README.md
│ │ │ ├── RouterWithInterceptors.java
│ │ │ └── SimpleRunner.java
│ │ ├── tcp
│ │ ├── README.md
│ │ ├── TcpPipelineApp.java
│ │ └── TcpPipelineHandlers.java
│ │ └── websockets
│ │ ├── README.md
│ │ └── WebSocketEchoServer.java
│ └── resources
│ ├── eureka-client.properties
│ ├── hello-netflix-oss-dev.properties
│ ├── hello-netflix-oss.properties
│ ├── sample-rxnetty-tcp-noss.properties
│ └── simplelogger.properties
├── karyon2-governator
├── README.md
├── build.gradle
└── src
│ ├── main
│ └── java
│ │ └── netflix
│ │ └── karyon
│ │ ├── AbstractKaryonServer.java
│ │ ├── Karyon.java
│ │ ├── KaryonBootstrap.java
│ │ ├── KaryonBootstrapModule.java
│ │ ├── KaryonRunner.java
│ │ ├── KaryonServer.java
│ │ ├── KaryonServerBackedServer.java
│ │ ├── MainClassBasedServer.java
│ │ ├── RxNettyServerBackedServer.java
│ │ ├── ShutdownModule.java
│ │ ├── health
│ │ └── SyncHealthCheckInvocationStrategy.java
│ │ ├── transport
│ │ ├── AbstractServerModule.java
│ │ ├── http
│ │ │ ├── GovernatorHttpInterceptorSupport.java
│ │ │ ├── HttpRxServerProvider.java
│ │ │ ├── KaryonHttpModule.java
│ │ │ ├── health
│ │ │ │ └── HealthCheckEndpoint.java
│ │ │ └── websockets
│ │ │ │ ├── KaryonWebSocketsModule.java
│ │ │ │ └── WebSocketsRxServerProvider.java
│ │ ├── tcp
│ │ │ ├── KaryonTcpModule.java
│ │ │ └── TcpRxServerProvider.java
│ │ └── util
│ │ │ └── HttpContentInputStream.java
│ │ └── utils
│ │ └── TypeUtils.java
│ └── test
│ └── java
│ └── netflix
│ └── karyon
│ └── transport
│ ├── http
│ ├── KaryonHttpModuleTest.java
│ └── websockets
│ │ └── KaryonWebSocketsModuleTest.java
│ └── tcp
│ └── KaryonTcpModuleTest.java
├── karyon2-jersey-blocking
├── README.md
├── build.gradle
└── src
│ ├── main
│ ├── java
│ │ └── netflix
│ │ │ └── karyon
│ │ │ └── jersey
│ │ │ └── blocking
│ │ │ ├── JerseyBasedRouter.java
│ │ │ ├── KaryonJerseyModule.java
│ │ │ ├── NettyContainer.java
│ │ │ ├── NettyContainerProvider.java
│ │ │ ├── NettyToJerseyBridge.java
│ │ │ ├── PropertiesBasedResourceConfig.java
│ │ │ └── ServiceIteratorProviderImpl.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── com.sun.jersey.spi.container.ContainerProvider
│ └── test
│ └── java
│ └── netflix
│ └── karyon
│ └── jersey
│ └── blocking
│ ├── JerseyBlockingModule.java
│ ├── JerseyBlockingTest.java
│ └── JsonReadingResource.java
├── karyon2-servo
├── README.md
├── build.gradle
└── src
│ └── main
│ └── java
│ └── netflix
│ └── karyon
│ └── servo
│ └── KaryonServoModule.java
├── print_junit_reports.sh
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 |
27 | # OS generated files #
28 | ######################
29 | .DS_Store*
30 | ehthumbs.db
31 | Icon?
32 | Thumbs.db
33 |
34 | # Editor Files #
35 | ################
36 | *~
37 | *.swp
38 |
39 | # Gradle Files #
40 | ################
41 | .gradle
42 | .m2
43 |
44 | # Build output directies
45 | /target
46 | **/target
47 | /build
48 | **/build
49 | /bin
50 | **/bin
51 |
52 | # IntelliJ specific files/directories
53 | out
54 | .idea
55 | *.ipr
56 | *.iws
57 | *.iml
58 | atlassian-ide-plugin.xml
59 |
60 | # Eclipse specific files/directories
61 | .classpath
62 | .project
63 | .settings
64 | .metadata
65 |
66 | # NetBeans specific files/directories
67 | .nbattrs
68 |
69 | *.class
70 | *.log
71 | **/deps
72 |
--------------------------------------------------------------------------------
/.netflixoss:
--------------------------------------------------------------------------------
1 | pullrequest_cloudbees=false
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | sudo: false
5 | install: ./installViaTravis.sh
6 | script: ./buildViaTravis.sh
7 | after_failure: print_junit_reports.sh
8 | cache:
9 | directories:
10 | - $HOME/.gradle/caches/
11 | env:
12 | global:
13 | - secure: DLWB16Ak6uB11U6pSqHlJz+IVVGJDun6qOlPTcwKAbZb8pSaxegK5vAu9/xTUgtq6ctjO0uAhxq66Fq+oQWrLIx0cdLWsdZ4kxJ9uq6TkNBCM2U4/NmSPHrIO0z3u107ehO8SKxHeWQpbNQF/Y80e4hvAAbgTfR9bXjC/zBtUhg=
14 | - secure: G3PMnpBAUlry+FNda0iL44wEG6T2q2hbJSRokJqw3qVyYc4b89MnF1gYZBJssawWoyyBybfha7ZIwMY9h5IpRVt3XE46VBMGq3aror9AV784e+pvFYvvRQgILrROL63nDehv3BrNYXrpvA6lxL6djRhitpb2GVuAvtVF2gHdO3s=
15 | - secure: RwfGxwmXIaHBq0Q+NVPeAHlj5yA841jU/HWOxYsOjwlKTcIN5QIZnbiweeK4nr0/RF3vBlD8SUY4BwVQT307Sbn4ZL1Yd3swMFoQd3ta9eJVRUEIiCeZpFMO9/vZUS7m7ddAl1NWcCee6Mh+L/F0FUrumUR4Vx2Xll5uKGqoDjM=
16 | - secure: oJJKAPfS7SOdmy1t0C/Tcyp8PxsYPUul/1E6YgjFSTIE+U0DDPh//kyCe/SvbqGeJy3JoW1KKYO7c9bD7VY/+LyEBML3O/RNFRKhc0Rxa0bCkmVb9pDBDeC/Xt3vNagK/GgFrXKgvWpzaeXT58jPnOq3fBDNMCz1iQrIIUtGio8=
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | TODO
2 |
--------------------------------------------------------------------------------
/OSSMETADATA:
--------------------------------------------------------------------------------
1 | osslifecycle=active
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | =====
2 | Karyon 2.0 is no longer supported. We are in the process of retiring Karyon in favor of using Governator for bootstrapping and OSS components with -guice or -governator subprojects.
3 | =====
4 |
5 |
6 | karyon
7 | ======
8 |
9 | [](https://travis-ci.org/Netflix/karyon/builds)
10 |
11 | Karyon in the context of molecular biology is essentially "a part of the cell containing DNA and RNA and responsible for growth and reproduction."
12 |
13 | At Netflix, Karyon is a framework and library that essentially contains the blueprint of what it means to implement a cloud ready web service. All the other fine grained web services and applications that form our SOA graph can essentially be thought as being cloned from this basic blueprint.
14 |
15 | Karyon can be thought of as a nucleus that contains the following main ingredients.
16 |
17 | * Bootstrapping , dependency and Lifecycle Management (via [Governator](https://github.com/Netflix/governator))
18 | * Runtime Insights and Diagnostics (via `karyon-admin-web` module)
19 | * Configuration Management (via [Archaius](https://github.com/Netflix/archaius))
20 | * Service discovery (via [Eureka](https://github.com/Netflix/eureka))
21 | * Powerful transport module (via [RxNetty](https://github.com/Netflix/RxNetty))
22 |
23 | Getting Started
24 | ===============
25 |
26 | Easiest way to get started with karyon is to see the examples provided with karyon under [karyon-examples](karyon2-examples) module.
27 |
28 | Documentation
29 | ==============
30 |
31 | Please see [wiki] (https://github.com/Netflix/karyon/wiki) for detailed documentation.
32 |
33 | Have a question?
34 | ===============
35 |
36 | We have a discussion group for karyon users (i.e. you!) here: https://groups.google.com/forum/?fromgroups#!forum/karyon-users
37 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories { jcenter() }
3 | dependencies {
4 | classpath 'com.netflix.nebula:gradle-extra-configurations-plugin:2.2.0'
5 | }
6 | }
7 |
8 | plugins {
9 | id 'nebula.netflixoss' version '2.2.9'
10 | }
11 |
12 | ext {
13 | githubProjectName = "karyon"
14 | }
15 |
16 | subprojects {
17 | apply plugin: 'nebula.netflixoss'
18 | apply plugin: 'groovy'
19 | apply plugin: 'nebula.provided-base'
20 | apply plugin: "jacoco"
21 |
22 | group = "com.netflix.karyon"
23 |
24 | repositories {
25 | jcenter()
26 | }
27 |
28 | dependencies {
29 | compile 'org.slf4j:slf4j-api:1.7.6'
30 | testCompile 'junit:junit:4.10'
31 | }
32 |
33 | eclipse {
34 | classpath {
35 | downloadSources = true
36 | downloadJavadoc = true
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/buildViaTravis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # This script will build the project.
3 |
4 | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
5 | echo -e "Build Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]"
6 | ./gradlew build --stacktrace --info
7 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then
8 | echo -e 'Build Branch with Snapshot => Branch ['$TRAVIS_BRANCH']'
9 | ./gradlew -Prelease.travisci=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build snapshot
10 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
11 | echo -e 'Build Branch for Release => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG']'
12 | case "$TRAVIS_TAG" in
13 | *-rc\.*)
14 | ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" candidate
15 | ;;
16 | *)
17 | ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" final
18 | ;;
19 | esac
20 | else
21 | echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG'] Pull Request ['$TRAVIS_PULL_REQUEST']'
22 | ./gradlew build
23 | fi
24 |
--------------------------------------------------------------------------------
/codequality/HEADER:
--------------------------------------------------------------------------------
1 | Copyright ${year} Netflix, Inc.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2012 Netflix, Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | org.gradle.daemon=true
17 |
18 | rxnetty_version=0.4.7
19 | jersey_version=1.19.1
20 | governator_version=1.14.2
21 | pytheas_version=1.29.0
22 | apache_httpclient_version=4.2.1
23 | eureka_version=1.1.151
24 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Netflix/karyon/d50bc0ff37693ef3fbda373e90a109d1f92e0b9a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jan 26 11:58:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/images/Interceptors-Flow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Netflix/karyon/d50bc0ff37693ef3fbda373e90a109d1f92e0b9a/images/Interceptors-Flow.jpg
--------------------------------------------------------------------------------
/installViaTravis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # This script will build the project.
3 |
4 | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
5 | echo -e "Assemble Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]"
6 | ./gradlew assemble
7 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then
8 | echo -e 'Assemble Branch with Snapshot => Branch ['$TRAVIS_BRANCH']'
9 | ./gradlew -Prelease.travisci=true assemble
10 | elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" != "" ]; then
11 | echo -e 'Assemble Branch for Release => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG']'
12 | ./gradlew -Prelease.travisci=true -Prelease.useLastTag=true assemble
13 | else
14 | echo -e 'WARN: Should not be here => Branch ['$TRAVIS_BRANCH'] Tag ['$TRAVIS_TAG'] Pull Request ['$TRAVIS_PULL_REQUEST']'
15 | ./gradlew assemble
16 | fi
17 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | tasks.withType(Javadoc).each {
19 | it.classpath = sourceSets.main.compileClasspath
20 | }
21 |
22 | dependencies {
23 | compile ('com.netflix.karyon:karyon-eureka:1.+')
24 | compile project(':karyon2-admin')
25 |
26 | testCompile 'org.slf4j:slf4j-log4j12:1.7.2'
27 | }
28 |
29 | eclipse {
30 | classpath {
31 | // include 'provided' dependencies on the classpath
32 | plusConfigurations += configurations.provided
33 | downloadSources = true
34 | downloadJavadoc = true
35 | }
36 | }
37 |
38 | idea {
39 | module {
40 | // include 'provided' dependencies on the classpath
41 | scopes.PROVIDED.plus += configurations.provided
42 | scopes.PROVIDED.plus += configurations.provided
43 | }
44 | }
45 |
46 | jar {
47 | manifest {
48 | name = 'karyon-admin-healthcheck-plugin'
49 | instruction 'Bundle-Vendor', 'Netflix'
50 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
51 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/main/java/com/netflix/adminresources/HealthcheckResource.java:
--------------------------------------------------------------------------------
1 | package com.netflix.adminresources;
2 |
3 | import com.google.inject.Inject;
4 | import com.netflix.karyon.server.eureka.HealthCheckInvocationStrategy;
5 | import com.sun.jersey.spi.resource.Singleton;
6 |
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.core.Response;
10 | import java.util.concurrent.TimeoutException;
11 |
12 | @Path("/v2/healthcheck")
13 | @Singleton
14 | public class HealthcheckResource {
15 |
16 | @Inject(optional = true)
17 | private HealthCheckInvocationStrategy invocationStrategy;
18 |
19 | @GET
20 | public Response doHealthCheck() {
21 | if (null != invocationStrategy) {
22 | try {
23 | int status = invocationStrategy.invokeCheck();
24 | return Response.status(status).build();
25 |
26 | } catch (TimeoutException e) {
27 | return Response.status(Response.Status.SERVICE_UNAVAILABLE).build();
28 |
29 | }
30 |
31 | } else {
32 | return Response.status(Response.Status.NOT_FOUND).build();
33 |
34 | }
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/main/java/netflix/adminresources/HealthCheckPlugin.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | @AdminPage
4 | public class HealthCheckPlugin extends AbstractAdminPageInfo {
5 |
6 | public static final String PAGE_ID = "karyon_healthCheck";
7 | public static final String NAME = "HealthCheck";
8 |
9 | public HealthCheckPlugin() {
10 | super(PAGE_ID, NAME);
11 | }
12 |
13 | @Override
14 | public String getJerseyResourcePackageList() {
15 | return "com.netflix.adminresources";
16 | }
17 |
18 | @Override
19 | public boolean isVisible() {
20 | return false;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2012 Netflix, Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | log4j.rootLogger=INFO, console
18 |
19 | log4j.appender.console=org.apache.log4j.ConsoleAppender
20 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
21 | log4j.appender.console.layout.ConversionPattern=%d %-5p %c{1}:%L %x %m [%t]%n
22 | log4j.logger.com.sun.jersey=TRACE
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-eureka-plugin/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | tasks.withType(Javadoc).each {
19 | it.classpath = sourceSets.main.compileClasspath
20 | }
21 |
22 | dependencies {
23 | dependencies {
24 | compile project(':karyon2-admin-web')
25 | compile "com.netflix.eureka:eureka-client:${eureka_version}"
26 | }
27 | }
28 |
29 | eclipse {
30 | classpath {
31 | // include 'provided' dependencies on the classpath
32 | plusConfigurations += configurations.provided
33 |
34 | downloadSources = true
35 | downloadJavadoc = true
36 | }
37 | }
38 |
39 | idea {
40 | module {
41 | // include 'provided' dependencies on the classpath
42 | scopes.PROVIDED.plus += configurations.provided
43 | scopes.PROVIDED.plus += configurations.provided
44 | }
45 | }
46 |
47 | jar {
48 | manifest {
49 | name = 'karyon2-admin-eureka-plugin'
50 | instruction 'Bundle-Vendor', 'Netflix'
51 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
52 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-eureka-plugin/src/main/java/netflix/adminresources/pages/EurekaPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import netflix.adminresources.AbstractAdminPageInfo;
4 | import netflix.adminresources.AdminPage;
5 |
6 | @AdminPage
7 | public class EurekaPage extends AbstractAdminPageInfo {
8 |
9 | public static final String PAGE_ID = "eureka";
10 | public static final String NAME = "Eureka";
11 |
12 | public EurekaPage() {
13 | super(PAGE_ID, NAME);
14 | }
15 | }
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-eureka-plugin/src/main/resources/webadmin/eureka/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-eureka-plugin/src/main/resources/webadmin/eureka/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | "use strict";
3 |
4 | $("#status-error").html("");
5 |
6 | var source = "${ajax_base}/eureka";
7 |
8 | var oTable = $('#discovery-table').dataTable( {
9 | "aoColumns": [
10 | {"sTitle" : "Application", "mDataProp" : "application"},
11 | {"sTitle" : "Instance Id", "mDataProp" : "id"},
12 | {"sTitle" : "Status", "mDataProp" : "status"},
13 | {"sTitle" : "IP Address", "mDataProp" : "ipAddress"},
14 | {"sTitle" : "Hostname", "mDataProp" : "hostName"}
15 | ],
16 | "sAjaxSource": source,
17 | "fnServerData": function ( sSource, aoData, fnCallback ) {
18 | $.getJSON(sSource)
19 | .success(function(json) {
20 | $("#status-error").html("");
21 | $("#status-lastupdate").html(new Date().format());
22 | if (json.error) {
23 | $("#status-error").html(json.error.message);
24 | $("#status-error").addClass("status-error");
25 | }
26 | else {
27 | $("#status-error").removeClass("status-error");
28 | fnCallback({"aaData": json.data});
29 | }
30 | })
31 | .error(function(jqXHR, textStatus, errorThrown) {
32 | $("#status-error").html(textStatus + ": " + errorThrown);
33 | $("#status-error").addClass("status-error");
34 | });
35 | },
36 | "bPaginate" : false,
37 | "bLengthChange" : false,
38 | "bAutoWidth" : false,
39 | "bFilter" : false,
40 | "fnInfoCallback": function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
41 | $("#status-visible").html(iTotal);
42 | $("#status-total").html(iMax);
43 | return "";
44 | }
45 | });
46 |
47 | $(".bse-filter").val("");
48 |
49 | $(".bse-filter").die("keyup").live("keyup", function() {
50 | $('#discovery-table').dataTable().fnFilter($(".bse-filter").val(), null, false, true);
51 | });
52 |
53 | $(".bse-refresh").die("click").live("click", function() {
54 | $('#discovery-table').dataTable().fnReloadAjax();
55 | });
56 | });
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-healthcheck-plugin/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | tasks.withType(Javadoc).each {
19 | it.classpath = sourceSets.main.compileClasspath
20 | }
21 |
22 | dependencies {
23 | dependencies {
24 | compile project(':karyon2-core')
25 | compile project(':karyon2-governator')
26 | compile project(':karyon2-admin-web')
27 | }
28 | }
29 |
30 | eclipse {
31 | classpath {
32 | // include 'provided' dependencies on the classpath
33 | plusConfigurations += configurations.provided
34 |
35 | downloadSources = true
36 | downloadJavadoc = true
37 | }
38 | }
39 |
40 | idea {
41 | module {
42 | // include 'provided' dependencies on the classpath
43 | scopes.PROVIDED.plus += configurations.provided
44 | scopes.PROVIDED.plus += configurations.provided
45 | }
46 | }
47 |
48 | jar {
49 | manifest {
50 | name = 'karyon2-admin-healthcheck-plugin'
51 | instruction 'Bundle-Vendor', 'Netflix'
52 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
53 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-healthcheck-plugin/src/main/java/netflix/adminresources/HealthCheckPlugin.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | @AdminPage
4 | public class HealthCheckPlugin extends AbstractAdminPageInfo {
5 |
6 | public static final String PAGE_ID = "karyon2_healthCheck";
7 | public static final String NAME = "HealthCheck";
8 |
9 | public HealthCheckPlugin() {
10 | super(PAGE_ID, NAME);
11 | }
12 |
13 | @Override
14 | public String getJerseyResourcePackageList() {
15 | return "netflix.adminresources";
16 | }
17 |
18 | @Override
19 | public boolean isVisible() {
20 | return false;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/karyon2-admin-plugins/karyon2-admin-healthcheck-plugin/src/main/java/netflix/adminresources/HealthCheckResource.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import com.google.inject.Inject;
4 | import com.google.inject.Singleton;
5 | import netflix.karyon.health.HealthCheckHandler;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import javax.ws.rs.GET;
10 | import javax.ws.rs.Path;
11 | import javax.ws.rs.Produces;
12 | import javax.ws.rs.core.MediaType;
13 | import javax.ws.rs.core.Response;
14 |
15 | @Path("/healthcheck")
16 | @Produces(MediaType.TEXT_HTML)
17 | @Singleton
18 | public class HealthCheckResource {
19 | private static final Logger logger = LoggerFactory.getLogger(HealthCheckResource.class);
20 | private HealthCheckHandler healthCheckHandler;
21 |
22 | @Inject
23 | public HealthCheckResource(HealthCheckHandler healthCheckHandler) {
24 | this.healthCheckHandler = healthCheckHandler;
25 | }
26 |
27 | @GET
28 | public Response getHealthCheck() {
29 | try {
30 | final int status = healthCheckHandler.getStatus();
31 | return Response.ok().status(status).build();
32 | } catch (Exception e) {
33 | logger.error("Exception in HealthCheckResource -- ", e);
34 | }
35 | return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/karyon2-admin-web/README.md:
--------------------------------------------------------------------------------
1 | karyon-admin-web
2 | ======
3 |
4 | The karyon web administration interface module.
5 |
6 | #### Guice Module
7 |
8 | [KaryonWebAdminModule](src/main/java/netflix/adminresources/resources/KaryonWebAdminModule.java) provides necessary guice bindings to use this web interface.
9 |
10 | See the [hello world example](../karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server) for a sample.
11 |
--------------------------------------------------------------------------------
/karyon2-admin-web/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | compile project(':karyon2-admin')
20 | compile "org.apache.httpcomponents:httpclient:${apache_httpclient_version}"
21 | compile 'com.google.code.gson:gson:2.1'
22 | runtime 'org.freemarker:freemarker:2.3.15'
23 | runtime 'org.codehaus.jackson:jackson-mapper-asl:1.9.11'
24 | }
25 |
26 | jar {
27 | manifest {
28 | name = 'karyon2-admin-web'
29 | instruction 'Bundle-Vendor', 'Netflix'
30 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
31 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/EnvPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 |
4 | import netflix.adminresources.AbstractAdminPageInfo;
5 | import netflix.adminresources.AdminPage;
6 |
7 | @AdminPage
8 | public class EnvPage extends AbstractAdminPageInfo {
9 |
10 | public static final String PAGE_ID = "env";
11 | public static final String NAME = "Environment";
12 |
13 | public EnvPage() {
14 | super(PAGE_ID, NAME);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/GuiceGraphPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import com.google.inject.Module;
4 |
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import netflix.adminresources.AbstractAdminPageInfo;
9 | import netflix.adminresources.AdminPage;
10 |
11 | @AdminPage
12 | public class GuiceGraphPage extends AbstractAdminPageInfo {
13 |
14 | public static final String PAGE_ID = "guicegraph";
15 | public static final String NAME = "GuiceGraph";
16 |
17 | public GuiceGraphPage() {
18 | super(PAGE_ID, NAME);
19 | }
20 |
21 | @Override
22 | public List getGuiceModules() {
23 | return Arrays.asList(new KaryonGrapherModule());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/GuicePage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import com.google.inject.Module;
4 |
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import netflix.adminresources.AbstractAdminPageInfo;
9 | import netflix.adminresources.AdminPage;
10 |
11 | @AdminPage
12 | public class GuicePage extends AbstractAdminPageInfo {
13 |
14 | public static final String PAGE_ID = "guice";
15 | public static final String NAME = "Guice";
16 |
17 | public GuicePage() {
18 | super(PAGE_ID, NAME);
19 | }
20 |
21 | @Override
22 | public List getGuiceModules() {
23 | return Arrays.asList(new KaryonGrapherModule());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/GuiceProvisionPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import com.google.inject.Module;
4 |
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import netflix.adminresources.AbstractAdminPageInfo;
9 | import netflix.adminresources.AdminPage;
10 |
11 | @AdminPage
12 | public class GuiceProvisionPage extends AbstractAdminPageInfo {
13 |
14 | public static final String PAGE_ID = "guiceprovision";
15 | public static final String NAME = "GuiceProvision";
16 |
17 | public GuiceProvisionPage() {
18 | super(PAGE_ID, NAME);
19 | }
20 |
21 | @Override
22 | public List getGuiceModules() {
23 | return Arrays.asList(new KaryonGrapherModule());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/JarsPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import netflix.adminresources.AbstractAdminPageInfo;
4 | import netflix.adminresources.AdminPage;
5 |
6 | @AdminPage
7 | public class JarsPage extends AbstractAdminPageInfo {
8 |
9 | public static final String PAGE_ID = "jars";
10 | public static final String NAME = "Jars";
11 |
12 | public JarsPage() {
13 | super(PAGE_ID, NAME);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/JmxPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import netflix.adminresources.AbstractAdminPageInfo;
4 | import netflix.adminresources.AdminPage;
5 |
6 | @AdminPage
7 | public class JmxPage extends AbstractAdminPageInfo {
8 |
9 | public static final String PAGE_ID = "jmx";
10 | public static final String NAME = "JMX";
11 |
12 | public JmxPage() {
13 | super(PAGE_ID, NAME);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/KaryonGrapherModule.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 | import com.google.inject.AbstractModule;
4 | import com.google.inject.grapher.NameFactory;
5 | import com.google.inject.grapher.ShortNameFactory;
6 | import com.google.inject.grapher.graphviz.PortIdFactory;
7 | import com.google.inject.grapher.graphviz.PortIdFactoryImpl;
8 |
9 | public class KaryonGrapherModule extends AbstractModule {
10 |
11 | @Override
12 | protected void configure() {
13 | bind(NameFactory.class).to(ShortNameFactory.class);
14 | bind(PortIdFactory.class).to(PortIdFactoryImpl.class);
15 | }
16 |
17 | @Override
18 | public int hashCode() {
19 | return getClass().hashCode();
20 | }
21 |
22 | @Override
23 | public boolean equals(Object obj) {
24 | return getClass().equals(obj.getClass());
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/pages/PropertiesPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.pages;
2 |
3 |
4 | import netflix.adminresources.AbstractAdminPageInfo;
5 | import netflix.adminresources.AdminPage;
6 |
7 | @AdminPage
8 | public class PropertiesPage extends AbstractAdminPageInfo {
9 |
10 | public static final String PAGE_ID = "archprops";
11 | public static final String NAME = "Archaius";
12 |
13 | public PropertiesPage() {
14 | super(PAGE_ID, NAME);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/AllPropsResource.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import netflix.adminresources.resources.model.Property;
6 |
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.Produces;
10 | import javax.ws.rs.core.MediaType;
11 | import javax.ws.rs.core.Response;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 |
16 | @Path("/allprops")
17 | @Produces(MediaType.APPLICATION_JSON)
18 | public class AllPropsResource {
19 |
20 | public static class PropsResponse {
21 | private Map props;
22 |
23 | public PropsResponse(Map props) {
24 | this.props = props;
25 | }
26 |
27 | public Map getProps() {
28 | return props;
29 | }
30 | }
31 |
32 | @GET
33 | public Response getAllProperties() {
34 | final List allProperties = PropertiesHelper.getAllProperties();
35 | GsonBuilder gsonBuilder = new GsonBuilder().serializeNulls();
36 | Gson gson = gsonBuilder.create();
37 | String propsJson = gson.toJson(new PropsResponse(PropertiesHelper.buildPropertiesMap(allProperties)));
38 | return Response.ok(propsJson).build();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/KaryonAdminResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.adminresources.resources;
18 |
19 | /**
20 | * @author Nitesh Kant
21 | */
22 | public class KaryonAdminResponse {
23 |
24 | private Object data;
25 |
26 | public KaryonAdminResponse(Object data) {
27 | this.data = data;
28 | }
29 |
30 | public Object getData() {
31 | return data;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/KaryonWebAdminModule.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources;
2 |
3 | import netflix.adminresources.KaryonAdminModule;
4 |
5 | public class KaryonWebAdminModule extends KaryonAdminModule {
6 |
7 | @Override
8 | protected void configure() {
9 | super.configure();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/MaskedResourceHelper.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources;
2 |
3 | import com.google.common.annotations.VisibleForTesting;
4 | import com.google.common.base.Splitter;
5 | import com.netflix.config.DynamicPropertyFactory;
6 |
7 | import java.util.HashSet;
8 | import java.util.Set;
9 |
10 | public class MaskedResourceHelper {
11 | @VisibleForTesting
12 | public static final String MASKED_PROPERTY_NAMES = "netflix.platform.admin.resources.masked.property.names";
13 | public static final String MASKED_ENV_NAMES = "netflix.platform.admin.resources.masked.env.names";
14 | public static final String MASKED_PROPERTY_VALUE = "**** MASKED ****";
15 |
16 | private static final Splitter SPLITTER = Splitter.on(',')
17 | .trimResults()
18 | .omitEmptyStrings();
19 |
20 | public static Set getMaskedPropertiesSet() {
21 | String maskedResourceNames = DynamicPropertyFactory.getInstance().getStringProperty(MASKED_PROPERTY_NAMES, "").get();
22 | Set maskedPropertiesSet = getMaskedResourceSet(maskedResourceNames);
23 | // add the MASKED_PROPERTY_NAMES property, itself, for super-duper security-obscurity
24 | maskedPropertiesSet.add(MASKED_PROPERTY_NAMES);
25 | return maskedPropertiesSet;
26 | }
27 |
28 | public static Set getMaskedEnvSet() {
29 | String maskedResourceNames = DynamicPropertyFactory.getInstance().getStringProperty(MASKED_ENV_NAMES, "").get();
30 | return getMaskedResourceSet(maskedResourceNames);
31 | }
32 |
33 |
34 | private static Set getMaskedResourceSet(String maskedResourceNames) {
35 | Iterable maskedResourceNamesIter = SPLITTER.split(maskedResourceNames);
36 |
37 | Set maskedResourceSet = new HashSet();
38 | for (String maskedResource : maskedResourceNamesIter) {
39 | maskedResourceSet.add(maskedResource);
40 | }
41 | return maskedResourceSet;
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/PairResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.adminresources.resources;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | /**
24 | * @author Nitesh Kant
25 | */
26 | public class PairResponse {
27 |
28 | List data;
29 |
30 | public PairResponse() {
31 | data = new ArrayList();
32 | }
33 |
34 | public PairResponse(Map input) {
35 | this();
36 | for (Map.Entry entry : input.entrySet()) {
37 | data.add(new Pair(String.valueOf(entry.getKey()), entry.getValue()));
38 | }
39 | }
40 |
41 | public void addEntry(String name, String value) {
42 | data.add(new Pair(name, value));
43 | }
44 |
45 | private static class Pair {
46 |
47 | private String name;
48 | private Object value;
49 |
50 | private Pair(String name, Object value) {
51 | this.name = name;
52 | this.value = value;
53 | }
54 |
55 | public String getName() {
56 | return name;
57 | }
58 |
59 | public Object getValue() {
60 | return value;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/PropertiesHelper.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources;
2 |
3 | import com.netflix.config.ConfigurationManager;
4 | import netflix.adminresources.resources.model.Property;
5 | import org.apache.commons.configuration.AbstractConfiguration;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.*;
10 |
11 | public class PropertiesHelper {
12 | private static final Logger LOG = LoggerFactory.getLogger(PropertiesHelper.class);
13 |
14 | public static List getAllProperties() {
15 | final AbstractConfiguration configInstance = ConfigurationManager.getConfigInstance();
16 | List properties = new ArrayList();
17 | Iterator keys = null;
18 | try {
19 | keys = configInstance.getKeys();
20 | } catch (Exception e) {
21 | LOG.error("Exception fetching all property keys ", e);
22 | }
23 |
24 | Set maskedResources = MaskedResourceHelper.getMaskedPropertiesSet();
25 |
26 | while (keys.hasNext()) {
27 | final String key = (String) keys.next();
28 | try {
29 | Object value = null;
30 | // mask the specified properties
31 | if (maskedResources.contains(key)) {
32 | value = MaskedResourceHelper.MASKED_PROPERTY_VALUE;
33 | } else {
34 | value = configInstance.getProperty(key);
35 | }
36 | Property property = new Property(key, value.toString(), null);
37 | properties.add(property);
38 | } catch (Exception e) {
39 | LOG.info("Exception fetching property value for key " + key, e);
40 | }
41 |
42 | }
43 | return properties;
44 | }
45 |
46 | public static Map buildPropertiesMap(List properties) {
47 | Map propsMap = new HashMap<>();
48 | for (Property prop : properties) {
49 | propsMap.put(prop.getName(), prop.getValue());
50 | }
51 | return propsMap;
52 | }
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/PropertiesResource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.adminresources.resources;
18 |
19 | import com.google.common.annotations.Beta;
20 | import com.google.gson.Gson;
21 | import com.google.gson.JsonObject;
22 | import com.google.inject.Inject;
23 | import netflix.adminresources.tableview.DataTableHelper;
24 | import netflix.adminresources.tableview.PropsTableView;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 |
28 | import javax.ws.rs.GET;
29 | import javax.ws.rs.Path;
30 | import javax.ws.rs.Produces;
31 | import javax.ws.rs.core.Context;
32 | import javax.ws.rs.core.MediaType;
33 | import javax.ws.rs.core.MultivaluedMap;
34 | import javax.ws.rs.core.Response;
35 | import javax.ws.rs.core.UriInfo;
36 |
37 | @Beta
38 | @Path("/archprops")
39 | @Produces(MediaType.APPLICATION_JSON)
40 | public class PropertiesResource {
41 | private static final Logger LOG = LoggerFactory.getLogger(PropertiesResource.class);
42 |
43 | @Inject(optional = true)
44 | private PropsTableView adminPropsResource;
45 |
46 | @GET
47 | public Response getProperties(@Context UriInfo uriInfo) {
48 | if (adminPropsResource != null) {
49 | MultivaluedMap queryParams = uriInfo.getQueryParameters();
50 | JsonObject output = DataTableHelper.buildOutput(adminPropsResource, queryParams);
51 | return Response.ok().entity(new Gson().toJson(output)).build();
52 | } else {
53 | return Response.status(Response.Status.BAD_REQUEST).build();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/model/Property.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources.model;
2 |
3 | import javax.xml.bind.annotation.XmlRootElement;
4 | import java.util.List;
5 |
6 | @XmlRootElement(name = "property")
7 | public class Property {
8 | private String name;
9 | private String value;
10 | private List sources;
11 |
12 | public Property(String name, String value, List sources) {
13 | this.name = name;
14 | this.value = value;
15 | this.sources = sources;
16 | }
17 |
18 | public Property() {
19 |
20 | }
21 |
22 | public String getName() {
23 | return name;
24 | }
25 |
26 | public void setName(String name) {
27 | this.name = name;
28 | }
29 |
30 | public String getValue() {
31 | return value;
32 | }
33 |
34 | public void setValue(String value) {
35 | this.value = value;
36 | }
37 |
38 | public List getSources() {
39 | return sources;
40 | }
41 |
42 | public void setSources(List sources) {
43 | this.sources = sources;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return "Property [name=" + name + ", value=" + value + ", sources=" + sources + "]";
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/resources/model/PropertySource.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.resources.model;
2 |
3 | public class PropertySource {
4 | private String sourceName;
5 | private String value;
6 |
7 | public PropertySource() {
8 | }
9 |
10 | public PropertySource(String sourceName, String value) {
11 | this.sourceName = sourceName;
12 | this.value = value;
13 | }
14 |
15 | public String getSourceName() {
16 | return sourceName;
17 | }
18 |
19 | public void setSourceName(String sourceName) {
20 | this.sourceName = sourceName;
21 | }
22 |
23 | public String getValue() {
24 | return value;
25 | }
26 |
27 | public void setValue(String value) {
28 | this.value = value;
29 | }
30 |
31 | @Override
32 | public String toString() {
33 | return "PropertySource [sourceName=" + sourceName + ", value=" + value + "]";
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/java/netflix/adminresources/tableview/TableViewResource.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources.tableview;
2 |
3 | import com.google.gson.JsonArray;
4 |
5 | import java.util.List;
6 |
7 | public interface TableViewResource {
8 |
9 | List getColumns();
10 |
11 | TableViewResource setColumnSearchTerm(String column, String term);
12 |
13 | TableViewResource setAllColumnsSearchTerm(String term);
14 |
15 | TableViewResource enableColumnSort(String column, boolean isDescending);
16 |
17 | JsonArray getData();
18 |
19 | int getTotalNumOfRecords();
20 |
21 | int getFilteredNumOfRecords();
22 |
23 | TableViewResource setCurrentPageInfo(int startIndex, int count);
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/css/d3.flameGraph.css:
--------------------------------------------------------------------------------
1 | .d3-flame-graph rect {
2 | stroke: #EEEEEE;
3 | fill-opacity: .8;
4 | }
5 |
6 | .d3-flame-graph rect:hover {
7 | stroke: #474747;
8 | stroke-width: 0.5;
9 | cursor: pointer;
10 | }
11 |
12 | .d3-flame-graph .label {
13 | pointer-events: none;
14 | white-space: nowrap;
15 | text-overflow: ellipsis;
16 | overflow: hidden;
17 | font-size: 12px;
18 | font-family: Verdana;
19 | margin-left: 4px;
20 | margin-right: 4px;
21 | line-height: 1.5;
22 | padding: 0 0 0;
23 | font-weight: 400;
24 | color: black;
25 | text-align: left;
26 | }
27 |
28 | .d3-flame-graph .fade {
29 | opacity: 0.6 !important;
30 | }
31 |
32 | .d3-flame-graph .title {
33 | font-size: 20px;
34 | font-family: Verdana;
35 | }
36 |
37 | .d3-flame-graph-tip {
38 | line-height: 1;
39 | font-family: Verdana;
40 | font-size: 12px;
41 | padding: 12px;
42 | background: rgba(0, 0, 0, 0.8);
43 | color: #fff;
44 | border-radius: 2px;
45 | pointer-events: none;
46 | }
47 |
48 | /* Creates a small triangle extender for the tooltip */
49 | .d3-flame-graph-tip:after {
50 | box-sizing: border-box;
51 | display: inline;
52 | font-size: 10px;
53 | width: 100%;
54 | line-height: 1;
55 | color: rgba(0, 0, 0, 0.8);
56 | position: absolute;
57 | pointer-events: none;
58 | }
59 |
60 | /* Northward tooltips */
61 | .d3-flame-graph-tip.n:after {
62 | content: "\25BC";
63 | margin: -1px 0 0 0;
64 | top: 100%;
65 | left: 0;
66 | text-align: center;
67 | }
68 |
69 | /* Eastward tooltips */
70 | .d3-flame-graph-tip.e:after {
71 | content: "\25C0";
72 | margin: -4px 0 0 0;
73 | top: 50%;
74 | left: -8px;
75 | }
76 |
77 | /* Southward tooltips */
78 | .d3-flame-graph-tip.s:after {
79 | content: "\25B2";
80 | margin: 0 0 1px 0;
81 | top: -8px;
82 | left: 0;
83 | text-align: center;
84 | }
85 |
86 | /* Westward tooltips */
87 | .d3-flame-graph-tip.w:after {
88 | content: "\25B6";
89 | margin: -4px 0 0 -1px;
90 | top: 50%;
91 | left: 100%;
92 | }
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/archprops/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
73 |
74 | <#import "/layout/bootstrap/form.ftl" as form/>
75 | <#import "/layout/bootstrap/bootstrap.ftl" as bs/>
76 |
77 |
78 |
79 |
80 |
81 |
82 | <@form.modalform action="/webadmin/props" id="property-new-template" title="New property" class="span10">
83 | <@form.modalbody>
84 | <@form.text label="Property Name" name="name" />
85 | <@form.textarea label="Property Value" name="value"/>
86 | @form.modalbody>
87 |
88 | <@form.modalfooter>
89 | <@form.submit "Create"/>
90 | <@form.cancel "Cancel"/>
91 | @form.modalfooter>
92 | @form.modalform>
93 |
94 |
95 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/archprops/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | "use strict";
3 |
4 | $("#status-error").html("");
5 | var source = "${ajax_base}/archprops";
6 |
7 | $('#props-table').dataTable({
8 | "aoColumns": [
9 | { "sTitle": "Name", "sWidth" : "30%", "sDefaultContent" : "-" },
10 | { "sTitle": "Value", "sWidth" : "70%", "sDefaultContent" : "-"}
11 | ],
12 | "sAjaxSource" : source,
13 | "fnServerData" : function (sSource, aoData, fnCallback) {
14 | $.getJSON(sSource, aoData, function (json) {
15 | $("#status-lastupdate").html(new Date().format());
16 | if (json.iTotalDisplayRecords) {
17 | $("#status-visible").html(json.iTotalDisplayRecords);
18 | }
19 | if (json.iTotalRecords) {
20 | $("#status-total").html(json.iTotalRecords);
21 | }
22 | fnCallback(json);
23 | });
24 | },
25 | "bLengthChange" : false,
26 | "bServerSide" : true,
27 | "bProcessing" : true,
28 | "sPaginationType": "bootstrap",
29 | "iDisplayLength" : 50,
30 | "bDestroy" : true,
31 | "bFilter" : true,
32 | "bAutoWidth" : false,
33 | "fnInfoCallback" : function (oSettings, iStart, iEnd, iMax, iTotal, sPre) {
34 | $("#status-visible").html(iTotal);
35 | $("#status-total").html(iMax);
36 | return "";
37 | }
38 | });
39 |
40 | $(".bse-filter").val("");
41 | $("#props-table_filter").hide();
42 |
43 | $(".bse-filter").die("keyup").live("keyup", function () {
44 | $('#props-table').dataTable().fnFilter($(".bse-filter").val(), null, false, true);
45 | });
46 |
47 | $(".bse-refresh").die("click").live("click", function () {
48 | $('#props-table').dataTable().fnReloadAjax();
49 | });
50 | });
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/env/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/env/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | "use strict";
3 |
4 | $("#status-error").html("");
5 |
6 | var source = "${ajax_base}/env";
7 |
8 | var oTable = $('#env-table').dataTable( {
9 | "aoColumns": [
10 | { "sTitle" : "Name", 'sWidth' : '50%' },
11 | { "sTitle" : "Value", 'sWidth' : '50%' }
12 | ],
13 | "sAjaxSource": source,
14 | "fnServerData": function ( sSource, aoData, fnCallback ) {
15 | $.getJSON(sSource)
16 | .success(function(json) {
17 | $("#status-error").html("");
18 | $("#status-lastupdate").html(new Date().format());
19 | if (json.error) {
20 | $("#status-error").html(json.error.message);
21 | $("#status-error").addClass("status-error");
22 | }
23 | else {
24 | $("#status-error").removeClass("status-error");
25 | var items = [];
26 | var envObj = json.env;
27 | for (var key in envObj) {
28 | if (envObj.hasOwnProperty(key)) {
29 | items.push([key, json.env[key]]);
30 | }
31 | }
32 | fnCallback({"aaData": items});
33 | }
34 | })
35 | .error(function(jqXHR, textStatus, errorThrown) {
36 | $("#status-error").html(textStatus + ": " + errorThrown);
37 | $("#status-error").addClass("status-error");
38 | });
39 | },
40 | "bPaginate" : false,
41 | "bLengthChange" : false,
42 | "bDestroy" : true,
43 | "bFilter" : true,
44 | "fnInfoCallback" : function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
45 | $("#status-visible").html(iTotal);
46 | $("#status-total").html(iMax);
47 | return "";
48 | }
49 | });
50 |
51 | $(".bse-filter").val("");
52 | $("#env-table_filter").hide();
53 |
54 | $(".bse-filter").die("keyup").live("keyup", function() {
55 | $('#env-table').dataTable().fnFilter($(".bse-filter").val(), null, false, true);
56 | });
57 |
58 | $(".bse-refresh").die("click").live("click", function() {
59 | $('#env-table').dataTable().fnReloadAjax();
60 | });
61 |
62 | });
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/guice/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/guice/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | "use strict";
3 |
4 | $("#status-error").html("");
5 |
6 | var source = "${ajax_base}/guice/keys";
7 |
8 | $.get(source, function(json) {
9 | var code = JSON.stringify(json, null, 2);
10 | $("#guice-keys").text(code);
11 | });
12 | });
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/guicegraph/index.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
38 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/guiceprovision/index.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
41 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/guiceprovision/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function(){
2 | var flamegraph = d3.flameGraph()
3 | .width(1280)
4 | .height(340)
5 | .label(function(d) {
6 | return d.name + " " + d.value + " msec";
7 | });
8 |
9 | d3.json("${ajax_base}/guice/metrics", function(error, data) {
10 | if (error) {
11 | console.warn(error);
12 | } else {
13 | d3.select(".middle-center")
14 | .datum(data)
15 | .call(flamegraph);
16 | }
17 | });
18 | });
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/home.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 | <#macro body>
4 |
12 |
13 | <#import "/layout/bootstrap/macros.ftl" as nf/>
14 |
15 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | <#if adminPages??>
45 | <#list adminPages as adminPage>
46 | <#if adminPage.isVisible()>
47 | <#if adminPage.name??>
48 |
49 | <#else>
50 |
51 | #if>
52 | #if>
53 | #list>
54 | #if>
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
72 |
73 |
74 |
80 | #macro>
81 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/home.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | "use strict";
3 | var templateBaseUrl = '${template_base}';
4 |
5 | $("div.outer-center").layout({
6 | defaults: {
7 | resizable : false,
8 | slideable : false,
9 | spacing_open: 0,
10 | spacing_closed: 0
11 | },
12 | north: { paneSelector : ".middle-north" },
13 | south: { paneSelector : ".middle-south" },
14 | center: { paneSelector : ".middle-center-wrapper" }
15 | });
16 |
17 | var ajaxCallBase = '${ajax_base}';
18 | var init = $.getHashParams();
19 | var state = {};
20 |
21 |
22 | $(".nav a").click( function(e) {
23 | e.preventDefault();
24 | $.modifyHashParams({"view": $(this).attr("id").substring("submenu-".length)});
25 | });
26 |
27 | $("#machine-readable").click(function(e) {
28 | e.preventDefault();
29 | window.open(ajaxCallBase + "/" + $.getHashParams()["view"]);
30 | });
31 |
32 |
33 | /**
34 | * Load page elements based on the location hash
35 | */
36 | function applyHashChange(prev, curr) {
37 | if (!curr.view)
38 | curr.view = "env";
39 | if (curr.view == state.view && curr.app == state.app && curr.inst == state.inst)
40 | return;
41 |
42 | $("#bc-app").text(curr.app ? curr.app : "");
43 | $("#bc-instance").text(curr.inst ? curr.inst : "");
44 | $("#bc-view").text($("#submenu-{0} span".format(curr.view)).text());
45 |
46 | populateContents(curr.view, curr.inst);
47 | }
48 |
49 | /**
50 | * Load the view for the currently select instance
51 | */
52 | function populateContents(view, inst) {
53 | state.view = view;
54 | if (!state.view) {
55 | state.view = "env";
56 | }
57 | state.inst = inst;
58 | var $view = $(".middle-center");
59 | if (view) {
60 | var url = templateBaseUrl + "/{0}".format(state.view);
61 | $(".nav li").removeClass("active");
62 | $("#submenu-{0}".format(state.view)).parent().addClass("active");
63 |
64 | $view.ajaxBusy();
65 | $view.html("");
66 | $view.load(url, function() {
67 | $view.ajaxBusy('remove');
68 | });
69 | } else {
70 | $view.html("Select an instance or valid view");
71 | }
72 | }
73 |
74 | $.listenHashChange(applyHashChange);
75 | });
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/jars/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/jmx/index.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
29 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/main/resources/webadmin/jmx/view.ftl:
--------------------------------------------------------------------------------
1 |
4 |
5 | <#import "/layout/main/macros.ftl" as nf/>
6 |
7 |
34 |
35 |
36 |
${key}
37 |
Attributes
38 |
41 |
42 |
43 |
Operations
44 |
45 |
46 |
47 |
Results
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/karyon2-admin-web/src/test/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootCategory=debug,stdout
2 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
4 | log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n
--------------------------------------------------------------------------------
/karyon2-admin/README.md:
--------------------------------------------------------------------------------
1 | karyon-admin
2 | ======
3 |
4 | Base module for karyon administration console.
5 | The actual web interface is provided by the [karyon2-admin-web](../karyon2-admin-web) module.
6 |
--------------------------------------------------------------------------------
/karyon2-admin/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | dependencies {
20 | compile 'javax.ws.rs:jsr311-api:1.1.1'
21 | compile 'javax.servlet:javax.servlet-api:3.0.1'
22 | compile 'org.mortbay.jetty:jetty:6.1.26'
23 | compile 'com.google.inject.extensions:guice-servlet:4.1.0'
24 | compile 'com.sun.jersey.contribs:jersey-guice:${jersey_version}'
25 | compile "com.sun.jersey:jersey-servlet:${jersey_version}"
26 | compile "com.sun.jersey:jersey-server:${jersey_version}"
27 | compile "com.netflix.pytheas:pytheas-core:${pytheas_version}"
28 | compile "com.sun.jersey:jersey-core:${jersey_version}"
29 | compile "com.sun.jersey:jersey-servlet:${jersey_version}"
30 | compile "com.sun.jersey:jersey-server:${jersey_version}"
31 | compile "com.sun.jersey:jersey-json:${jersey_version}"
32 | runtime 'org.codehaus.jackson:jackson-mapper-asl:1.9.11'
33 |
34 | testCompile "org.apache.httpcomponents:httpclient:${apache_httpclient_version}"
35 | testCompile 'log4j:log4j:1.2.17'
36 | testCompile 'org.slf4j:slf4j-log4j12:1.7.2'
37 | }
38 | }
39 |
40 | jar {
41 | manifest {
42 | name = 'karyon2-admin'
43 | instruction 'Bundle-Vendor', 'Netflix'
44 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
45 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/AdminContainerConfig.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 |
6 | import javax.servlet.Filter;
7 |
8 | import com.google.inject.ImplementedBy;
9 | import org.mortbay.jetty.Connector;
10 |
11 | @ImplementedBy(AdminConfigImpl.class)
12 | public interface AdminContainerConfig {
13 | boolean shouldIsolateResources();
14 | boolean shouldEnable();
15 | String templateResourceContext();
16 | String ajaxDataResourceContext();
17 | String jerseyResourcePkgList();
18 | String jerseyViewableResourcePkgList();
19 | boolean shouldScanClassPathForPluginDiscovery();
20 | int listenPort();
21 | List additionalFilters();
22 | List additionalConnectors();
23 | Map getJerseyConfigProperties();
24 | List homeScriptResources();
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/AdminUtils.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.util.Properties;
9 |
10 | public class AdminUtils {
11 | private static final Logger LOG = LoggerFactory.getLogger(AdminExplorerManager.class);
12 |
13 | public static Properties loadAdminConsoleProps() {
14 | final Properties properties = new Properties();
15 | final InputStream propsResourceStream = AdminUtils.class.getClassLoader().getResourceAsStream("admin-explorers.properties");
16 | if (propsResourceStream != null) {
17 | try {
18 | properties.load(propsResourceStream);
19 | } catch (IOException e) {
20 | LOG.error("Exception loading admin console properties file.", e);
21 | }
22 | }
23 |
24 | return properties;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/DefaultGlobalContextOverride.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import java.util.Properties;
4 |
5 | public class DefaultGlobalContextOverride implements GlobalModelContextOverride {
6 | @Override
7 | public Properties overrideProperties(Properties properties) {
8 | return properties;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/DefaultRedirectRules.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import javax.inject.Singleton;
7 | import javax.inject.Inject;
8 | import javax.servlet.http.HttpServletRequest;
9 |
10 | @Singleton
11 | public class DefaultRedirectRules implements RedirectRules {
12 |
13 | private AdminContainerConfig adminContainerConfig;
14 |
15 | @Inject
16 | public DefaultRedirectRules(AdminContainerConfig adminContainerConfig) {
17 | this.adminContainerConfig = adminContainerConfig;
18 | }
19 |
20 | @Override
21 | public Map getMappings() {
22 | Map urlRedirects = new HashMap<>();
23 | urlRedirects.put("/", adminContainerConfig.templateResourceContext());
24 | return urlRedirects;
25 | }
26 |
27 | @Override
28 | public String getRedirect(HttpServletRequest httpServletRequest) {
29 | return httpServletRequest.getRequestURI();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/GlobalModelContextOverride.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import com.google.inject.ImplementedBy;
4 |
5 | import java.util.Properties;
6 |
7 | @ImplementedBy(DefaultGlobalContextOverride.class)
8 | public interface GlobalModelContextOverride {
9 | Properties overrideProperties(Properties properties);
10 | }
11 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/admin/RedirectRules.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 | import com.google.inject.ImplementedBy;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 | import java.util.Map;
7 |
8 | @ImplementedBy(DefaultRedirectRules.class)
9 | public interface RedirectRules {
10 | Map getMappings();
11 | String getRedirect(HttpServletRequest httpServletRequest);
12 | }
13 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/AbstractAdminPageInfo.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import com.google.inject.Module;
4 | import com.netflix.config.ConfigurationManager;
5 |
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | public abstract class AbstractAdminPageInfo implements AdminPageInfo {
12 | public static final String ADMIN_PAGE_DISABLE_PROP_PREFIX = "netflix.platform.admin.pages.";
13 | public static final String DISABLED = ".disabled";
14 |
15 | private final String pageId;
16 | private final String name;
17 |
18 | public AbstractAdminPageInfo(String pageId, String name) {
19 | this.pageId = pageId;
20 | this.name = name;
21 | }
22 |
23 | public String getPageId() {
24 | return pageId;
25 | }
26 |
27 | @Override
28 | public String getName() {
29 | return name;
30 | }
31 |
32 | @Override
33 | public String getPageTemplate() {
34 | return "/webadmin/" + pageId + "/index.ftl";
35 | }
36 |
37 | @Override
38 | public String getJerseyResourcePackageList() {
39 | return "";
40 | }
41 |
42 | @Override
43 | public boolean isEnabled() {
44 | final String disablePagePropId = ADMIN_PAGE_DISABLE_PROP_PREFIX + pageId + DISABLED;
45 | boolean isDisabled = ConfigurationManager.getConfigInstance().getBoolean(disablePagePropId, false);
46 | return !isDisabled;
47 | }
48 |
49 | @Override
50 | public List getGuiceModules() {
51 | return new ArrayList<>(0);
52 | }
53 |
54 | @Override
55 | public Map getDataModel() {
56 | return new HashMap<>();
57 | }
58 |
59 | @Override
60 | public boolean isVisible() {
61 | return true;
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/AdminPage.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
4 | @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
5 | public @interface AdminPage {
6 | }
7 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/AdminPageInfo.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import com.google.inject.Module;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | public interface AdminPageInfo {
9 | // id of the new page
10 | String getPageId();
11 |
12 | // title as shown in tab UI
13 | String getName();
14 |
15 | // freemarker template path
16 | String getPageTemplate();
17 |
18 | // exports additional bindings needed by the plugin
19 | Map getDataModel();
20 |
21 | // additional jersey resource package list if needed
22 | String getJerseyResourcePackageList();
23 |
24 | // Guice modules that need to be added to the injector
25 | List getGuiceModules();
26 |
27 | // controls if the module should be visible/enabled in admin console
28 | boolean isEnabled();
29 |
30 | // should it be visible (by rendering page template as defined above)
31 | boolean isVisible();
32 | }
33 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesFilter.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 | import java.util.Set;
7 |
8 | import javax.inject.Inject;
9 | import javax.servlet.ServletException;
10 |
11 | import com.google.inject.Injector;
12 | import com.netflix.explorers.providers.FreemarkerTemplateProvider;
13 | import com.netflix.explorers.providers.WebApplicationExceptionMapper;
14 | import com.sun.jersey.api.core.PackagesResourceConfig;
15 | import com.sun.jersey.api.core.ResourceConfig;
16 | import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
17 | import com.sun.jersey.spi.container.servlet.WebConfig;
18 |
19 | import netflix.admin.AdminFreemarkerTemplateProvider;
20 |
21 | /**
22 | * This class is a minimal simulation of GuiceFilter. Due to the number of
23 | * statics used in GuiceFilter, there cannot be more than one in an application.
24 | * The AdminResources app needs minimal features and this class provides those.
25 | */
26 | class AdminResourcesFilter extends GuiceContainer {
27 | private Map props = Collections.emptyMap();
28 |
29 | @Inject
30 | AdminResourcesFilter(Injector injector) {
31 | super(injector);
32 | }
33 |
34 | @Override
35 | protected ResourceConfig getDefaultResourceConfig(Map props,
36 | WebConfig webConfig) throws ServletException {
37 | HashMap mergedProps = new HashMap<>(props);
38 | mergedProps.putAll(this.props);
39 | return new PackagesResourceConfig(mergedProps) {
40 | @Override
41 | public Set> getProviderClasses() {
42 | Set> providers = super.getProviderClasses();
43 | // remove conflicting provider if present
44 | providers.remove(FreemarkerTemplateProvider.class);
45 | providers.add(AdminFreemarkerTemplateProvider.class);
46 | providers.add(WebApplicationExceptionMapper.class);
47 | return providers;
48 | }
49 | };
50 | }
51 |
52 | public void setProperties(Map props) {
53 | this.props = new HashMap<>(props);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/KaryonAdminModule.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import javax.inject.Named;
4 |
5 | import com.google.inject.AbstractModule;
6 | import com.google.inject.Provides;
7 |
8 | public class KaryonAdminModule extends AbstractModule {
9 |
10 | public static final String ADMIN_RESOURCES_SERVER_PORT = "adminResourcesServerPort";
11 |
12 | @Override
13 | protected void configure() {
14 | bind(AdminResourcesContainer.class).asEagerSingleton();
15 | }
16 |
17 | @Provides
18 | @Named(ADMIN_RESOURCES_SERVER_PORT)
19 | public int adminListenPort(AdminResourcesContainer adminResourcesContainer) {
20 | return adminResourcesContainer.getServerPort();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/java/netflix/adminresources/RedirectFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.adminresources;
18 |
19 | import com.google.inject.Inject;
20 | import com.google.inject.Singleton;
21 | import netflix.admin.RedirectRules;
22 |
23 | import javax.servlet.*;
24 | import javax.servlet.http.HttpServletRequest;
25 | import javax.servlet.http.HttpServletResponse;
26 | import java.io.IOException;
27 | import java.util.Map;
28 |
29 | @Singleton
30 | public class RedirectFilter implements Filter {
31 |
32 | private RedirectRules redirectRules;
33 |
34 | @Inject
35 | public RedirectFilter(RedirectRules redirectRules) {
36 | this.redirectRules = redirectRules;
37 | }
38 |
39 | @Override
40 | public void destroy() {
41 | }
42 |
43 | @Override
44 | public void doFilter(ServletRequest request, ServletResponse response,
45 | FilterChain chain) throws IOException, ServletException {
46 | HttpServletRequest httpRequest = (HttpServletRequest) request;
47 | final String requestURI = httpRequest.getRequestURI();
48 |
49 | // redirect based on a simple table lookup
50 | final Map mappings = redirectRules.getMappings();
51 | for (Map.Entry mapping : mappings.entrySet()) {
52 | if (requestURI.equals(mapping.getKey())) {
53 | ((HttpServletResponse) response).sendRedirect(mapping.getValue());
54 | return;
55 | }
56 | }
57 |
58 | // redirect based on a custom logic for request
59 | final String redirectTo = redirectRules.getRedirect(httpRequest);
60 | if (redirectTo != null && !redirectTo.isEmpty() && !redirectTo.equals(requestURI)) {
61 | ((HttpServletResponse) response).sendRedirect(redirectTo);
62 | return;
63 | }
64 |
65 | chain.doFilter(httpRequest, response);
66 | }
67 |
68 | @Override
69 | public void init(FilterConfig config) throws ServletException {
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/resources/admin-explorers.properties:
--------------------------------------------------------------------------------
1 | com.netflix.explorers.environmentName=test
2 | com.netflix.explorers.applicationName=Admin
3 | com.netflix.explorers.applicationVersion=1.0
4 | com.netflix.explorers.currentRegion=us-east-1
5 |
--------------------------------------------------------------------------------
/karyon2-admin/src/main/resources/baseserver-explorer.properties:
--------------------------------------------------------------------------------
1 | com.netflix.explorers.baseserver.title=Admin Resources
2 | com.netflix.explorers.baseserver.pageLayout=bootstrap
3 | com.netflix.explorers.baseserver.description=Admin web resources
4 |
5 |
--------------------------------------------------------------------------------
/karyon2-admin/src/test/java/netflix/admin/AdminUtilsTest.java:
--------------------------------------------------------------------------------
1 | package netflix.admin;
2 |
3 |
4 | import com.netflix.explorers.PropertiesGlobalModelContext;
5 | import org.junit.Test;
6 |
7 | import java.util.Properties;
8 |
9 | import static junit.framework.Assert.assertTrue;
10 |
11 | public class AdminUtilsTest {
12 |
13 | @Test
14 | public void environmentPropertyLoaded() {
15 | final Properties properties = AdminUtils.loadAdminConsoleProps();
16 | assertTrue(properties.getProperty(PropertiesGlobalModelContext.PROPERTY_ENVIRONMENT_NAME) != null);
17 | }
18 |
19 | @Test
20 | public void regionPropertyLoaded() {
21 | final Properties properties = AdminUtils.loadAdminConsoleProps();
22 | assertTrue(properties.getProperty(PropertiesGlobalModelContext.PROPERTY_CURRENT_REGION) != null);
23 | }
24 |
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/karyon2-admin/src/test/java/netflix/adminresources/AuthFilter.java:
--------------------------------------------------------------------------------
1 | package netflix.adminresources;
2 |
3 | import javax.servlet.*;
4 | import javax.servlet.http.HttpServletRequest;
5 | import javax.servlet.http.HttpServletResponse;
6 | import java.io.IOException;
7 |
8 | public class AuthFilter implements Filter {
9 | @Override
10 | public void init(FilterConfig filterConfig) throws ServletException {}
11 |
12 | @Override
13 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
14 | if (request instanceof HttpServletRequest) {
15 | String url = ((HttpServletRequest)request).getRequestURI();
16 | if (url.startsWith("/main") || url.startsWith("/auth")) {
17 | ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
18 | }
19 | chain.doFilter(request, response);
20 | }
21 | }
22 |
23 | @Override
24 | public void destroy() {
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/karyon2-admin/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2012 Netflix, Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | log4j.rootLogger=INFO, console
18 |
19 | log4j.appender.console=org.apache.log4j.ConsoleAppender
20 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
21 | log4j.appender.console.layout.ConversionPattern=%d %-5p %c{1}:%L %x %m [%t]%n
22 |
--------------------------------------------------------------------------------
/karyon2-archaius/README.md:
--------------------------------------------------------------------------------
1 | karyon-eureka
2 | ======
3 |
4 | This module provides integration with [Archaius](https://github.com/Netflix/archaius)
5 |
6 | ##### @ArchaiusBootstrap
7 |
8 | This annotation is the integration with archiaus and sets up the necessary bindings using [ArchaiusSuite](src/main/java/netflix/karyon/archaius/ArchaiusSuite.java)
9 |
10 | See the [hello world example](../karyon2-examples/hello-netflix-oss) for a sample.
11 |
--------------------------------------------------------------------------------
/karyon2-archaius/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | compile project(':karyon2-governator')
20 | compile 'com.netflix.archaius:archaius-core:0.7.2'
21 | compile "com.netflix.governator:governator-archaius:$governator_version"
22 | }
23 |
24 | jar {
25 | manifest {
26 | name = 'karyon2-archaius'
27 | instruction 'Bundle-Vendor', 'Netflix'
28 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
29 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/karyon2-archaius/src/main/java/netflix/karyon/archaius/ArchaiusBootstrap.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.archaius;
2 |
3 | import com.netflix.governator.guice.annotations.Bootstrap;
4 |
5 | import java.lang.annotation.Documented;
6 | import java.lang.annotation.ElementType;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author Nitesh Kant
12 | */
13 | @Documented
14 | @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
15 | @Target({ElementType.TYPE})
16 | @Bootstrap(bootstrap = ArchaiusBootstrapModule.class)
17 | public @interface ArchaiusBootstrap {
18 |
19 | Class extends PropertiesLoader> loader() default DefaultPropertiesLoader.class;
20 | }
--------------------------------------------------------------------------------
/karyon2-archaius/src/main/java/netflix/karyon/archaius/PropertiesLoader.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.archaius;
2 |
3 | /**
4 | * @author Nitesh Kant
5 | */
6 | public interface PropertiesLoader {
7 |
8 | void load();
9 | }
10 |
--------------------------------------------------------------------------------
/karyon2-core/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | compile "io.reactivex:rxnetty-contexts:${rxnetty_version}"
20 | }
21 |
22 | jar {
23 | manifest {
24 | name = 'karyon2-core'
25 | instruction 'Bundle-Vendor', 'Netflix'
26 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
27 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/health/AlwaysHealthyHealthCheck.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.health;
18 |
19 | /**
20 | * Default health check handler implementation which always returns healthy. There is always a single instance of this
21 | * class which can be obtained via {@link #INSTANCE}
22 | *
23 | * @author Nitesh Kant
24 | */
25 | public class AlwaysHealthyHealthCheck implements HealthCheckHandler {
26 |
27 | public static final AlwaysHealthyHealthCheck INSTANCE = new AlwaysHealthyHealthCheck();
28 |
29 | public AlwaysHealthyHealthCheck() {
30 | }
31 |
32 | @Override
33 | public int getStatus() {
34 | return 200;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/health/HealthCheckHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.health;
18 |
19 | /**
20 | * This is an extension to the callback handler
21 | * in eureka to provide a
22 | * more flexible health check response (an HTTP status code) as a healthcheck request.
23 | *
24 | * This healthcheck handler is also used to have a fixed healthcheck endpoint created by karyon.
25 | *
26 | * @author Nitesh Kant
27 | */
28 | public interface HealthCheckHandler {
29 |
30 | /**
31 | * Checks the health of the application and returns a status code, which can be directly consumed as a HTTP status
32 | * code.
33 | * Kayon considers any status code >= 200 and < 300 as healthy.
34 | *
35 | * @return The health status of the application.
36 | */
37 | int getStatus();
38 | }
39 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/health/HealthCheckInvocationStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.health;
18 |
19 | import java.util.concurrent.TimeoutException;
20 |
21 | /**
22 | * A strategy to make application specific healthchecks. Since, the application health checks can be poorly implemented
23 | * and hence take a long time to complete, in some cases, it is wise to have an SLA around the health check response
24 | * times.
25 | * There is a 1:1 mapping between a strategy instance and a {@link HealthCheckHandler} instance and hence it is assumed
26 | * that the strategy already knows about the handler instance.
27 | *
28 | * @author Nitesh Kant
29 | */
30 | public interface HealthCheckInvocationStrategy {
31 |
32 | /**
33 | * Invokes the handler associated with this strategy and returns the response. This method may block waiting for results.
34 | * If this strategy supports timeouts, this call must not wait more than the timeout value.
35 | *
36 | * @return The health check result.
37 | *
38 | * @throws TimeoutException If the healthcheck did not return after the stipulated time (governed entirely by this
39 | * strategy implementation)
40 | */
41 | int invokeCheck() throws TimeoutException;
42 |
43 | /**
44 | * Returns the instance of {@link HealthCheckHandler} associated with this strategy.
45 | *
46 | * @return The instance of {@link HealthCheckHandler} associated with this strategy.
47 | */
48 | HealthCheckHandler getHandler();
49 | }
50 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/KaryonTransport.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport;
2 |
3 | import io.reactivex.netty.contexts.RxContexts;
4 | import io.reactivex.netty.protocol.http.server.HttpServer;
5 | import io.reactivex.netty.protocol.http.server.HttpServerBuilder;
6 | import io.reactivex.netty.protocol.http.server.RequestHandler;
7 | import netflix.karyon.transport.http.HttpRequestHandler;
8 |
9 | /**
10 | * A factory class for creating karyon transport servers which are created using
11 | * RxNetty
12 | *
13 | * @author Nitesh Kant
14 | */
15 | public final class KaryonTransport {
16 |
17 | public static final String DEFAULT_REQUEST_ID_CTX_KEY = "X-Karyon-REQUEST_ID";
18 |
19 | static {
20 | RxContexts.useRequestIdContextKey(DEFAULT_REQUEST_ID_CTX_KEY);
21 | }
22 |
23 | private KaryonTransport() {
24 | }
25 |
26 | public static HttpServerBuilder newHttpServerBuilder(int port, RequestHandler router) {
27 | return RxContexts.newHttpServerBuilder(port, new HttpRequestHandler(router), RxContexts.DEFAULT_CORRELATOR);
28 | }
29 |
30 | public static HttpServerBuilder newHttpServerBuilder(int port, HttpRequestHandler requestHandler) {
31 | return RxContexts.newHttpServerBuilder(port, requestHandler, RxContexts.DEFAULT_CORRELATOR);
32 | }
33 |
34 | public static HttpServer newHttpServer(int port, RequestHandler router) {
35 | return newHttpServerBuilder(port, router).build();
36 | }
37 |
38 | public static HttpServer newHttpServer(int port, HttpRequestHandler requestHandler) {
39 | return newHttpServerBuilder(port, requestHandler).build();
40 | }
41 |
42 | /**
43 | * Karyon
44 | *
45 | * @param name The name of the context key to be used as default.
46 | */
47 | public static void useRequestIdContextKey(String name) {
48 | RxContexts.useRequestIdContextKey(name);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/RequestRouter.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport;
2 |
3 | import rx.Observable;
4 |
5 | /**
6 | * @author Nitesh Kant
7 | *
8 | * @deprecated Use RxNetty's {@link io.reactivex.netty.channel.Handler} instead.
9 | */
10 | @Deprecated
11 | public interface RequestRouter {
12 |
13 | Observable route(I request, O response);
14 | }
15 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/HttpInterceptorKey.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
4 | import netflix.karyon.transport.interceptor.InterceptorKey;
5 |
6 | /**
7 | * @author Nitesh Kant
8 | */
9 | public interface HttpInterceptorKey extends InterceptorKey, HttpKeyEvaluationContext> {
10 | }
11 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/HttpInterceptorSupport.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.netty.handler.codec.http.HttpMethod;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
6 | import netflix.karyon.transport.interceptor.AbstractAttacher;
7 | import netflix.karyon.transport.interceptor.AbstractInterceptorSupport;
8 | import netflix.karyon.transport.interceptor.InterceptorKey;
9 |
10 | /**
11 | * An extension of {@link netflix.karyon.transport.interceptor.InterceptorSupport} to add HTTP specific methods for attaching interceptors.
12 | *
13 | * @author Nitesh Kant
14 | */
15 | public class HttpInterceptorSupport extends
16 | AbstractInterceptorSupport, HttpServerResponse, HttpKeyEvaluationContext,
17 | HttpInterceptorSupport.HttpAttacher, HttpInterceptorSupport> {
18 |
19 | @Override
20 | protected HttpAttacher newAttacher(InterceptorKey, HttpKeyEvaluationContext> key) {
21 | return new HttpAttacher(this, key);
22 | }
23 |
24 | public HttpAttacher forUri(String uri) {
25 | if (null == uri || uri.isEmpty()) {
26 | throw new IllegalArgumentException("Uri can not be null or empty.");
27 | }
28 | return getAttacherForKey(new ServletStyleUriConstraintKey(uri, ""));
29 | }
30 |
31 | public HttpAttacher forUriRegex(String uriRegEx) {
32 | if (null == uriRegEx || uriRegEx.isEmpty()) {
33 | throw new IllegalArgumentException("Uri regular expression can not be null or empty.");
34 | }
35 | return getAttacherForKey(new RegexUriConstraintKey(uriRegEx));
36 | }
37 |
38 | public HttpAttacher forHttpMethod(HttpMethod method) {
39 | if (null == method) {
40 | throw new IllegalArgumentException("Uri can not be null or empty.");
41 | }
42 | return getAttacherForKey(new MethodConstraintKey(method));
43 | }
44 |
45 | public static class HttpAttacher
46 | extends AbstractAttacher, HttpServerResponse, HttpKeyEvaluationContext,
47 | HttpInterceptorSupport> {
48 |
49 | public HttpAttacher(HttpInterceptorSupport support,
50 | InterceptorKey, HttpKeyEvaluationContext> key) {
51 | super(support, key);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/HttpRequestHandler.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
4 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
5 | import io.reactivex.netty.protocol.http.server.RequestHandler;
6 | import netflix.karyon.transport.interceptor.AbstractInterceptorSupport;
7 | import netflix.karyon.transport.interceptor.InterceptorExecutor;
8 | import rx.Observable;
9 |
10 | /**
11 | * An implementation of {@link RequestHandler} for karyon.
12 | *
13 | * @author Nitesh Kant
14 | */
15 | public class HttpRequestHandler implements RequestHandler {
16 |
17 | private final InterceptorExecutor, HttpServerResponse, HttpKeyEvaluationContext> executor;
18 |
19 | public HttpRequestHandler(RequestHandler router) {
20 | this(router, new HttpInterceptorSupport());
21 | }
22 |
23 | public HttpRequestHandler(RequestHandler router,
24 | AbstractInterceptorSupport, HttpServerResponse, HttpKeyEvaluationContext, ?, ?> interceptorSupport) {
25 | executor = new InterceptorExecutor, HttpServerResponse, HttpKeyEvaluationContext>(interceptorSupport, router);
26 | }
27 |
28 | @Override
29 | public Observable handle(HttpServerRequest request, HttpServerResponse response) {
30 | return executor.execute(request, response, new HttpKeyEvaluationContext(response.getChannel()));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/HttpRequestHandlerBuilder.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.netty.handler.codec.http.HttpMethod;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.RequestHandler;
6 | import netflix.karyon.transport.interceptor.InterceptorKey;
7 |
8 | /**
9 | * A convenience builder to create {@link HttpRequestHandler} instances.
10 | *
11 | * @author Nitesh Kant
12 | */
13 | public class HttpRequestHandlerBuilder {
14 |
15 | private final HttpInterceptorSupport interceptorSupport;
16 | private final RequestHandler router;
17 |
18 | public HttpRequestHandlerBuilder(RequestHandler router) {
19 | this(new HttpInterceptorSupport(), router);
20 | }
21 |
22 | public HttpRequestHandlerBuilder(HttpInterceptorSupport interceptorSupport,
23 | RequestHandler router) {
24 | this.interceptorSupport = interceptorSupport;
25 | this.router = router;
26 | }
27 |
28 | public HttpInterceptorSupport.HttpAttacher forKey(InterceptorKey, HttpKeyEvaluationContext> key) {
29 | return interceptorSupport.forKey(key);
30 | }
31 |
32 | public HttpInterceptorSupport.HttpAttacher forUri(String uri) {
33 | return interceptorSupport.forUri(uri);
34 | }
35 |
36 | public HttpInterceptorSupport.HttpAttacher forUriRegex(String uriRegEx) {
37 | return interceptorSupport.forUriRegex(uriRegEx);
38 | }
39 |
40 | public HttpInterceptorSupport.HttpAttacher forHttpMethod(HttpMethod method) {
41 | return interceptorSupport.forHttpMethod(method);
42 | }
43 |
44 | public HttpInterceptorSupport getInterceptorSupport() {
45 | return interceptorSupport;
46 | }
47 |
48 | public RequestHandler getRouter() {
49 | return router;
50 | }
51 |
52 | public HttpRequestHandler build() {
53 | interceptorSupport.finish();
54 | return new HttpRequestHandler(router, interceptorSupport);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/MethodConstraintKey.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.netty.handler.codec.http.HttpMethod;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * @author Nitesh Kant
10 | */
11 | public class MethodConstraintKey implements HttpInterceptorKey {
12 |
13 | private static final Logger logger = LoggerFactory.getLogger(MethodConstraintKey.class);
14 |
15 | private final HttpMethod method;
16 |
17 | public MethodConstraintKey(HttpMethod method) {
18 | if (null == method) {
19 | throw new NullPointerException("HTTP method in the interceptor constraint can not be null.");
20 | }
21 | this.method = method;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "MethodConstraintKey{" + "method=" + method + '}';
27 | }
28 |
29 | @Override
30 | public boolean apply(HttpServerRequest request, HttpKeyEvaluationContext context) {
31 | boolean matches = request.getHttpMethod().equals(method);
32 | if (logger.isDebugEnabled()) {
33 | logger.debug("Result for HTTP method constraint for method {} and required method {} : {}",
34 | request.getHttpMethod(), method, matches);
35 | }
36 |
37 | return matches;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/QueryStringDecoder.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | /**
4 | * A simple wrapper over {@link io.netty.handler.codec.http.QueryStringDecoder} to also provide access to the uri string.
5 | *
6 | * @author Nitesh Kant
7 | */
8 | public class QueryStringDecoder {
9 |
10 | private final io.netty.handler.codec.http.QueryStringDecoder nettyDecoder;
11 | private final String uri;
12 |
13 | public QueryStringDecoder(String uri) {
14 | if (null == uri) {
15 | throw new NullPointerException("Uri can not be null.");
16 | }
17 | this.uri = uri;
18 | uri = io.netty.handler.codec.http.QueryStringDecoder.decodeComponent(uri);
19 | if (!uri.endsWith("/") && !uri.contains(".") && !uri.contains("?")) {
20 | // Normalize the URI for better matching of Servlet style URI constraints.
21 | uri += "/";
22 | }
23 | nettyDecoder = new io.netty.handler.codec.http.QueryStringDecoder(uri);
24 | }
25 |
26 | public io.netty.handler.codec.http.QueryStringDecoder nettyDecoder() {
27 | return nettyDecoder;
28 | }
29 |
30 | public String uri() {
31 | return uri;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/http/RegexUriConstraintKey.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.http;
2 |
3 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.regex.Matcher;
8 | import java.util.regex.Pattern;
9 |
10 | /**
11 | * Provides constraint implementation for {@link netflix.karyon.transport.interceptor.InterceptorKey} for matching URI paths as regular expressions as
12 | * supported by {@link java.util.regex.Pattern}.
13 | * The request URI path is as retrieved using: {@link HttpKeyEvaluationContext#getRequestUriPath(HttpServerRequest)}
14 | *
15 | * @author Nitesh Kant
16 | */
17 | public class RegexUriConstraintKey implements HttpInterceptorKey {
18 |
19 | private static final Logger logger = LoggerFactory.getLogger(RegexUriConstraintKey.class);
20 |
21 | private final Pattern regEx;
22 |
23 | public RegexUriConstraintKey(String constraint) {
24 | if (null == constraint) {
25 | throw new NullPointerException("Constraint can not be null.");
26 | }
27 | regEx = Pattern.compile(constraint);
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "RegexUriConstraintKey{" + "regEx=" + regEx + '}';
33 | }
34 |
35 | @Override
36 | public boolean apply(HttpServerRequest request, HttpKeyEvaluationContext context) {
37 | String requestUriPath = context.getRequestUriPath(request);
38 | boolean matches = false;
39 | if (null != requestUriPath) {
40 | Matcher matcher = regEx.matcher(requestUriPath);
41 | matches = matcher.matches();
42 | }
43 | if (logger.isDebugEnabled()) {
44 | logger.debug("Result for regex based uri constraint for uri path {} and pattern {} : {}", requestUriPath,
45 | regEx, matches);
46 | }
47 | return matches;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/AbstractAttacher.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | /**
7 | * @author Nitesh Kant
8 | */
9 | public class AbstractAttacher {
10 |
11 | protected final S interceptorSupport;
12 | protected final InterceptorKey key;
13 |
14 | public AbstractAttacher(S interceptorSupport, InterceptorKey key) {
15 | this.interceptorSupport = interceptorSupport;
16 | this.key = key;
17 | }
18 |
19 | @SuppressWarnings({"unchecked", "rawtypes"})
20 | public S intercept(InboundInterceptor... interceptors) {
21 | List list = interceptorSupport.getInboundInterceptors();
22 | list.add(new InterceptorHolder>(key, Arrays.asList(interceptors)));
23 | return interceptorSupport;
24 | }
25 |
26 | @SuppressWarnings({"unchecked", "rawtypes"})
27 | public S intercept(OutboundInterceptor... interceptors) {
28 | List list = interceptorSupport.getOutboundInterceptors();
29 | list.add(new InterceptorHolder>(key, Arrays.asList(interceptors)));
30 | return interceptorSupport;
31 | }
32 |
33 | @SuppressWarnings({"unchecked", "rawtypes"})
34 | public S intercept(DuplexInterceptor... interceptors) {
35 | List ins = interceptorSupport.getInboundInterceptors();
36 | ins.add(new InterceptorHolder(key, Arrays.asList(interceptors)));
37 | List outs = interceptorSupport.getOutboundInterceptors();
38 | outs.add(new InterceptorHolder(key, Arrays.asList(interceptors)));
39 | return interceptorSupport;
40 | }
41 |
42 | public InterceptorKey getKey() {
43 | return key;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/DuplexInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | /**
4 | *
5 | * @author Nitesh Kant
6 | */
7 | public interface DuplexInterceptor extends InboundInterceptor, OutboundInterceptor {
8 | }
9 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/InboundInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | import rx.Observable;
4 |
5 | /**
6 | * @author Nitesh Kant
7 | */
8 | public interface InboundInterceptor {
9 |
10 | Observable in(I request, O response);
11 | }
12 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/InterceptorHolder.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author Nitesh Kant
7 | */
8 | public class InterceptorHolder {
9 |
10 | private final InterceptorKey key;
11 | private final List interceptors;
12 |
13 | public InterceptorHolder(InterceptorKey key, List interceptors) {
14 | this.key = key;
15 | this.interceptors = interceptors;
16 | }
17 |
18 | public InterceptorKey getKey() {
19 | return key;
20 | }
21 |
22 | public List getInterceptors() {
23 | return interceptors;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/InterceptorKey.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | /**
4 | * Key for a {@link InboundInterceptor} or {@link OutboundInterceptor} which determines whether a interceptor must
5 | * be applied for a particular request.
6 | * Any implementation for the key must be aware that it will be invoked for every request so it should always optimize
7 | * for speed of evaluation.
8 | *
9 | * @author Nitesh Kant
10 | */
11 | public interface InterceptorKey {
12 |
13 | /**
14 | * This is invoked for a request to determine whether the interceptor attached to this key must be executed for this
15 | * request.
16 | *
17 | * @param request Request to determine whether the attached interceptor is to be applied or not.
18 | * @param context Context for the key evaluation, usually used to cache costly operations like parsing request
19 | * URI.
20 | *
21 | * @return {@code true} if the interceptor must be applied for this request.
22 | */
23 | boolean apply(I request, C context);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/InterceptorSupport.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | /**
4 | * A contract to support interceptors for requests i.e. how to attach filters to a request processing.
5 | *
6 | * @author Nitesh Kant
7 | */
8 | public class InterceptorSupport
9 | extends AbstractInterceptorSupport, InterceptorSupport> {
10 |
11 | @Override
12 | protected Attacher newAttacher(InterceptorKey key) {
13 | return new Attacher(this, key);
14 | }
15 |
16 | public static class Attacher
17 | extends AbstractAttacher> {
18 |
19 | public Attacher(InterceptorSupport interceptorSupport, InterceptorKey key) {
20 | super(interceptorSupport, key);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/KeyEvaluationContext.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | import io.netty.channel.Channel;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * A context to store results of costly operations during evaluation of filter keys, eg: request URI parsing.
10 | * This context is not thread-safe.
11 | */
12 | public class KeyEvaluationContext {
13 |
14 | protected final Channel channel;
15 |
16 | public KeyEvaluationContext(Channel channel) {
17 | this.channel = channel;
18 | }
19 |
20 | enum KeyEvaluationResult { Apply, Skip, NotExecuted }
21 |
22 | private final Map, Boolean> keyEvaluationCache = new HashMap, Boolean>();
23 |
24 | protected void updateKeyEvaluationResult(InterceptorKey, ?> key, boolean result) {
25 | keyEvaluationCache.put(key, result);
26 | }
27 |
28 | protected KeyEvaluationResult getEvaluationResult(InterceptorKey, ?> key) {
29 | Boolean result = keyEvaluationCache.get(key);
30 | return null == result ? KeyEvaluationResult.NotExecuted
31 | : result ? KeyEvaluationResult.Apply : KeyEvaluationResult.Skip;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-core/src/main/java/netflix/karyon/transport/interceptor/OutboundInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport.interceptor;
2 |
3 | import rx.Observable;
4 |
5 | /**
6 | * @author Nitesh Kant
7 | */
8 | public interface OutboundInterceptor {
9 |
10 | Observable out(O response);
11 | }
12 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/http/InterceptorConstraintTestBase.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.http;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.handler.codec.http.DefaultHttpRequest;
5 | import io.netty.handler.codec.http.HttpMethod;
6 | import io.netty.handler.codec.http.HttpVersion;
7 | import io.reactivex.netty.protocol.http.UnicastContentSubject;
8 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
9 | import netflix.karyon.server.MockChannelHandlerContext;
10 | import netflix.karyon.transport.http.HttpKeyEvaluationContext;
11 | import netflix.karyon.transport.interceptor.InterceptorKey;
12 |
13 | /**
14 | * @author Nitesh Kant
15 | */
16 | public class InterceptorConstraintTestBase {
17 |
18 | protected static boolean doApplyForGET(InterceptorKey, HttpKeyEvaluationContext> key, String uri) {
19 | return doApply(key, uri, HttpMethod.GET);
20 | }
21 |
22 | protected static boolean doApply(InterceptorKey, HttpKeyEvaluationContext> key, String uri,
23 | HttpMethod httpMethod) {
24 | DefaultHttpRequest nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_0, httpMethod, uri);
25 | return key.apply(new HttpServerRequest(nettyRequest,
26 | UnicastContentSubject.createWithoutNoSubscriptionTimeout()),
27 | new HttpKeyEvaluationContext(new MockChannelHandlerContext("mock").channel()));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/http/MethodConstraintTest.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.http;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.handler.codec.http.HttpMethod;
5 | import netflix.karyon.transport.http.MethodConstraintKey;
6 | import org.junit.Assert;
7 | import org.junit.Test;
8 |
9 | /**
10 | * @author Nitesh Kant
11 | */
12 | public class MethodConstraintTest extends InterceptorConstraintTestBase {
13 |
14 | @Test
15 | public void testMethodConstraint() throws Exception {
16 | MethodConstraintKey key = new MethodConstraintKey(HttpMethod.HEAD);
17 | boolean keyApplicable = doApply(key, "a/b/c", HttpMethod.HEAD);
18 | Assert.assertTrue("Http Method style constraint failed.", keyApplicable);
19 | }
20 |
21 | @Test
22 | public void testMethodConstraintFail() throws Exception {
23 | MethodConstraintKey key = new MethodConstraintKey(HttpMethod.HEAD);
24 | boolean keyApplicable = doApply(key, "a/b/c", HttpMethod.GET);
25 | Assert.assertFalse("Http Method style constraint failed.", keyApplicable);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/http/RegExConstraintTest.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.http;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import netflix.karyon.transport.http.RegexUriConstraintKey;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | /**
9 | * @author Nitesh Kant
10 | */
11 | public class RegExConstraintTest extends InterceptorConstraintTestBase {
12 |
13 | @Test
14 | public void testRegExConstraint() throws Exception {
15 | RegexUriConstraintKey key = new RegexUriConstraintKey("a/.*");
16 | boolean keyApplicable = doApplyForGET(key, "a/b/c");
17 | Assert.assertTrue("Regex style constraint failed.", keyApplicable);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/interceptor/MockKey.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.interceptor;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import netflix.karyon.transport.interceptor.InterceptorKey;
5 | import netflix.karyon.transport.interceptor.KeyEvaluationContext;
6 |
7 | /**
8 | * @author Nitesh Kant
9 | */
10 | class MockKey implements InterceptorKey {
11 |
12 | private final boolean result;
13 |
14 | public MockKey(boolean result) {
15 | this.result = result;
16 | }
17 |
18 | @Override
19 | public boolean apply(ByteBuf request, KeyEvaluationContext context) {
20 | return result;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/interceptor/TestableDuplexInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.interceptor;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import netflix.karyon.server.MockChannelHandlerContext;
5 | import netflix.karyon.transport.interceptor.DuplexInterceptor;
6 | import netflix.karyon.transport.interceptor.InterceptorKey;
7 | import netflix.karyon.transport.interceptor.KeyEvaluationContext;
8 | import rx.Observable;
9 |
10 | /**
11 | * @author Nitesh Kant
12 | */
13 | public class TestableDuplexInterceptor implements DuplexInterceptor {
14 |
15 | private final InterceptorKey filterKey;
16 | private volatile boolean inCalled;
17 | private volatile boolean outCalled;
18 | private volatile boolean wasLastInCallValid;
19 | private volatile boolean wasLastOutCallValid;
20 |
21 | @SuppressWarnings("unchecked")
22 | public TestableDuplexInterceptor(InterceptorKey filterKey) {
23 | this.filterKey = filterKey;
24 | }
25 |
26 | public boolean isCalledForIn() {
27 | return inCalled;
28 | }
29 |
30 | public boolean isCalledForOut() {
31 | return outCalled;
32 | }
33 |
34 | public boolean wasLastInCallValid() {
35 | return wasLastInCallValid;
36 | }
37 |
38 | public boolean wasLastOutCallValid() {
39 | return wasLastOutCallValid;
40 | }
41 |
42 | @Override
43 | public Observable in(ByteBuf request, ByteBuf response) {
44 | inCalled = true;
45 | MockChannelHandlerContext mock = new MockChannelHandlerContext("mock");
46 | wasLastInCallValid = filterKey.apply(request, new KeyEvaluationContext(mock.channel()));
47 | return Observable.empty();
48 | }
49 |
50 | @Override
51 | public Observable out(ByteBuf response) {
52 | outCalled = true;
53 | wasLastOutCallValid = filterKey.apply(response, new KeyEvaluationContext(new MockChannelHandlerContext("").channel()));
54 | return Observable.empty();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/interceptor/TestableInboundInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.interceptor;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import netflix.karyon.server.MockChannelHandlerContext;
5 | import netflix.karyon.transport.interceptor.InboundInterceptor;
6 | import netflix.karyon.transport.interceptor.InterceptorKey;
7 | import netflix.karyon.transport.interceptor.KeyEvaluationContext;
8 | import rx.Observable;
9 |
10 | /**
11 | * @author Nitesh Kant
12 | */
13 | class TestableInboundInterceptor implements InboundInterceptor {
14 |
15 | private final InterceptorKey filterKey;
16 | private volatile boolean wasLastCallValid;
17 | private volatile boolean receivedACall;
18 |
19 | public TestableInboundInterceptor(InterceptorKey filterKey) {
20 | this.filterKey = filterKey;
21 | }
22 |
23 | public boolean wasLastCallValid() {
24 | return wasLastCallValid;
25 | }
26 |
27 | boolean isReceivedACall() {
28 | return receivedACall;
29 | }
30 |
31 | @Override
32 | public Observable in(ByteBuf request, ByteBuf response) {
33 | MockChannelHandlerContext context = new MockChannelHandlerContext("mock");
34 | wasLastCallValid = filterKey.apply(request, new KeyEvaluationContext(context.channel()));
35 | receivedACall = true;
36 | return Observable.empty();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/interceptor/TestableOutboundInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.interceptor;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import netflix.karyon.transport.interceptor.InterceptorKey;
5 | import netflix.karyon.transport.interceptor.KeyEvaluationContext;
6 |
7 | /**
8 | * @author Nitesh Kant
9 | */
10 | public class TestableOutboundInterceptor extends TestableDuplexInterceptor {
11 |
12 | public TestableOutboundInterceptor(InterceptorKey filterKey) {
13 | super(filterKey);
14 | }
15 |
16 | public boolean isReceivedACall() {
17 | return isCalledForOut();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/karyon2-core/src/test/java/netflix/karyon/server/interceptor/TestableRequestRouter.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.server.interceptor;
2 |
3 | import io.reactivex.netty.channel.Handler;
4 | import rx.Observable;
5 | import rx.functions.Action0;
6 |
7 | /**
8 | * @author Nitesh Kant
9 | */
10 | class TestableRequestRouter implements Handler {
11 |
12 | private volatile boolean called;
13 | private volatile boolean unsubscribed;
14 |
15 | public boolean isReceivedACall() {
16 | return called;
17 | }
18 |
19 | public boolean isUnsubscribed() {
20 | return unsubscribed;
21 | }
22 |
23 | @Override
24 | public Observable handle(I input, O output) {
25 | called = true;
26 | return Observable.empty().doOnUnsubscribe(new Action0() {
27 | @Override
28 | public void call() {
29 | unsubscribed = true;
30 | }
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-eureka/README.md:
--------------------------------------------------------------------------------
1 | karyon-eureka
2 | ======
3 |
4 | This module provides integration with [Eureka](https://github.com/Netflix/eureka)
5 |
6 | #### KaryonEurekaModule
7 |
8 | Install this in your application to guice to enable eureka.
9 |
10 | See the [hello world example](../karyon-examples/hello-netflix-oss) for a sample.
--------------------------------------------------------------------------------
/karyon2-eureka/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | compile project(':karyon2-governator')
20 | compile "com.netflix.eureka:eureka-client:${eureka_version}"
21 | }
22 |
23 | jar {
24 | manifest {
25 | name = 'karyon2-eureka'
26 | instruction 'Bundle-Vendor', 'Netflix'
27 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
28 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/karyon2-eureka/src/main/java/netflix/karyon/eureka/DefaultEurekaKaryonStatusBridge.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.eureka;
2 |
3 | import com.netflix.appinfo.InstanceInfo;
4 |
5 | /**
6 | * @author Nitesh Kant
7 | */
8 | public class DefaultEurekaKaryonStatusBridge implements EurekaKaryonStatusBridge {
9 |
10 | @Override
11 | public InstanceInfo.InstanceStatus interpretKaryonStatus(int karyonStatus) {
12 | if(karyonStatus == 204) {
13 | return InstanceInfo.InstanceStatus.STARTING;
14 | } else if (karyonStatus >= 200 && karyonStatus < 300) {
15 | return InstanceInfo.InstanceStatus.UP;
16 | }
17 |
18 | return InstanceInfo.InstanceStatus.DOWN;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/karyon2-eureka/src/main/java/netflix/karyon/eureka/EurekaHealthCheckHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.eureka;
18 |
19 | import com.netflix.appinfo.InstanceInfo;
20 | import netflix.karyon.health.HealthCheckHandler;
21 |
22 | import javax.inject.Inject;
23 |
24 | /**
25 | * @author Nitesh Kant
26 | */
27 | public class EurekaHealthCheckHandler implements com.netflix.appinfo.HealthCheckHandler {
28 |
29 | private final HealthCheckHandler healthCheckHandler;
30 | private final EurekaKaryonStatusBridge eurekaKaryonStatusBridge;
31 |
32 | @Inject
33 | public EurekaHealthCheckHandler(HealthCheckHandler healthCheckHandler,
34 | EurekaKaryonStatusBridge eurekaKaryonStatusBridge) {
35 | this.healthCheckHandler = healthCheckHandler;
36 | this.eurekaKaryonStatusBridge = eurekaKaryonStatusBridge;
37 | }
38 |
39 | @Override
40 | public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) {
41 | int healthStatus = healthCheckHandler.getStatus();
42 | return eurekaKaryonStatusBridge.interpretKaryonStatus(healthStatus);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/karyon2-eureka/src/main/java/netflix/karyon/eureka/EurekaKaryonStatusBridge.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.eureka;
2 |
3 | import com.google.inject.ImplementedBy;
4 | import com.netflix.appinfo.InstanceInfo;
5 |
6 | /**
7 | * @author Nitesh Kant
8 | */
9 | @ImplementedBy(DefaultEurekaKaryonStatusBridge.class)
10 | public interface EurekaKaryonStatusBridge {
11 |
12 | InstanceInfo.InstanceStatus interpretKaryonStatus(int karyonStatus);
13 | }
14 |
--------------------------------------------------------------------------------
/karyon2-eureka/src/main/java/netflix/karyon/eureka/KaryonEurekaModule.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.eureka;
2 |
3 | import com.google.inject.AbstractModule;
4 | import com.google.inject.binder.LinkedBindingBuilder;
5 | import com.netflix.appinfo.ApplicationInfoManager;
6 | import com.netflix.appinfo.EurekaInstanceConfig;
7 | import com.netflix.appinfo.providers.CloudInstanceConfigProvider;
8 | import com.netflix.discovery.DiscoveryClient;
9 | import com.netflix.discovery.EurekaClientConfig;
10 | import com.netflix.discovery.EurekaNamespace;
11 | import com.netflix.discovery.providers.DefaultEurekaClientConfigProvider;
12 | import com.netflix.governator.guice.BootstrapModule;
13 | import netflix.karyon.Karyon;
14 |
15 | /**
16 | * Initialize Eureka, by binding the "eureka." namespace and adding providers for EurekaClientConfig
17 | * and EurekaInstanceConfig.
18 | *
19 | * @author Nitesh Kant
20 | */
21 | public class KaryonEurekaModule extends AbstractModule {
22 |
23 | private final String eurekaNamespace;
24 |
25 | public KaryonEurekaModule() {
26 | this("eureka.");
27 | }
28 |
29 | public KaryonEurekaModule(String eurekaNamespace) {
30 | this.eurekaNamespace = eurekaNamespace;
31 | }
32 |
33 | @Override
34 | protected void configure() {
35 | bind(com.netflix.appinfo.HealthCheckHandler.class).to(EurekaHealthCheckHandler.class);
36 | bind(ApplicationInfoManager.class).asEagerSingleton();
37 | bind(DiscoveryClient.class).asEagerSingleton();
38 |
39 | configureEureka();
40 | }
41 |
42 | protected void configureEureka() {
43 | bindEurekaNamespace().toInstance(eurekaNamespace);
44 | bindEurekaInstanceConfig().toProvider(CloudInstanceConfigProvider.class);
45 | bindEurekaClientConfig().toProvider(DefaultEurekaClientConfigProvider.class);
46 | }
47 |
48 | protected LinkedBindingBuilder bindEurekaInstanceConfig() {
49 | return bind(EurekaInstanceConfig.class);
50 | }
51 |
52 | protected LinkedBindingBuilder bindEurekaClientConfig() {
53 | return bind(EurekaClientConfig.class);
54 | }
55 |
56 | protected LinkedBindingBuilder bindEurekaNamespace() {
57 | return bind(String.class).annotatedWith(EurekaNamespace.class);
58 | }
59 |
60 | public static BootstrapModule asBootstrapModule() {
61 | return Karyon.toBootstrapModule(KaryonEurekaModule.class);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/karyon2-examples/README.md:
--------------------------------------------------------------------------------
1 | Karyon Examples
2 | ================
3 |
4 | This module provides a catalog for the variety of ways to interact with karyon.
5 |
6 | Examples Catalog
7 | ================
8 |
9 | Category | Example | Description
10 | -------------------|----------------------------------------------------------------------------------------------|------------
11 | Simple URI Routing | [Annotation based](src/main/java/netflix/karyon/examples/hellonoss/server/simple/annotation) | A simple URI based routing application that uses karyon's annotation based bootstrapping model.
12 | Simple URI Routing | [Guice module based](src/main/java/netflix/karyon/examples/hellonoss/server/simple/module) | A simple URI based routing application that uses karyon's guice modules based bootstrapping model.
13 | Jersey | [Annotation based](src/main/java/netflix/karyon/examples/hellonoss/server/jersey) | An example of how to use blocking jersey resources inside karyon.
14 | RxNetty | [Guice module based](src/main/java/netflix/karyon/examples/hellonoss/server/rxnetty) | An example of how to directly use an RxNetty based `RequestHandler` inside karyon.
15 | TCP | [Karyon TCP server](src/main/java/netflix/karyon/examples/tcp) | An example of how to create a raw TCP karyon server.
16 | WebSockets | [Karyon WebSocket Echo server](src/main/java/netflix/karyon/examples/websockets) | An example of WebSockets server.
17 |
18 | Build
19 | =====
20 |
21 | To build:
22 |
23 | ```
24 | $ cd karyon/karyon-examples
25 | $ ../gradlew build
26 | ```
27 |
28 | Run
29 | ===
30 |
31 | It is possible to run these examples using Gradle. For list of available tasks check "Examples" group
32 | in the gradle task list:
33 |
34 | ```
35 | $ ../gradlew tasks
36 | ```
37 |
38 | For example to run the simple URI router example run the following command:
39 |
40 | ```
41 | $ ../gradlew runSimpleRouterHelloNOSS
42 | ```
43 |
44 | Some of the examples require parameters. They must be passed with ```-P=``` option.
45 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/common/LoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.common;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
6 | import netflix.karyon.transport.interceptor.DuplexInterceptor;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import rx.Observable;
10 |
11 | /**
12 | * @author Nitesh Kant
13 | */
14 | public class LoggingInterceptor implements DuplexInterceptor, HttpServerResponse> {
15 |
16 | private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
17 |
18 | private static int count;
19 | private final int id;
20 |
21 | public LoggingInterceptor() {
22 | id = ++count;
23 | }
24 |
25 | @Override
26 | public Observable in(HttpServerRequest request, HttpServerResponse response) {
27 | logger.info("Logging interceptor with id {} invoked for direction IN.", id);
28 | return Observable.empty();
29 | }
30 |
31 | @Override
32 | public Observable out(HttpServerResponse response) {
33 | logger.info("Logging interceptor with id {} invoked for direction OUT.", id);
34 | return Observable.empty();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/common/auth/AuthInterceptor.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.common.auth;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
6 | import netflix.karyon.transport.interceptor.InboundInterceptor;
7 | import rx.Observable;
8 | import rx.functions.Func1;
9 |
10 | import javax.inject.Inject;
11 |
12 | /**
13 | * @author Nitesh Kant
14 | */
15 | public class AuthInterceptor implements InboundInterceptor, HttpServerResponse> {
16 |
17 | private final AuthenticationService authService;
18 |
19 | @Inject
20 | public AuthInterceptor(AuthenticationService authService) {
21 | this.authService = authService;
22 | }
23 |
24 | @Override
25 | public Observable in(HttpServerRequest request, HttpServerResponse response) {
26 | return authService.authenticate(request).map(new Func1() {
27 | @Override
28 | public Void call(Boolean aBoolean) {
29 | return null;
30 | }
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/common/auth/AuthenticationService.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.common.auth;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import rx.Observable;
6 |
7 | /**
8 | * @author Nitesh Kant
9 | */
10 | public interface AuthenticationService {
11 |
12 | Observable authenticate(HttpServerRequest request);
13 | }
14 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/common/auth/AuthenticationServiceImpl.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.common.auth;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import rx.Observable;
6 |
7 | /**
8 | * @author Nitesh Kant
9 | */
10 | public class AuthenticationServiceImpl implements AuthenticationService {
11 |
12 | public static final String AUTH_HEADER_NAME = "MY-USER-ID";
13 |
14 | @Override
15 | public Observable authenticate(HttpServerRequest request) {
16 | if (request.getHeaders().contains(AUTH_HEADER_NAME)) {
17 | return Observable.just(Boolean.TRUE);
18 | } else {
19 | return Observable.error(new IllegalArgumentException("Should pass a header: " + AUTH_HEADER_NAME));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/common/health/HealthCheck.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.examples.hellonoss.common.health;
18 |
19 | import com.google.inject.Singleton;
20 | import netflix.karyon.health.HealthCheckHandler;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 |
24 | import javax.annotation.PostConstruct;
25 |
26 | /**
27 | * @author Nitesh Kant (nkant@netflix.com)
28 | */
29 | @Singleton
30 | public class HealthCheck implements HealthCheckHandler {
31 |
32 | private static final Logger logger = LoggerFactory.getLogger(HealthCheck.class);
33 |
34 | @PostConstruct
35 | public void init() {
36 | logger.info("Health check initialized.");
37 | }
38 |
39 | @Override
40 | public int getStatus() {
41 | // TODO: Health check logic.
42 | logger.info("Health check invoked.");
43 | return 200;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/jersey/HealthcheckResource.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.jersey;
2 |
3 | import com.google.inject.Inject;
4 | import netflix.karyon.health.HealthCheckHandler;
5 |
6 | import javax.ws.rs.GET;
7 | import javax.ws.rs.Path;
8 | import javax.ws.rs.Produces;
9 | import javax.ws.rs.core.MediaType;
10 | import javax.ws.rs.core.Response;
11 |
12 | /**
13 | * @author Nitesh Kant
14 | */
15 | @Path("/healthcheck")
16 | public class HealthcheckResource {
17 |
18 | private final HealthCheckHandler healthCheckHandler;
19 |
20 | @Inject
21 | public HealthcheckResource(HealthCheckHandler healthCheckHandler) {
22 | this.healthCheckHandler = healthCheckHandler;
23 | }
24 |
25 | @GET
26 | @Produces(MediaType.APPLICATION_JSON)
27 | public Response healthcheck() {
28 | return Response.status(healthCheckHandler.getStatus()).build();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/jersey/JerseyHelloWorldApp.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.jersey;
2 |
3 | import com.netflix.governator.annotations.Modules;
4 | import netflix.adminresources.resources.KaryonWebAdminModule;
5 | import netflix.karyon.KaryonBootstrap;
6 | import netflix.karyon.ShutdownModule;
7 | import netflix.karyon.archaius.ArchaiusBootstrap;
8 | import netflix.karyon.examples.hellonoss.common.LoggingInterceptor;
9 | import netflix.karyon.examples.hellonoss.common.auth.AuthInterceptor;
10 | import netflix.karyon.examples.hellonoss.common.auth.AuthenticationService;
11 | import netflix.karyon.examples.hellonoss.common.auth.AuthenticationServiceImpl;
12 | import netflix.karyon.examples.hellonoss.common.health.HealthCheck;
13 | import netflix.karyon.examples.hellonoss.server.jersey.JerseyHelloWorldApp.KaryonJerseyModuleImpl;
14 | import netflix.karyon.jersey.blocking.KaryonJerseyModule;
15 | import netflix.karyon.servo.KaryonServoModule;
16 |
17 | @ArchaiusBootstrap
18 | @KaryonBootstrap(name = "hello-netflix-oss", healthcheck = HealthCheck.class)
19 | @Modules(include = {
20 | ShutdownModule.class,
21 | KaryonWebAdminModule.class,
22 | // KaryonEurekaModule.class, // Uncomment this to enable Eureka client.
23 | KaryonJerseyModuleImpl.class,
24 | KaryonServoModule.class
25 | })
26 | public interface JerseyHelloWorldApp {
27 |
28 | class KaryonJerseyModuleImpl extends KaryonJerseyModule {
29 | @Override
30 | protected void configureServer() {
31 | bind(AuthenticationService.class).to(AuthenticationServiceImpl.class);
32 | interceptorSupport().forUri("/*").intercept(LoggingInterceptor.class);
33 | interceptorSupport().forUri("/hello").interceptIn(AuthInterceptor.class);
34 | server().port(8888).threadPoolSize(100);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/jersey/README.md:
--------------------------------------------------------------------------------
1 | Hello Netflix OSS (Jersey)
2 | ======
3 |
4 | A helloworld using jersey based endpoints.
5 |
6 | Apart from the common modules used by all examples, this example uses the following karyon module:
7 |
8 | * _[karyon-jersey-blocking](../../karyon-jersey-blocking) extension_: For jersey based resources.
9 |
10 | Running the example
11 | ===================
12 |
13 | This example can be run using gradle.
14 |
15 | `../gradlew runJerseyHelloNOSS`
16 |
17 | What to see
18 | ===========
19 |
20 | After the server starts, you can use the following commands to verify the server's endpoints:
21 |
22 | * _Hello to 'newbee'_:
23 |
24 | ```
25 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/to/newbee"
26 | ```
27 | Which will produce the output:
28 | ```
29 | {"Message":"Hello newbee from Netflix OSS"}
30 | ```
31 |
32 | * _Hello to Anonymous_:
33 |
34 | ```
35 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/"
36 | ```
37 | Which will produce the output:
38 | ```
39 | {"Message":"Hello from Netflix OSS"}
40 | ```
41 |
42 | * _Healthcheck_:
43 |
44 | ```
45 | curl -v "http://localhost:8888/healthcheck"
46 | ```
47 | Which will produce the output:
48 | ```
49 | > GET /healthcheck HTTP/1.1
50 | > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
51 | > Host: localhost:8888
52 | > Accept: */*
53 | >
54 | < HTTP/1.1 200 OK
55 | < Content-Type: application/json
56 | < Transfer-Encoding: chunked
57 | <
58 | ```
59 |
60 | This demonstrate the healthcheck endpoint added by this application and using karyon's `HealthCheckHandler` contract.
61 |
62 | * _Admin console_
63 |
64 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
65 |
66 | This will take you to the karyon admin user interface.
67 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/rxnetty/MyApplicationRunner.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.rxnetty;
2 |
3 | import netflix.adminresources.resources.KaryonWebAdminModule;
4 | import netflix.karyon.Karyon;
5 | import netflix.karyon.KaryonBootstrapModule;
6 | import netflix.karyon.ShutdownModule;
7 | import netflix.karyon.archaius.ArchaiusBootstrapModule;
8 | import netflix.karyon.examples.hellonoss.common.health.HealthCheck;
9 | import netflix.karyon.servo.KaryonServoModule;
10 | import netflix.karyon.transport.http.health.HealthCheckEndpoint;
11 |
12 | /**
13 | * @author Nitesh Kant
14 | */
15 | public class MyApplicationRunner {
16 |
17 | public static void main(String[] args) {
18 | HealthCheck healthCheckHandler = new HealthCheck();
19 | Karyon.forRequestHandler(8888,
20 | new RxNettyHandler("/healthcheck",
21 | new HealthCheckEndpoint(healthCheckHandler)),
22 | new KaryonBootstrapModule(healthCheckHandler),
23 | new ArchaiusBootstrapModule("hello-netflix-oss"),
24 | // KaryonEurekaModule.asBootstrapModule(), /* Uncomment if you need eureka */
25 | Karyon.toBootstrapModule(KaryonWebAdminModule.class),
26 | ShutdownModule.asBootstrapModule(),
27 | KaryonServoModule.asBootstrapModule()
28 | ).startAndWaitTillShutdown();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/rxnetty/README.md:
--------------------------------------------------------------------------------
1 | Hello Netflix OSS (RxNetty)
2 | ======
3 |
4 | This helloworld example demonstrates how to directly use an [RxNetty](https://github.com/ReactiveX/RxNetty)
5 | `RequestHandler` inside karyon and still leverage all bootstrapping facilities of karyon.
6 |
7 | Running the example
8 | ===================
9 |
10 | This example can be run using gradle.
11 |
12 | `../gradlew runPureRxNettyHelloNOSS`
13 |
14 | What to see
15 | ===========
16 |
17 | After the server starts, you can use the following commands to verify the server's endpoints:
18 |
19 | * _Hello to 'newbee'_:
20 |
21 | ```
22 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/to/newbee"
23 | ```
24 | Which will produce the output:
25 | ```
26 | {"Message":"Hello newbee from Netflix OSS"}
27 | ```
28 |
29 | * _Hello to Anonymous_:
30 |
31 | ```
32 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/"
33 | ```
34 | Which will produce the output:
35 | ```
36 | {"Message":"Hello from Netflix OSS"}
37 | ```
38 |
39 | * _Healthcheck_:
40 |
41 | ```
42 | curl -v "http://localhost:8888/healthcheck"
43 | ```
44 | Which will produce the output:
45 | ```
46 | > GET /healthcheck HTTP/1.1
47 | > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
48 | > Host: localhost:8888
49 | > Accept: */*
50 | >
51 | < HTTP/1.1 200 OK
52 | < Content-Type: application/json
53 | < Transfer-Encoding: chunked
54 | <
55 | ```
56 |
57 | This demonstrate the healthcheck endpoint added by this application and using karyon's `HealthCheckHandler` contract.
58 |
59 | * _Admin console_
60 |
61 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
62 |
63 | This will take you to the karyon admin user interface.
64 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/rxnetty/RxNettyHandler.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.rxnetty;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.handler.codec.http.HttpResponseStatus;
5 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
6 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
7 | import io.reactivex.netty.protocol.http.server.RequestHandler;
8 | import netflix.karyon.transport.http.health.HealthCheckEndpoint;
9 | import rx.Observable;
10 |
11 | /**
12 | * @author Nitesh Kant
13 | */
14 | public class RxNettyHandler implements RequestHandler {
15 |
16 | private final String healthCheckUri;
17 | private final HealthCheckEndpoint healthCheckEndpoint;
18 |
19 | public RxNettyHandler(String healthCheckUri, HealthCheckEndpoint healthCheckEndpoint) {
20 | this.healthCheckUri = healthCheckUri;
21 | this.healthCheckEndpoint = healthCheckEndpoint;
22 | }
23 |
24 | @Override
25 | public Observable handle(HttpServerRequest request, HttpServerResponse response) {
26 | if (request.getUri().startsWith(healthCheckUri)) {
27 | return healthCheckEndpoint.handle(request, response);
28 | } else if (request.getUri().startsWith("/hello/to/")) {
29 | int prefixLength = "/hello/to".length();
30 | String userName = request.getPath().substring(prefixLength);
31 | if (userName.isEmpty() || userName.length() == 1 /*The uri is /hello/to/ but no name */) {
32 | response.setStatus(HttpResponseStatus.BAD_REQUEST);
33 | return response.writeStringAndFlush(
34 | "{\"Error\":\"Please provide a username to say hello. The URI should be /hello/to/{username}\"}");
35 | } else {
36 | String msg = "Hello " + userName.substring(1) /*Remove the / prefix*/ + " from Netflix OSS";
37 | return response.writeStringAndFlush("{\"Message\":\"" + msg + "\"}");
38 | }
39 | } else if (request.getUri().startsWith("/hello")) {
40 | return response.writeStringAndFlush("{\"Message\":\"Hello newbee from Netflix OSS\"}");
41 | } else {
42 | response.setStatus(HttpResponseStatus.NOT_FOUND);
43 | return response.close();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/HelloWorldEndpoint.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.simple;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.handler.codec.http.HttpResponseStatus;
5 | import io.reactivex.netty.channel.StringTransformer;
6 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
7 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
8 | import org.codehaus.jettison.json.JSONException;
9 | import org.codehaus.jettison.json.JSONObject;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import rx.Observable;
13 |
14 | /**
15 | * @author Tomasz Bak
16 | */
17 | public class HelloWorldEndpoint {
18 |
19 | private static final Logger logger = LoggerFactory.getLogger(HelloWorldEndpoint.class);
20 |
21 | public Observable sayHello(HttpServerResponse response) {
22 | JSONObject content = new JSONObject();
23 | try {
24 | content.put("Message", "Hello from Netflix OSS");
25 | response.write(content.toString(), StringTransformer.DEFAULT_INSTANCE);
26 | return response.close();
27 | } catch (JSONException e) {
28 | logger.error("Error creating json response.", e);
29 | return Observable.error(e);
30 | }
31 | }
32 |
33 | public Observable sayHelloToUser(HttpServerRequest request, HttpServerResponse response) {
34 | JSONObject content = new JSONObject();
35 |
36 | int prefixLength = "/hello/to".length();
37 | String userName = request.getPath().substring(prefixLength);
38 |
39 | try {
40 | if (userName.isEmpty() || userName.length() == 1 /*The uri is /hello/to/ but no name */) {
41 | response.setStatus(HttpResponseStatus.BAD_REQUEST);
42 | content.put("Error", "Please provide a username to say hello. The URI should be /hello/to/{username}");
43 | } else {
44 | content.put("Message", "Hello " + userName.substring(1) /*Remove the / prefix*/ + " from Netflix OSS");
45 | }
46 | } catch (JSONException e) {
47 | logger.error("Error creating json response.", e);
48 | return Observable.error(e);
49 | }
50 |
51 | response.write(content.toString(), StringTransformer.DEFAULT_INSTANCE);
52 | return response.close();
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/README.md:
--------------------------------------------------------------------------------
1 | Hello Netflix OSS (Simple Routing)
2 | ======
3 |
4 | This helloworld example demonstrates how to use karyon's simple but powerful [SimpleUriRouter](https://github.com/Netflix/karyon/blob/master/karyon-core/src/main/java/com/netflix/karyon/transport/http/SimpleUriRouter.java)
5 | to provide HTTP endpoints.
6 |
7 | This module demonstrates how one can use karyon's annotation based bootstrapping and guice modules based bootstrapping
8 | as provided by [karyon-governator](https://github.com/Netflix/karyon/tree/master/karyon-governator)
9 |
10 | Running the example
11 | ===================
12 |
13 | This example can be run using gradle.
14 |
15 | * _Annotation based bootstrapping_:
16 |
17 | `../gradlew runSimpleRouterAnnotationHelloNOSS`
18 |
19 | * _Guice modules based bootstrapping_:
20 |
21 | `../gradlew runSimpleRouterGuiceHelloNOSS`
22 |
23 | What to see
24 | ===========
25 |
26 | After the server starts, you can use the following commands to verify the server's endpoints:
27 |
28 | * _Hello to 'newbee'_:
29 |
30 | ```
31 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/to/newbee"
32 | ```
33 | Which will produce the output:
34 | ```
35 | {"Message":"Hello newbee from Netflix OSS"}
36 | ```
37 |
38 | * _Hello to Anonymous_:
39 |
40 | ```
41 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/"
42 | ```
43 | Which will produce the output:
44 | ```
45 | {"Message":"Hello from Netflix OSS"}
46 | ```
47 |
48 | * _Healthcheck_:
49 |
50 | ```
51 | curl -v "http://localhost:8888/healthcheck"
52 | ```
53 | Which will produce the output:
54 | ```
55 | > GET /healthcheck HTTP/1.1
56 | > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
57 | > Host: localhost:8888
58 | > Accept: */*
59 | >
60 | < HTTP/1.1 200 OK
61 | < Content-Type: application/json
62 | < Transfer-Encoding: chunked
63 | <
64 | ```
65 |
66 | This demonstrate the healthcheck endpoint added by this application and using karyon's `HealthCheckHandler` contract.
67 |
68 | * _Admin console_
69 |
70 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
71 |
72 | This will take you to the karyon admin user interface.
73 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/SimpleRouter.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.simple;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
6 | import io.reactivex.netty.protocol.http.server.RequestHandler;
7 | import netflix.karyon.examples.hellonoss.common.health.HealthCheck;
8 | import netflix.karyon.transport.http.SimpleUriRouter;
9 | import netflix.karyon.transport.http.health.HealthCheckEndpoint;
10 | import rx.Observable;
11 |
12 | /**
13 | * A {@link RequestHandler} implementation for this example.
14 | *
15 | * @author Nitesh Kant
16 | */
17 | public class SimpleRouter implements RequestHandler {
18 |
19 | private final SimpleUriRouter delegate;
20 |
21 | public SimpleRouter() {
22 | final HelloWorldEndpoint endpoint = new HelloWorldEndpoint();
23 | delegate = new SimpleUriRouter();
24 |
25 | delegate.addUri("/healthcheck",
26 | new HealthCheckEndpoint(new HealthCheck()))
27 | .addUri("/hello",
28 | new RequestHandler() {
29 | @Override
30 | public Observable handle(
31 | HttpServerRequest request,
32 | HttpServerResponse response) {
33 | return endpoint.sayHello(response);
34 | }
35 | })
36 | .addUri("/hello/to/*",
37 | new RequestHandler() {
38 | @Override
39 | public Observable handle(HttpServerRequest request,
40 | HttpServerResponse response) {
41 | return endpoint.sayHelloToUser(request, response);
42 | }
43 | });
44 | }
45 |
46 | @Override
47 | public Observable handle(HttpServerRequest request, HttpServerResponse response) {
48 | return delegate.handle(request, response);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/annotation/README.md:
--------------------------------------------------------------------------------
1 | Hello Netflix OSS (Simple Routing - Annotations based bootstrapping)
2 | ======
3 |
4 | This helloworld example demonstrates how to use karyon's simple but powerful [SimpleUriRouter](https://github.com/Netflix/karyon/blob/master/karyon-core/src/main/java/com/netflix/karyon/transport/http/SimpleUriRouter.java)
5 | to provide HTTP endpoints.
6 |
7 | This module uses karyon's annotation based bootstrapping as provided by [karyon-governator](https://github.com/Netflix/karyon/tree/master/karyon-governator)
8 |
9 | Running the example
10 | ===================
11 |
12 | This example can be run using gradle.
13 |
14 | `../gradlew runSimpleRouterAnnotationHelloNOSS`
15 |
16 | What to see
17 | ===========
18 |
19 | After the server starts, you can use the following commands to verify the server's endpoints:
20 |
21 | * _Hello to 'newbee'_:
22 |
23 | ```
24 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/to/newbee"
25 | ```
26 | Which will produce the output:
27 | ```
28 | {"Message":"Hello newbee from Netflix OSS"}
29 | ```
30 |
31 | * _Hello to Anonymous_:
32 |
33 | ```
34 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/"
35 | ```
36 | Which will produce the output:
37 | ```
38 | {"Message":"Hello from Netflix OSS"}
39 | ```
40 |
41 | * _Healthcheck_:
42 |
43 | ```
44 | curl -v "http://localhost:8888/healthcheck"
45 | ```
46 | Which will produce the output:
47 | ```
48 | > GET /healthcheck HTTP/1.1
49 | > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
50 | > Host: localhost:8888
51 | > Accept: */*
52 | >
53 | < HTTP/1.1 200 OK
54 | < Content-Type: application/json
55 | < Transfer-Encoding: chunked
56 | <
57 | ```
58 |
59 | This demonstrate the healthcheck endpoint added by this application and using karyon's `HealthCheckHandler` contract.
60 |
61 | * _Admin console_
62 |
63 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
64 |
65 | This will take you to the karyon admin user interface.
66 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/annotation/SimpleRoutingApp.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.simple.annotation;
2 |
3 | import com.google.inject.Singleton;
4 | import com.netflix.governator.annotations.Modules;
5 | import io.netty.buffer.ByteBuf;
6 | import netflix.adminresources.resources.KaryonWebAdminModule;
7 | import netflix.karyon.KaryonBootstrap;
8 | import netflix.karyon.ShutdownModule;
9 | import netflix.karyon.archaius.ArchaiusBootstrap;
10 | import netflix.karyon.examples.hellonoss.common.LoggingInterceptor;
11 | import netflix.karyon.examples.hellonoss.common.auth.AuthInterceptor;
12 | import netflix.karyon.examples.hellonoss.common.auth.AuthenticationService;
13 | import netflix.karyon.examples.hellonoss.common.auth.AuthenticationServiceImpl;
14 | import netflix.karyon.examples.hellonoss.common.health.HealthCheck;
15 | import netflix.karyon.examples.hellonoss.server.simple.SimpleRouter;
16 | import netflix.karyon.examples.hellonoss.server.simple.annotation.SimpleRoutingApp.KaryonRxRouterModuleImpl;
17 | import netflix.karyon.servo.KaryonServoModule;
18 | import netflix.karyon.transport.http.KaryonHttpModule;
19 |
20 | /**
21 | * @author Tomasz Bak
22 | */
23 | @ArchaiusBootstrap
24 | @KaryonBootstrap(name = "hello-netflix-oss", healthcheck = HealthCheck.class)
25 | @Singleton
26 | @Modules(include = {
27 | ShutdownModule.class,
28 | KaryonServoModule.class,
29 | KaryonWebAdminModule.class,
30 | // KaryonEurekaModule.class, // Uncomment this to enable Eureka client.
31 | KaryonRxRouterModuleImpl.class
32 | })
33 | public interface SimpleRoutingApp {
34 |
35 | class KaryonRxRouterModuleImpl extends KaryonHttpModule {
36 |
37 | public KaryonRxRouterModuleImpl() {
38 | super("httpServerA", ByteBuf.class, ByteBuf.class);
39 | }
40 |
41 | @Override
42 | protected void configureServer() {
43 | bindRouter().toInstance(new SimpleRouter());
44 |
45 | bind(AuthenticationService.class).to(AuthenticationServiceImpl.class);
46 | interceptorSupport().forUri("/*").intercept(LoggingInterceptor.class);
47 | interceptorSupport().forUri("/hello").interceptIn(AuthInterceptor.class);
48 |
49 | server().port(8888);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/module/README.md:
--------------------------------------------------------------------------------
1 | Hello Netflix OSS (Simple Routing - Guice module based bootstrapping)
2 | ======
3 |
4 | This helloworld example demonstrates how to use karyon's simple but powerful [SimpleUriRouter](https://github.com/Netflix/karyon/blob/master/karyon-core/src/main/java/com/netflix/karyon/transport/http/SimpleUriRouter.java)
5 | to provide HTTP endpoints.
6 |
7 | This module uses karyon's guice module based bootstrapping as provided by [karyon-governator](https://github.com/Netflix/karyon/tree/master/karyon-governator)
8 |
9 | Running the example
10 | ===================
11 |
12 | This example can be run using gradle.
13 |
14 | `../gradlew runSimpleRouterGuiceHelloNOSS`
15 |
16 | What to see
17 | ===========
18 |
19 | After the server starts, you can use the following commands to verify the server's endpoints:
20 |
21 | * _Hello to 'newbee'_:
22 |
23 | ```
24 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/to/newbee"
25 | ```
26 | Which will produce the output:
27 | ```
28 | {"Message":"Hello newbee from Netflix OSS"}
29 | ```
30 |
31 | * _Hello to Anonymous_:
32 |
33 | ```
34 | curl -H"MY-USER-ID: nkant" "http://localhost:8888/hello/"
35 | ```
36 | Which will produce the output:
37 | ```
38 | {"Message":"Hello from Netflix OSS"}
39 | ```
40 |
41 | * _Healthcheck_:
42 |
43 | ```
44 | curl -v "http://localhost:8888/healthcheck"
45 | ```
46 | Which will produce the output:
47 | ```
48 | > GET /healthcheck HTTP/1.1
49 | > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
50 | > Host: localhost:8888
51 | > Accept: */*
52 | >
53 | < HTTP/1.1 200 OK
54 | < Content-Type: application/json
55 | < Transfer-Encoding: chunked
56 | <
57 | ```
58 |
59 | This demonstrate the healthcheck endpoint added by this application and using karyon's `HealthCheckHandler` contract.
60 |
61 | * _Admin console_
62 |
63 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
64 |
65 | This will take you to the karyon admin user interface.
66 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/module/RouterWithInterceptors.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.simple.module;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.reactivex.netty.protocol.http.server.HttpServerRequest;
5 | import io.reactivex.netty.protocol.http.server.HttpServerResponse;
6 | import io.reactivex.netty.protocol.http.server.RequestHandler;
7 | import netflix.karyon.examples.hellonoss.common.LoggingInterceptor;
8 | import netflix.karyon.examples.hellonoss.common.auth.AuthInterceptor;
9 | import netflix.karyon.examples.hellonoss.common.auth.AuthenticationServiceImpl;
10 | import netflix.karyon.examples.hellonoss.server.simple.SimpleRouter;
11 | import netflix.karyon.transport.http.HttpInterceptorSupport;
12 | import netflix.karyon.transport.http.HttpRequestHandler;
13 | import rx.Observable;
14 |
15 | /**
16 | * @author Nitesh Kant
17 | */
18 | public class RouterWithInterceptors implements RequestHandler {
19 |
20 | private final HttpRequestHandler delegate;
21 |
22 | public RouterWithInterceptors() {
23 | SimpleRouter router = new SimpleRouter();
24 | HttpInterceptorSupport interceptorSupport = new HttpInterceptorSupport();
25 | interceptorSupport.forUri("/*").intercept(new LoggingInterceptor());
26 | interceptorSupport.forUri("/hello").intercept(new AuthInterceptor(new AuthenticationServiceImpl()));
27 | delegate = new HttpRequestHandler(router, interceptorSupport);
28 | }
29 |
30 | @Override
31 | public Observable handle(HttpServerRequest request, HttpServerResponse response) {
32 | return delegate.handle(request, response);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/simple/module/SimpleRunner.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.hellonoss.server.simple.module;
2 |
3 | import netflix.adminresources.resources.KaryonWebAdminModule;
4 | import netflix.karyon.Karyon;
5 | import netflix.karyon.KaryonBootstrapModule;
6 | import netflix.karyon.ShutdownModule;
7 | import netflix.karyon.archaius.ArchaiusBootstrapModule;
8 | import netflix.karyon.servo.KaryonServoModule;
9 |
10 | /**
11 | * @author Nitesh Kant
12 | */
13 | public class SimpleRunner {
14 |
15 | public static void main(String[] args) {
16 |
17 | Karyon.forRequestHandler(8888,
18 | // new SimpleRouter(), /* Use this instead of RouterWithInterceptors below if interceptors are not required */
19 | new RouterWithInterceptors(),
20 | new KaryonBootstrapModule(),
21 | new ArchaiusBootstrapModule("hello-netflix-oss"),
22 | // KaryonEurekaModule.asBootstrapModule(), /* Uncomment if you need eureka */
23 | Karyon.toBootstrapModule(KaryonWebAdminModule.class),
24 | ShutdownModule.asBootstrapModule(),
25 | KaryonServoModule.asBootstrapModule())
26 | .startAndWaitTillShutdown();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/tcp/README.md:
--------------------------------------------------------------------------------
1 | TCP pipeline
2 | ======
3 |
4 | It is a simple example of how to run multiple Karyon TCP servers.
5 | There are two servers created:
6 | * frontend, that reads user input and sends it an internal queue
7 | * backend, that reads messages from the internal queue and sends them out to a user
8 |
9 | Running the example
10 | ===================
11 |
12 | `../gradlew runTcpPipelineApp`
13 |
14 | What to see
15 | ===========
16 |
17 | * _Message pipeline_
18 |
19 | After the server starts, connect with telnet to frontend and backend servers:
20 | * frontend:```telnet localhost 7770```
21 | * backend: ```telnet localhost 7771```
22 |
23 | The text entered on first client, should be print out on the second one.
24 |
25 | * _Admin console_
26 |
27 | Use the URL: `http://localhost:8077/` to navigate to karyon's admin console.
28 |
29 | This will take you to the karyon admin user interface.
30 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/tcp/TcpPipelineApp.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.tcp;
2 |
3 | import com.google.inject.AbstractModule;
4 | import com.netflix.governator.annotations.Modules;
5 | import io.netty.buffer.ByteBuf;
6 | import netflix.adminresources.resources.KaryonWebAdminModule;
7 | import netflix.karyon.KaryonBootstrap;
8 | import netflix.karyon.ShutdownModule;
9 | import netflix.karyon.archaius.ArchaiusBootstrap;
10 | import netflix.karyon.examples.tcp.TcpPipelineApp.ApplicationModule;
11 | import netflix.karyon.examples.tcp.TcpPipelineApp.TcpBackendModule;
12 | import netflix.karyon.examples.tcp.TcpPipelineApp.TcpFrontendModule;
13 | import netflix.karyon.transport.tcp.KaryonTcpModule;
14 |
15 | /**
16 | * @author Tomasz Bak
17 | */
18 | @ArchaiusBootstrap
19 | @KaryonBootstrap(name = "sample-rxnetty-tcp-noss")
20 | @Modules(include = {
21 | ShutdownModule.class,
22 | KaryonWebAdminModule.class,
23 | // KaryonEurekaModule.class, // Uncomment this to enable Eureka client.
24 | ApplicationModule.class,
25 | TcpFrontendModule.class, TcpBackendModule.class
26 | })
27 | public interface TcpPipelineApp {
28 |
29 | class ApplicationModule extends AbstractModule {
30 | @Override
31 | protected void configure() {
32 | bind(TcpPipelineHandlers.QueueProvider.class).asEagerSingleton();
33 | }
34 | }
35 |
36 | class TcpFrontendModule extends KaryonTcpModule {
37 | public TcpFrontendModule() {
38 | super("tcpFrontServer", ByteBuf.class, ByteBuf.class);
39 | }
40 |
41 | @Override
42 | protected void configureServer() {
43 | bindConnectionHandler().to(TcpPipelineHandlers.FrontendConnectionHandler.class);
44 | server().port(7770);
45 | }
46 | }
47 |
48 | class TcpBackendModule extends KaryonTcpModule {
49 | public TcpBackendModule() {
50 | super("tcpBackendServer", ByteBuf.class, ByteBuf.class);
51 | }
52 |
53 | @Override
54 | protected void configureServer() {
55 | bindConnectionHandler().to(TcpPipelineHandlers.BackendConnectionHandler.class);
56 | server().port(7771);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/websockets/README.md:
--------------------------------------------------------------------------------
1 | WebSocket Example
2 | ======
3 |
4 | It is a simple example of how to run WebSocket server with Karyon.
5 |
6 | Running the example
7 | ===================
8 |
9 | `../gradlew runWebSocketEcho`
10 |
11 | What to see
12 | ===========
13 |
14 | Connect with any WebSocket client and send a text message at localhost:8888.
15 | You should get a reply with the same content, but all letters capitalized.
--------------------------------------------------------------------------------
/karyon2-examples/src/main/java/netflix/karyon/examples/websockets/WebSocketEchoServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.examples.websockets;
2 |
3 | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
4 | import io.netty.handler.codec.http.websocketx.WebSocketFrame;
5 | import io.reactivex.netty.RxNetty;
6 | import io.reactivex.netty.channel.ConnectionHandler;
7 | import io.reactivex.netty.channel.ObservableConnection;
8 | import io.reactivex.netty.server.RxServer;
9 | import netflix.adminresources.resources.KaryonWebAdminModule;
10 | import netflix.karyon.Karyon;
11 | import netflix.karyon.KaryonBootstrapModule;
12 | import netflix.karyon.ShutdownModule;
13 | import netflix.karyon.archaius.ArchaiusBootstrapModule;
14 | import netflix.karyon.servo.KaryonServoModule;
15 | import rx.Observable;
16 | import rx.functions.Func1;
17 |
18 | /**
19 | * Simple WebSockets echo server.
20 | *
21 | * @author Tomasz Bak
22 | */
23 | public final class WebSocketEchoServer {
24 |
25 | public static void main(final String[] args) {
26 | RxServer webSocketServer = RxNetty.newWebSocketServerBuilder(
27 | 8888,
28 | new ConnectionHandler() {
29 | @Override
30 | public Observable handle(final ObservableConnection connection) {
31 | return connection.getInput().flatMap(new Func1>() {
32 | @Override
33 | public Observable call(WebSocketFrame wsFrame) {
34 | TextWebSocketFrame textFrame = (TextWebSocketFrame) wsFrame;
35 | System.out.println("Got message: " + textFrame.text());
36 | return connection.writeAndFlush(new TextWebSocketFrame(textFrame.text().toUpperCase()));
37 | }
38 | });
39 | }
40 | }
41 | ).build();
42 | Karyon.forWebSocketServer(
43 | webSocketServer,
44 | new KaryonBootstrapModule(),
45 | new ArchaiusBootstrapModule("websocket-echo-server"),
46 | // KaryonEurekaModule.asBootstrapModule(), /* Uncomment if you need eureka */
47 | Karyon.toBootstrapModule(KaryonWebAdminModule.class),
48 | ShutdownModule.asBootstrapModule(),
49 | KaryonServoModule.asBootstrapModule())
50 | .startAndWaitTillShutdown();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/resources/eureka-client.properties:
--------------------------------------------------------------------------------
1 | # Eureka Client configuration for your service. These properties are used by eureka to contact the eureka server
2 | # for all eureka operations.
3 | # Properties based configuration for eureka client. The properties specified here is mostly what the users
4 | # need to change. All of these can be specified as a java system property with -D option (eg)-Deureka.region=us-east-1
5 | # Refer to eureka wiki (https://github.com/Netflix/eureka/wiki/Configuring-Eureka) for details about these configurations.
6 |
7 |
8 | #Region where eureka is deployed -For AWS specify one of the AWS regions, for other datacenters specify a arbitrary string
9 | #indicating the region.This is normally specified as a -D option (eg) -Deureka.region=us-east-1
10 | eureka.region=default
11 |
12 | #Name of the application to be identified by other services
13 |
14 | eureka.name=hello-netflix-oss
15 |
16 | #Virtual host name by which the clients identifies this service
17 | eureka.vipAddress=hello-netflix-oss.mydomain.net
18 |
19 | #The port where the service will be running and serving requests
20 | eureka.port=8001
21 |
22 | #For eureka clients running in eureka server, it needs to connect to servers in other zones
23 | eureka.preferSameZone=false
24 |
25 | #Change this if you want to use a DNS based lookup for determining other eureka servers.
26 | eureka.shouldUseDns=false
27 |
28 | eureka.us-east-1.availabilityZones=default
29 |
30 | eureka.serviceUrl.default=http://us-east-1.discoverytest.netflix.net:7001/discovery/v2/
31 |
--------------------------------------------------------------------------------
/karyon2-examples/src/main/resources/hello-netflix-oss-dev.properties:
--------------------------------------------------------------------------------
1 | eureka.validateInstanceId=false
--------------------------------------------------------------------------------
/karyon2-examples/src/main/resources/hello-netflix-oss.properties:
--------------------------------------------------------------------------------
1 | com.sun.jersey.config.property.packages=netflix.karyon.examples.hellonoss
--------------------------------------------------------------------------------
/karyon2-examples/src/main/resources/sample-rxnetty-tcp-noss.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Netflix/karyon/d50bc0ff37693ef3fbda373e90a109d1f92e0b9a/karyon2-examples/src/main/resources/sample-rxnetty-tcp-noss.properties
--------------------------------------------------------------------------------
/karyon2-examples/src/main/resources/simplelogger.properties:
--------------------------------------------------------------------------------
1 | org.slf4j.simpleLogger.defaultLogLevel=INFO
2 | org.slf4j.simplelogger.showdatetime=true
3 | org.slf4j.simplelogger.showthreadname=true
4 |
5 |
--------------------------------------------------------------------------------
/karyon2-governator/README.md:
--------------------------------------------------------------------------------
1 | karyon-governator
2 | ======
3 |
4 | This module provides bootstrapping for karyon using [Governator](https://github.com/Netflix/governator). Bootstrapping
5 | is categorized into two broad categories:
6 |
7 | #### Annotation Based
8 |
9 | This model leverages [Governators](https://github.com/Netflix/governator) `@Bootstrap` annotations to provide syntactic
10 | sugar for discovering applicable modules.
11 | Under this model, one provides all `@Bootstrap` annotations on a class/interface which is referred to as an
12 | _Application_ class and is consumed by Karyon to create a [KaryonServer](src/main/java/netflix/karyon/KaryonServer.java)
13 |
14 | An example of this model can be found under [karyon examples](../karyon2-examples)
15 |
16 | ###### KaryonRunner
17 |
18 | [KaryonRunner](src/main/java/netflix/karyon/KaryonRunner.java) is a utility class which can be used as the startup
19 | for all _Application_ classes created in this annotation based model. This class has a main method which expects an
20 | _Application_ class name to be passed as the program argument.
21 |
22 | #### Guice modules Based
23 |
24 | The annotation based model above leverages this basic guice module based bootstrapping model which requires the user to
25 | explicitly provide the guice modules which are required by the application.
26 |
27 | An example of this model can be found under[karyon examples](../karyon2-examples)
28 |
--------------------------------------------------------------------------------
/karyon2-governator/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | apply plugin: 'osgi'
17 |
18 | dependencies {
19 | compile "com.netflix.governator:governator:${governator_version}"
20 | compile project(':karyon2-core')
21 | }
22 |
23 | jar {
24 | manifest {
25 | name = 'karyon2-governator'
26 | instruction 'Bundle-Vendor', 'Netflix'
27 | instruction 'Bundle-DocURL', 'https://github.com/Netflix/karyon'
28 | instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/AbstractKaryonServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.google.inject.Injector;
4 | import com.netflix.governator.guice.BootstrapModule;
5 | import com.netflix.governator.lifecycle.LifecycleManager;
6 |
7 | import java.util.Arrays;
8 |
9 | /**
10 | * @author Nitesh Kant
11 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
12 | */
13 | @Deprecated
14 | abstract class AbstractKaryonServer implements KaryonServer {
15 |
16 | protected final BootstrapModule[] bootstrapModules;
17 | protected LifecycleManager lifecycleManager;
18 | protected Injector injector;
19 |
20 | public AbstractKaryonServer(BootstrapModule... bootstrapModules) {
21 | this.bootstrapModules = bootstrapModules;
22 | }
23 |
24 | @Override
25 | public final void start() {
26 | startWithAdditionalBootstrapModules();
27 | }
28 |
29 | public final void startWithAdditionalBootstrapModules(BootstrapModule... additionalBootstrapModules) {
30 | BootstrapModule[] applicableBootstrapModules = this.bootstrapModules;
31 | if (null != additionalBootstrapModules && additionalBootstrapModules.length != 0) {
32 | applicableBootstrapModules = Arrays.copyOf(bootstrapModules, bootstrapModules.length + additionalBootstrapModules.length);
33 | System.arraycopy(additionalBootstrapModules, 0, applicableBootstrapModules, bootstrapModules.length, additionalBootstrapModules.length);
34 | }
35 |
36 | injector = newInjector(applicableBootstrapModules);
37 |
38 | startLifecycleManager();
39 | _start();
40 | }
41 |
42 | protected abstract void _start();
43 |
44 | @Override
45 | public void shutdown() {
46 | if (lifecycleManager != null) {
47 | lifecycleManager.close();
48 | }
49 | }
50 |
51 | @Override
52 | public void startAndWaitTillShutdown() {
53 | start();
54 | waitTillShutdown();
55 | }
56 |
57 | protected abstract Injector newInjector(BootstrapModule... applicableBootstrapModules);
58 |
59 | protected void startLifecycleManager() {
60 | lifecycleManager = injector.getInstance(LifecycleManager.class);
61 | try {
62 | lifecycleManager.start();
63 | } catch (Exception e) {
64 | throw new RuntimeException(e); // So that this does not pollute the API.
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/KaryonBootstrap.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.netflix.governator.guice.annotations.Bootstrap;
4 | import netflix.karyon.health.AlwaysHealthyHealthCheck;
5 | import netflix.karyon.health.HealthCheckHandler;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | /**
14 | * @author Nitesh Kant
15 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
16 | */
17 | @Documented
18 | @Retention(RetentionPolicy.RUNTIME)
19 | @Target(ElementType.TYPE)
20 | @Bootstrap(bootstrap = KaryonBootstrapModule.class)
21 | @Deprecated
22 | public @interface KaryonBootstrap {
23 |
24 | String name();
25 |
26 | Class extends HealthCheckHandler> healthcheck() default AlwaysHealthyHealthCheck.class;
27 | }
28 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/KaryonRunner.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.netflix.governator.guice.BootstrapModule;
4 | import com.netflix.governator.guice.annotations.Bootstrap;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * An application runner which consumes a main class annotated with governator's {@link Bootstrap} annotations.
10 | *
11 | * This is shorthand for:
12 | *
13 |
14 | com.netflix.karyon.forApplication(MyApp.class).startAndWaitTillShutdown()
15 |
16 | *
17 | * where the name of the Application class is passed as the argument to the main method.
18 | *
19 | * This is useful while creating standard packaging scripts where the main class for starting the JVM remains the same
20 | * and the actual application class differs from one application to another.
21 | *
22 | * If you are bootstrapping karyon programmatically, it is better to use {@code Karyon} directly.
23 | *
24 | * @author Nitesh Kant
25 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
26 | */
27 | @Deprecated
28 | public class KaryonRunner {
29 |
30 | private static final Logger logger = LoggerFactory.getLogger(KaryonRunner.class);
31 |
32 | public static void main(String[] args) {
33 | if (args.length == 0) {
34 | System.out.println("Usage: " + KaryonRunner.class.getCanonicalName() + " ");
35 | System.exit(-1);
36 | }
37 |
38 | String mainClassName = args[0];
39 | System.out.println("Using main class: " + mainClassName);
40 |
41 | try {
42 | Karyon.forApplication(Class.forName(mainClassName), (BootstrapModule[]) null)
43 | .startAndWaitTillShutdown();
44 | } catch (@SuppressWarnings("UnusedCatchParameter") ClassNotFoundException e) {
45 | System.out.println("Main class: " + mainClassName + " not found.");
46 | System.exit(-1);
47 | } catch (Exception e) {
48 | logger.error("Error while starting karyon server.", e);
49 | System.exit(-1);
50 | }
51 |
52 | // In case we have non-daemon threads running
53 | System.exit(0);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/KaryonServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | /**
4 | * A logical abstraction to manage the lifecycle of a karyon based application.
5 | * This does not define any contracts of handling and processing requests, those should all be defined by means of
6 | * modules.
7 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
8 | */
9 | @Deprecated
10 | public interface KaryonServer {
11 |
12 | /**
13 | * Starts the server and hence the modules associated with this server.
14 | */
15 | void start();
16 |
17 | /**
18 | * Shutdown the server and hence the modules associated with this server.
19 | */
20 | void shutdown();
21 |
22 | /**
23 | * A utility method to block the caller thread till the server is shutdown (by external invocation).
24 | * This method does not start or shutdown the server. It just waits for shutdown.
25 | */
26 | void waitTillShutdown();
27 |
28 | /**
29 | * A shorthand for calling {@link #start()} and {@link #waitTillShutdown()}
30 | */
31 | void startAndWaitTillShutdown();
32 | }
33 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/KaryonServerBackedServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.netflix.governator.guice.BootstrapModule;
4 |
5 | /**
6 | * An implementation of {@link KaryonServer} which wraps an existing {@link KaryonServer}.
7 | *
8 | * @author Nitesh Kant
9 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
10 | */
11 | @Deprecated
12 | class KaryonServerBackedServer implements KaryonServer {
13 |
14 | private final AbstractKaryonServer delegate;
15 | private final BootstrapModule[] bootstrapModules;
16 |
17 | KaryonServerBackedServer(AbstractKaryonServer delegate, BootstrapModule... bootstrapModules) {
18 | this.delegate = delegate;
19 | this.bootstrapModules = bootstrapModules;
20 | }
21 |
22 | @Override
23 | public void start() {
24 | delegate.startWithAdditionalBootstrapModules(bootstrapModules);
25 | }
26 |
27 | @Override
28 | public void shutdown() {
29 | delegate.shutdown();
30 | }
31 |
32 | @Override
33 | public void waitTillShutdown() {
34 | delegate.waitTillShutdown();
35 | }
36 |
37 | @Override
38 | public void startAndWaitTillShutdown() {
39 | start();
40 | waitTillShutdown();
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/MainClassBasedServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.google.inject.Injector;
4 | import com.netflix.governator.guice.BootstrapModule;
5 | import com.netflix.governator.guice.LifecycleInjector;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.concurrent.CountDownLatch;
10 |
11 | /**
12 | * @author Nitesh Kant
13 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
14 | */
15 | @Deprecated
16 | class MainClassBasedServer extends AbstractKaryonServer {
17 |
18 | private static final Logger logger = LoggerFactory.getLogger(MainClassBasedServer.class);
19 |
20 | private final Class> mainClass;
21 |
22 | protected MainClassBasedServer(Class> mainClass, BootstrapModule... bootstrapModules) {
23 | super(bootstrapModules);
24 | this.mainClass = mainClass;
25 | }
26 |
27 | @Override
28 | public void waitTillShutdown() {
29 | final CountDownLatch shutdownFinished = new CountDownLatch(1);
30 |
31 | Runtime.getRuntime().addShutdownHook(new Thread() {
32 | @Override
33 | public void run() {
34 | try {
35 | shutdown();
36 | logger.info("Leaving main loop - shutdown finished.");
37 | } finally {
38 | shutdownFinished.countDown();
39 | }
40 | }
41 | });
42 |
43 | try {
44 | shutdownFinished.await();
45 | } catch (InterruptedException e) {
46 | logger.error("Interrupted while waiting for shutdown.", e);
47 | Thread.interrupted();
48 | throw new RuntimeException(e);
49 | }
50 | }
51 |
52 | @Override
53 | protected void _start() {
54 | // No Op.
55 | }
56 |
57 | @Override
58 | protected Injector newInjector(BootstrapModule... applicableBootstrapModules) {
59 | return LifecycleInjector.bootstrap(mainClass, applicableBootstrapModules);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/RxNettyServerBackedServer.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon;
2 |
3 | import com.netflix.governator.guice.BootstrapModule;
4 | import io.reactivex.netty.server.AbstractServer;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * An implementation of {@link KaryonServer} which wraps an RxNetty's server.
10 | *
11 | * @author Nitesh Kant
12 | * @deprecated 2016-07-20 Karyon2 no longer supported. See https://github.com/Netflix/karyon/issues/347 for more info
13 | */
14 | @Deprecated
15 | class RxNettyServerBackedServer extends MainClassBasedServer {
16 |
17 | private static final Logger logger = LoggerFactory.getLogger(RxNettyServerBackedServer.class);
18 |
19 | @SuppressWarnings("rawtypes") private final AbstractServer rxNettyServer;
20 |
21 | RxNettyServerBackedServer(AbstractServer rxNettyServer, BootstrapModule... bootstrapModules) {
22 | super(RxNettyServerBackedServer.class, bootstrapModules);
23 | this.rxNettyServer = rxNettyServer;
24 | }
25 |
26 | @Override
27 | protected void _start() {
28 | rxNettyServer.start();
29 | }
30 |
31 | @Override
32 | public void shutdown() {
33 | super.shutdown();
34 | try {
35 | rxNettyServer.shutdown();
36 | } catch (InterruptedException e) {
37 | logger.error("Interrupted while shutdown.", e);
38 | Thread.interrupted();
39 | throw new RuntimeException(e);
40 | }
41 | }
42 |
43 | @Override
44 | public void waitTillShutdown() {
45 | try {
46 | rxNettyServer.waitTillShutdown();
47 | } catch (InterruptedException e) {
48 | logger.error("Interrupted while waiting for shutdown.", e);
49 | Thread.interrupted();
50 | throw new RuntimeException(e);
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/health/SyncHealthCheckInvocationStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Netflix, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package netflix.karyon.health;
18 |
19 | import javax.inject.Inject;
20 | import java.util.concurrent.TimeoutException;
21 |
22 | /**
23 | * An implementation of {@link netflix.karyon.health.HealthCheckInvocationStrategy} that synchronously calls the underlying
24 | * {@link netflix.karyon.health.HealthCheckHandler}.
25 | *
26 | * @author Nitesh Kant
27 | */
28 | @SuppressWarnings("unused")
29 | public class SyncHealthCheckInvocationStrategy implements HealthCheckInvocationStrategy {
30 |
31 | private final HealthCheckHandler handler;
32 |
33 | @Inject
34 | public SyncHealthCheckInvocationStrategy(HealthCheckHandler handler) {
35 | this.handler = handler;
36 | }
37 |
38 | @Override
39 | public int invokeCheck() throws TimeoutException {
40 | return handler.getStatus();
41 | }
42 |
43 | @Override
44 | public HealthCheckHandler getHandler() {
45 | return handler;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/karyon2-governator/src/main/java/netflix/karyon/transport/AbstractServerModule.java:
--------------------------------------------------------------------------------
1 | package netflix.karyon.transport;
2 |
3 | import com.google.inject.AbstractModule;
4 | import com.google.inject.Key;
5 | import com.google.inject.binder.LinkedBindingBuilder;
6 | import com.google.inject.name.Named;
7 | import com.google.inject.name.Names;
8 | import io.reactivex.netty.pipeline.PipelineConfigurator;
9 | import netflix.karyon.transport.AbstractServerModule.ServerConfigBuilder;
10 |
11 | /**
12 | * @author Tomasz Bak
13 | */
14 | @SuppressWarnings("rawtypes")
15 | public abstract class AbstractServerModule extends AbstractModule {
16 |
17 | protected final Named nameAnnotation;
18 | protected final Class iType;
19 | protected final Class oType;
20 |
21 | protected final Key