├── .gitignore ├── .sbtopts ├── .scalafmt.conf ├── .travis.yml ├── LICENSE.txt ├── README.md ├── Vagrantfile ├── api └── src │ └── main │ └── scala │ └── io │ └── quckoo │ ├── api │ ├── Cluster.scala │ ├── Registry.scala │ ├── Scheduler.scala │ ├── TopicTag.scala │ └── package.scala │ ├── auth │ ├── Credentials.scala │ ├── InvalidCredentials.scala │ ├── InvalidPassport.scala │ ├── Passport.scala │ ├── Permission.scala │ ├── Principal.scala │ ├── User.scala │ ├── http │ │ └── package.scala │ └── package.scala │ ├── net │ ├── Location.scala │ ├── NodeStatus.scala │ ├── QuckooMetrics.scala │ ├── QuckooNode.scala │ └── QuckooState.scala │ └── protocol │ ├── Command.scala │ ├── Event.scala │ ├── client │ └── messages.scala │ ├── cluster │ └── messages.scala │ ├── registry │ └── messages.scala │ ├── scheduler │ └── messages.scala │ └── worker │ └── messages.scala ├── build.sbt ├── circle.yml ├── client ├── js │ └── src │ │ └── main │ │ └── scala │ │ └── io │ │ └── quckoo │ │ └── client │ │ └── http │ │ └── dom │ │ ├── Cookie.scala │ │ ├── EventSourceSubscriber.scala │ │ ├── HttpDOMBackend.scala │ │ └── package.scala ├── jvm │ └── src │ │ ├── main │ │ └── scala │ │ │ └── io │ │ │ └── quckoo │ │ │ └── client │ │ │ ├── http │ │ │ └── akka │ │ │ │ ├── HttpAkkaBackend.scala │ │ │ │ └── HttpAkkaQuckooClient.scala │ │ │ └── tcp │ │ │ └── QuckooTcpClient.scala │ │ └── test │ │ ├── resources │ │ └── log4j2.xml │ │ └── scala │ │ └── io │ │ └── quckoo │ │ └── client │ │ └── http │ │ ├── WireMock.scala │ │ └── akka │ │ └── AkkaHttpBackendSpec.scala └── shared │ └── src │ ├── main │ └── scala │ │ └── io │ │ └── quckoo │ │ └── client │ │ ├── QuckooClient.scala │ │ ├── core │ │ ├── Channel.scala │ │ ├── ChannelException.scala │ │ ├── ChannelMagnet.scala │ │ ├── Channels.scala │ │ ├── ClusterCmds.scala │ │ ├── CmdMarshalling.scala │ │ ├── Driver.scala │ │ ├── DriverBackend.scala │ │ ├── Protocol.scala │ │ ├── ProtocolSpecs.scala │ │ ├── RegistryCmds.scala │ │ ├── SchedulerCmds.scala │ │ ├── SecurityCmds.scala │ │ ├── commands.scala │ │ └── package.scala │ │ └── http │ │ ├── Http.scala │ │ ├── HttpBackend.scala │ │ ├── HttpClusterCmds.scala │ │ ├── HttpMarshalling.scala │ │ ├── HttpProtocol.scala │ │ ├── HttpRegistryCmds.scala │ │ ├── HttpSchedulerCmds.scala │ │ ├── HttpSecurityCmds.scala │ │ ├── SSEChannels.scala │ │ ├── model.scala │ │ └── package.scala │ └── test │ └── scala │ └── io │ └── quckoo │ └── client │ ├── core │ ├── StubClient.scala │ └── TestDriverBackend.scala │ └── http │ ├── HttpProtocolSpec.scala │ └── HttpRequestMatchers.scala ├── console └── src │ ├── main │ └── scala │ │ └── io │ │ └── quckoo │ │ └── console │ │ ├── ConsoleRoute.scala │ │ ├── boot │ │ ├── Boot.scala │ │ ├── ConsoleApp.scala │ │ └── ConsoleRouter.scala │ │ ├── components │ │ ├── Alert.scala │ │ ├── Button.scala │ │ ├── CodeEditor.scala │ │ ├── CoproductSelect.scala │ │ ├── DateTimeDisplay.scala │ │ ├── FiniteDurationInput.scala │ │ ├── Icon.scala │ │ ├── Icons.scala │ │ ├── Input.scala │ │ ├── Modal.scala │ │ ├── NavBar.scala │ │ ├── NavStyle.scala │ │ ├── Notification.scala │ │ ├── NotificationContainer.scala │ │ ├── Panel.scala │ │ ├── Password.scala │ │ ├── TabPanel.scala │ │ ├── Table.scala │ │ ├── TableStyle.scala │ │ ├── TextArea.scala │ │ ├── ToolBar.scala │ │ ├── ValidatedInput.scala │ │ └── package.scala │ │ ├── core │ │ ├── ActionSubscriber.scala │ │ ├── AuthHandler.scala │ │ ├── ConsoleCircuit.scala │ │ ├── ConsoleHandler.scala │ │ ├── ConsoleOps.scala │ │ ├── ConsoleScope.scala │ │ ├── ConsoleSubscriptions.scala │ │ ├── Effects.scala │ │ ├── ErrorProcessor.scala │ │ ├── EventLogProcessor.scala │ │ ├── ExecutionFetcher.scala │ │ ├── ExecutionPlanFetcher.scala │ │ ├── JobSpecFetcher.scala │ │ ├── LoginProcessor.scala │ │ ├── UserScope.scala │ │ ├── messages.scala │ │ └── package.scala │ │ ├── dashboard │ │ ├── ClusterView.scala │ │ ├── DashboardHandler.scala │ │ ├── DashboardPage.scala │ │ ├── NodeList.scala │ │ └── package.scala │ │ ├── layout │ │ ├── ClockWidget.scala │ │ ├── ContextStyle.scala │ │ ├── Footer.scala │ │ ├── GlobalStyles.scala │ │ ├── Layout.scala │ │ ├── LookAndFeel.scala │ │ ├── Navigation.scala │ │ └── package.scala │ │ ├── libs │ │ ├── BootstrapJQuery.scala │ │ ├── BootstrapNotify.scala │ │ ├── codemirror │ │ │ ├── ChangeEvent.scala │ │ │ ├── CodeMirror.scala │ │ │ ├── CodeMirrorReact.scala │ │ │ ├── LineHandle.scala │ │ │ └── package.scala │ │ └── package.scala │ │ ├── log │ │ ├── LogDisplay.scala │ │ ├── model.scala │ │ └── package.scala │ │ ├── registry │ │ ├── ArtifactInput.scala │ │ ├── JarJobPackageInput.scala │ │ ├── JobForm.scala │ │ ├── JobPackageSelect.scala │ │ ├── JobSelect.scala │ │ ├── JobSpecList.scala │ │ ├── RegistryHandler.scala │ │ ├── RegistryPage.scala │ │ ├── ShellScriptPackageInput.scala │ │ └── package.scala │ │ ├── scheduler │ │ ├── AfterTriggerInput.scala │ │ ├── AtTriggerInput.scala │ │ ├── CronTriggerInput.scala │ │ ├── EveryTriggerInput.scala │ │ ├── ExecutionParameterList.scala │ │ ├── ExecutionPlanForm.scala │ │ ├── ExecutionPlanList.scala │ │ ├── ExecutionPlanPreview.scala │ │ ├── ExecutionPlansHandler.scala │ │ ├── ExecutionTimeoutInput.scala │ │ ├── SchedulerHandler.scala │ │ ├── SchedulerPage.scala │ │ ├── TaskExecutionList.scala │ │ ├── TasksHandler.scala │ │ ├── TriggerSelect.scala │ │ └── package.scala │ │ ├── security │ │ ├── LoginForm.scala │ │ ├── LoginPage.scala │ │ └── PrincipalWidget.scala │ │ └── validation │ │ ├── ValidatedField.scala │ │ └── package.scala │ └── test │ └── scala │ └── io │ └── quckoo │ └── console │ ├── components │ ├── FiniteDurationInputObserver.scala │ ├── FiniteDurationInputTest.scala │ ├── FiniteDurationInputTestDsl.scala │ ├── InputTest.scala │ ├── NavBarObserver.scala │ ├── NavBarTest.scala │ ├── NavBarTestDsl.scala │ ├── TextAreaObserver.scala │ ├── TextAreaTestDsl.scala │ └── TextAreaTestIgnore.scala │ ├── scheduler │ ├── AtTriggerInputObserver.scala │ ├── AtTriggerInputTest.scala │ ├── AtTriggerInputTestDsl.scala │ ├── CronTriggerInputObserver.scala │ ├── CronTriggerInputTest.scala │ └── CronTriggerInputTestDsl.scala │ ├── security │ ├── LoginObserver.scala │ ├── LoginTest.scala │ └── LoginTestDsl.scala │ └── test │ ├── ConsoleTestExports.scala │ └── package.scala ├── core └── src │ ├── main │ └── scala │ │ └── io │ │ └── quckoo │ │ ├── ArtifactId.scala │ │ ├── ExecutionPlan.scala │ │ ├── Job.scala │ │ ├── JobId.scala │ │ ├── JobPackage.scala │ │ ├── JobSpec.scala │ │ ├── NodeId.scala │ │ ├── PlanId.scala │ │ ├── Task.scala │ │ ├── TaskExecution.scala │ │ ├── TaskId.scala │ │ ├── Trigger.scala │ │ ├── errors.scala │ │ ├── package.scala │ │ ├── serialization │ │ ├── Codec.scala │ │ ├── DataBuffer.scala │ │ ├── Decoder.scala │ │ ├── Encoder.scala │ │ ├── base64 │ │ │ ├── Base64Codec.scala │ │ │ ├── Scheme.scala │ │ │ └── package.scala │ │ └── json │ │ │ ├── Cron4s.scala │ │ │ ├── TimeJson.scala │ │ │ └── package.scala │ │ ├── time │ │ └── implicits.scala │ │ ├── util │ │ ├── IsTraversable.scala │ │ └── package.scala │ │ └── validation │ │ ├── AnyValidators.scala │ │ ├── CaseClassValidators.scala │ │ ├── OptionValidators.scala │ │ ├── OrderValidators.scala │ │ ├── Path.scala │ │ ├── TraversableValidators.scala │ │ ├── ValidatorSyntax.scala │ │ ├── Validators.scala │ │ ├── Violation.scala │ │ └── package.scala │ └── test │ └── scala │ └── io │ └── quckoo │ ├── AfterTriggerTest.scala │ ├── ArtifactIdSpec.scala │ ├── AtTriggerTest.scala │ ├── CronTriggerSpec.scala │ ├── EveryTriggerTest.scala │ ├── IdValSpec.scala │ ├── ImmediateTriggerTest.scala │ ├── JobIdSpec.scala │ ├── JobSpecSpec.scala │ ├── NodeIdSpec.scala │ ├── PlanIdSpec.scala │ ├── TaskIdSpec.scala │ ├── serialization │ └── DataBufferSpec.scala │ └── validation │ ├── PathSpec.scala │ ├── ValidatorGen.scala │ ├── ValidatorLaws.scala │ ├── ValidatorSpec.scala │ └── ValidatorTests.scala ├── docs ├── CNAME ├── diagrams │ ├── RegisterJobWorkflow.drawing │ ├── ScheduleJobWorkflow.drawing │ └── Topology.drawing └── img │ ├── RegisterJobWorkflow.jpg │ ├── ScheduleJobWorkflow.jpg │ └── Topology.jpg ├── examples ├── jobs │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quckoo │ │ └── examples │ │ ├── HelloWorldJob.java │ │ └── parameters │ │ └── PowerOfNJob.java └── producers │ └── src │ ├── main │ ├── resources │ │ └── application.conf │ └── scala │ │ └── io │ │ └── quckoo │ │ └── examples │ │ ├── CliOptions.scala │ │ ├── ExamplesMain.scala │ │ └── parameters │ │ └── PowerOfNActor.scala │ └── universal │ └── conf │ └── log4j2.xml ├── master └── src │ ├── main │ ├── assets │ │ ├── css │ │ │ ├── _globals.scss │ │ │ ├── _header.scss │ │ │ ├── _imports.scss │ │ │ └── application.scss │ │ └── img │ │ │ └── hourglass.gif │ ├── resources │ │ ├── log4j2.xml │ │ └── reference.conf │ ├── scala │ │ └── io │ │ │ └── quckoo │ │ │ └── cluster │ │ │ ├── QuckooFacade.scala │ │ │ ├── QuckooRoles.scala │ │ │ ├── boot │ │ │ ├── Boot.scala │ │ │ └── CliOptions.scala │ │ │ ├── config │ │ │ ├── model.scala │ │ │ └── package.scala │ │ │ ├── core │ │ │ ├── Auth.scala │ │ │ ├── ClusterStreams.scala │ │ │ ├── QuckooGuardian.scala │ │ │ ├── QuckooServer.scala │ │ │ ├── Topic.scala │ │ │ ├── TopicConsumer.scala │ │ │ └── UserAuthenticator.scala │ │ │ ├── http │ │ │ ├── AuthDirectives.scala │ │ │ ├── HttpRouter.scala │ │ │ ├── StaticResources.scala │ │ │ ├── TimeoutDirectives.scala │ │ │ └── package.scala │ │ │ ├── journal │ │ │ ├── QuckooJournal.scala │ │ │ ├── QuckooProductionJournal.scala │ │ │ └── package.scala │ │ │ ├── package.scala │ │ │ ├── registry │ │ │ ├── PersistentJob.scala │ │ │ ├── Registration.scala │ │ │ ├── Registry.scala │ │ │ ├── RegistryHttpRouter.scala │ │ │ ├── RegistrySettings.scala │ │ │ ├── RegistryStreams.scala │ │ │ └── RegistryTagEventAdapter.scala │ │ │ └── scheduler │ │ │ ├── ExecutionDriver.scala │ │ │ ├── ExecutionLifecycle.scala │ │ │ ├── Scheduler.scala │ │ │ ├── SchedulerHttpRouter.scala │ │ │ ├── SchedulerStreams.scala │ │ │ ├── SchedulerTagEventAdapter.scala │ │ │ ├── TaskQueue.scala │ │ │ └── TaskQueueMonitor.scala │ └── twirl │ │ └── io │ │ └── quckoo │ │ └── console │ │ ├── index.scala.html │ │ └── main.scala.html │ ├── multi-jvm │ ├── resources │ │ ├── application.conf │ │ └── log4j2.xml │ └── scala │ │ └── io │ │ └── quckoo │ │ ├── cluster │ │ ├── QuckooMultiNodeCluster.scala │ │ └── registry │ │ │ └── RegistryMultiNode.scala │ │ └── multijvm │ │ ├── MultiNodeClusterSpec.scala │ │ └── ScalaTestMultiNodeSpec.scala │ ├── test │ ├── resources │ │ ├── application.conf │ │ └── log4j2.xml │ └── scala │ │ └── io │ │ └── quckoo │ │ ├── cluster │ │ ├── config │ │ │ └── ClusterSettingsSpec.scala │ │ ├── core │ │ │ ├── LocalTopicConsumerSpec.scala │ │ │ └── PubSubTopicConsumerSpec.scala │ │ ├── journal │ │ │ └── QuckooTestJournal.scala │ │ ├── registry │ │ │ ├── PersistentJobSpec.scala │ │ │ ├── RegistryHttpRouterSpec.scala │ │ │ └── RegistrySpec.scala │ │ └── scheduler │ │ │ ├── ExecutionDriverSpec.scala │ │ │ ├── ExecutionLifecycleSpec.scala │ │ │ ├── SchedulerHttpRouterSpec.scala │ │ │ ├── SchedulerSpec.scala │ │ │ └── TaskQueueSpec.scala │ │ └── testkit │ │ └── QuckooActorClusterSuite.scala │ └── universal │ └── conf │ ├── application.conf │ └── log4j2.xml ├── project ├── Dependencies.scala ├── QuckooMultiJvmTesting.scala ├── QuckooPackager.scala ├── QuckooWebServer.scala ├── build.properties └── plugins.sbt ├── sandbox ├── Quckoo-Grafana.json ├── consul │ ├── docker-compose.yml │ └── etc │ │ └── quckoo │ │ ├── master │ │ ├── application.conf │ │ └── log4j2.xml │ │ └── worker │ │ ├── application.conf │ │ └── log4j2.xml ├── standalone │ ├── docker-compose.yml │ └── etc │ │ ├── prometheus │ │ └── config.yml │ │ └── quckoo │ │ ├── application.conf │ │ └── log4j2.xml └── vagrant │ ├── build.sh │ ├── docker-quckoo.yml │ ├── docker-support.yml │ ├── etc │ ├── quckoo │ │ ├── application.conf │ │ └── log4j2.xml │ └── sbt │ │ └── 0.13 │ │ └── artifactory.sbt │ ├── provision.sh │ └── provision_mesos.sh ├── scripts ├── travis-build.sh └── travis-setup.sh ├── shared └── src │ ├── main │ ├── resources │ │ └── reference.conf │ └── scala │ │ └── io │ │ └── quckoo │ │ ├── cluster │ │ ├── net │ │ │ └── package.scala │ │ ├── package.scala │ │ ├── pattern │ │ │ └── package.scala │ │ └── protocol │ │ │ └── messages.scala │ │ ├── config │ │ └── package.scala │ │ ├── kamon │ │ └── package.scala │ │ ├── reflect │ │ ├── Artifact.scala │ │ ├── ArtifactClassLoader.scala │ │ ├── ReflectOp.scala │ │ ├── Reflector.scala │ │ ├── ReflectorInterpreter.scala │ │ ├── javareflect │ │ │ ├── JavaReflector.scala │ │ │ └── package.scala │ │ ├── ops.scala │ │ └── package.scala │ │ └── resolver │ │ ├── Patterns.scala │ │ ├── Repository.scala │ │ ├── RepositoryConversion.scala │ │ ├── Resolver.scala │ │ ├── ResolverInterpreter.scala │ │ ├── ResolverOp.scala │ │ ├── config │ │ └── IvyConfig.scala │ │ ├── ivy │ │ ├── IvyConfiguration.scala │ │ ├── IvyResolver.scala │ │ └── package.scala │ │ ├── ops.scala │ │ └── package.scala │ └── test │ ├── java │ └── io │ │ └── quckoo │ │ └── resolver │ │ └── DummyJavaJob.java │ ├── resources │ ├── application.conf │ └── log4j2.xml │ └── scala │ └── io │ └── quckoo │ ├── reflect │ └── javareflect │ │ └── JavaReflectorSpec.scala │ └── resolver │ ├── ArtifactClassLoaderSpec.scala │ ├── PureResolver.scala │ ├── config │ └── IvyConfigSpec.scala │ └── ivy │ ├── IvyConfigurationTest.scala │ └── IvyResolverSpec.scala ├── test-support ├── jvm │ └── src │ │ └── main │ │ └── scala │ │ └── io │ │ └── quckoo │ │ └── testkit │ │ └── QuckooActorSuite.scala └── shared │ └── src │ └── main │ └── scala │ └── io │ └── quckoo │ └── testkit │ ├── ImplicitClock.scala │ └── gen │ └── JavaTimeGenerators.scala ├── util ├── js │ └── src │ │ ├── main │ │ └── scala │ │ │ └── io │ │ │ └── quckoo │ │ │ └── md5 │ │ │ ├── MD5_js.scala │ │ │ └── SparkMD5.scala │ │ └── test │ │ └── scala │ │ └── io │ │ └── quckoo │ │ └── md5 │ │ └── JsMD5Spec.scala └── jvm │ └── src │ ├── main │ └── scala │ │ └── io │ │ └── quckoo │ │ └── md5 │ │ └── MD5_jvm.scala │ └── test │ └── scala │ └── io │ └── quckoo │ └── md5 │ └── JvmMD5Spec.scala ├── version.sbt └── worker └── src ├── main ├── resources │ ├── log4j2.xml │ └── reference.conf └── scala │ └── io │ └── quckoo │ └── worker │ ├── boot │ ├── Boot.scala │ └── CliOptions.scala │ ├── config │ ├── model.scala │ └── package.scala │ ├── core │ ├── TaskExecutor.scala │ ├── TaskExecutorProvider.scala │ ├── Worker.scala │ └── WorkerContext.scala │ ├── executor │ ├── DefaultTaskExecutorProvider.scala │ ├── JarTaskExecutor.scala │ ├── ProcessRunner.scala │ └── ShellTaskExecutor.scala │ └── package.scala ├── test ├── resources │ ├── application.conf │ └── log4j2.xml └── scala │ └── io │ └── quckoo │ └── worker │ ├── config │ └── WorkerSettingsSpec.scala │ ├── core │ └── WorkerSpec.scala │ └── executor │ ├── JarTaskExecutorSpec.scala │ ├── ProcessRunnerSpec.scala │ └── ShellTaskExecutorSpec.scala └── universal └── conf ├── application.conf └── log4j2.xml /.sbtopts: -------------------------------------------------------------------------------- 1 | # see https://weblogs.java.net/blog/kcpeppe/archive/2013/12/11/case-study-jvm-hotspot-flags 2 | -J-Dfile.encoding=UTF8 3 | -J-Xms1G 4 | -J-Xmx6G 5 | -J-XX:MaxMetaspaceSize=512M 6 | -J-XX:ReservedCodeCacheSize=250M 7 | -J-XX:+TieredCompilation 8 | -J-XX:-UseGCOverheadLimit 9 | # effectively adds GC to Perm space 10 | -J-XX:+CMSClassUnloadingEnabled 11 | # must be enabled for CMSClassUnloadingEnabled to work 12 | -J-XX:+UseConcMarkSweepGC 13 | 14 | 15 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | style = defaultWithAlign 2 | maxColumn = 100 3 | 4 | align { 5 | openParenCallSite = false 6 | } 7 | 8 | binPack { 9 | parentConstructors = true 10 | } 11 | 12 | continuationIndent { 13 | callSite = 2 14 | defnSite = 4 15 | } 16 | 17 | danglingParentheses = true 18 | 19 | rewrite.rules = [RedundantBraces, RedundantParens, PreferCurlyFors] 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | 3 | dist: trusty 4 | sudo: required 5 | 6 | jdk: 7 | - oraclejdk8 8 | 9 | scala: 10 | - 2.12.3 11 | 12 | cache: 13 | directories: 14 | - $HOME/.sbt/1.0/dependency 15 | - $HOME/.sbt/boot/scala* 16 | - $HOME/.sbt/launchers 17 | - $HOME/.ivy2/cache 18 | - $HOME/.nvm 19 | 20 | env: 21 | - TRAVIS_NODE_VERSION="4" 22 | 23 | before_install: 24 | - scripts/travis-setup.sh 25 | 26 | script: 27 | - scripts/travis-build.sh 28 | 29 | after_success: 30 | - bash <(curl -s https://codecov.io/bash) 31 | 32 | branches: 33 | only: 34 | - master 35 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2015 Antonio Alonso Dominguez 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 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/api/Cluster.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.api 18 | 19 | import io.quckoo.auth.Passport 20 | import io.quckoo.net.QuckooState 21 | 22 | import scala.concurrent.duration.{FiniteDuration} 23 | import scala.concurrent.{ExecutionContext, Future} 24 | 25 | /** 26 | * Created by alonsodomin on 04/04/2016. 27 | */ 28 | trait Cluster { 29 | 30 | def clusterState(implicit ec: ExecutionContext, 31 | timeout: FiniteDuration, 32 | passport: Passport): Future[QuckooState] 33 | 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/api/TopicTag.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.api 18 | 19 | import io.quckoo.protocol.cluster.MasterEvent 20 | import io.quckoo.protocol.registry.RegistryEvent 21 | import io.quckoo.protocol.scheduler.SchedulerEvent 22 | import io.quckoo.protocol.worker.WorkerEvent 23 | 24 | import scala.reflect.ClassTag 25 | 26 | /** 27 | * Created by alonsodomin on 20/09/2016. 28 | */ 29 | sealed abstract class TopicTag[A](val name: String)(implicit val eventType: ClassTag[A]) 30 | extends Product with Serializable 31 | 32 | object TopicTag { 33 | 34 | @inline def apply[A](implicit ev: TopicTag[A]): TopicTag[A] = ev 35 | 36 | implicit case object Master extends TopicTag[MasterEvent]("master") 37 | implicit case object Worker extends TopicTag[WorkerEvent]("worker") 38 | implicit case object Registry extends TopicTag[RegistryEvent]("registry") 39 | implicit case object Scheduler extends TopicTag[SchedulerEvent]("scheduler") 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/api/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | /** 20 | * Created by alonsodomin on 04/09/2016. 21 | */ 22 | package object api { 23 | 24 | final val AuthorizationHeader = "Authorization" 25 | final val RequestTimeoutHeader = "X-QUCKOO-REQ-TIMEOUT" 26 | 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/Credentials.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 05/09/2016. 21 | */ 22 | final case class Credentials(username: String, password: String) 23 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/InvalidCredentials.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 16/09/2016. 21 | */ 22 | case object InvalidCredentials extends Exception("Invalid credentials") 23 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/InvalidPassport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 15/09/2016. 21 | */ 22 | final case class InvalidPassport(token: String) 23 | extends Exception(s"Token '$token' is not valid.") 24 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/Permission.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 14/10/2015. 21 | */ 22 | trait Permission {} 23 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/Principal.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 29/03/2016. 21 | */ 22 | trait Principal extends Serializable { 23 | val id: String 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/User.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | final case class User(id: UserId) extends Principal 20 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/http/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.auth 18 | 19 | /** 20 | * Created by alonsodomin on 24/03/2016. 21 | */ 22 | package object http { 23 | 24 | final val XSRFTokenCookie = "XSRF_TOKEN" 25 | final val XSRFTokenHeader = "X-" + XSRFTokenCookie 26 | 27 | final val AuthScheme = "QuckooAuth" 28 | final val AuthCookie = "Auth-Token" 29 | final val ApiTokenHeader = "X-QuckooToken" 30 | 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/auth/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | /** 20 | * Created by alonsodomin on 21/03/2016. 21 | */ 22 | package object auth { 23 | 24 | type UserId = String 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/net/Location.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.net 18 | 19 | /** 20 | * Created by alonsodomin on 03/04/2016. 21 | */ 22 | final case class Location(host: String) 23 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/net/NodeStatus.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.net 18 | 19 | import enumeratum._ 20 | 21 | /** 22 | * Created by alonsodomin on 03/04/2016. 23 | */ 24 | sealed trait NodeStatus extends EnumEntry 25 | object NodeStatus extends Enum[NodeStatus] with CirceEnum[NodeStatus] { 26 | case object Active extends NodeStatus 27 | case object Unreachable extends NodeStatus 28 | 29 | val values = findValues 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/net/QuckooMetrics.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.net 18 | 19 | import io.quckoo.protocol.scheduler.TaskQueueUpdated 20 | import monocle.macros.Lenses 21 | 22 | /** 23 | * Created by alonsodomin on 12/04/2016. 24 | */ 25 | @Lenses final case class QuckooMetrics(pendingTasks: Int = 0, inProgressTasks: Int = 0) { 26 | 27 | def updated(event: TaskQueueUpdated): QuckooMetrics = 28 | copy(pendingTasks = event.pendingTasks, inProgressTasks = event.inProgressTasks) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/net/QuckooNode.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.net 18 | 19 | import io.quckoo.NodeId 20 | 21 | /** 22 | * Created by alonsodomin on 03/04/2016. 23 | */ 24 | sealed trait QuckooNode { 25 | val id: NodeId 26 | val location: Location 27 | def status: NodeStatus 28 | } 29 | 30 | final case class MasterNode(id: NodeId, location: Location, status: NodeStatus) extends QuckooNode 31 | final case class WorkerNode(id: NodeId, location: Location, status: NodeStatus) extends QuckooNode 32 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/protocol/Command.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.protocol 18 | 19 | import diode.ActionType 20 | 21 | /** 22 | * Created by alonsodomin on 02/07/2016. 23 | */ 24 | trait Command 25 | 26 | object Command { 27 | implicit object actionType extends ActionType[Command] 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/protocol/Event.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.protocol 18 | 19 | import diode.ActionType 20 | 21 | /** 22 | * Created by alonsodomin on 02/07/2016. 23 | */ 24 | trait Event 25 | 26 | object Event { 27 | implicit object eventType extends ActionType[Event] 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/protocol/client/messages.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.protocol.client 18 | 19 | import monocle.macros.Lenses 20 | 21 | sealed trait ClientEvent 22 | sealed trait ClientCommand 23 | 24 | case object Connect extends ClientCommand 25 | case object Connected extends ClientEvent 26 | 27 | case object Disconnect extends ClientCommand 28 | case object Disconnected extends ClientEvent 29 | case object UnableToConnect extends ClientEvent 30 | 31 | @Lenses 32 | case class SignIn(username: String, password: Array[Char]) 33 | case object SignOut 34 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/protocol/cluster/messages.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.protocol.cluster 18 | 19 | import io.quckoo.NodeId 20 | import io.quckoo.net.Location 21 | import io.quckoo.protocol.{Command, Event} 22 | 23 | case object GetClusterStatus extends Command 24 | 25 | sealed trait MasterEvent extends Event with Product with Serializable 26 | 27 | final case class MasterJoined(nodeId: NodeId, location: Location) extends MasterEvent 28 | final case class MasterReachable(nodeId: NodeId) extends MasterEvent 29 | final case class MasterUnreachable(nodeId: NodeId) extends MasterEvent 30 | final case class MasterRemoved(nodeId: NodeId) extends MasterEvent 31 | -------------------------------------------------------------------------------- /api/src/main/scala/io/quckoo/protocol/worker/messages.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.protocol.worker 18 | 19 | import io.quckoo.NodeId 20 | import io.quckoo.net.Location 21 | import io.quckoo.protocol.Event 22 | 23 | sealed trait WorkerEvent extends Event { 24 | val workerId: NodeId 25 | } 26 | 27 | final case class WorkerJoined(workerId: NodeId, location: Location) extends WorkerEvent 28 | final case class WorkerLost(workerId: NodeId) extends WorkerEvent 29 | final case class WorkerRemoved(workerId: NodeId) extends WorkerEvent 30 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | environment: 3 | SBT_OPTS: "-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC" 4 | java: 5 | version: openjdk8 6 | pre: 7 | - gem install compass 8 | 9 | dependencies: 10 | cache_directories: 11 | - "~/.m2" 12 | - "~/.sbt" 13 | - "~/.ivy2" 14 | 15 | test: 16 | override: 17 | - sbt coverage test:test 18 | post: 19 | - sbt coverageReport && sbt coverageAggregate -------------------------------------------------------------------------------- /client/js/src/main/scala/io/quckoo/client/http/dom/Cookie.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http.dom 18 | 19 | import org.scalajs.dom 20 | 21 | /** 22 | * Created by alonsodomin on 13/10/2015. 23 | */ 24 | object Cookie { 25 | 26 | private[this] def rawCookies: Map[String, String] = { 27 | import dom.document 28 | 29 | val pairs = document.cookie.split("; ").map { c => 30 | val namePair = c.split("=") 31 | namePair(0) -> namePair(1) 32 | } 33 | 34 | Map(pairs: _*) 35 | } 36 | 37 | def apply(name: String): Option[String] = 38 | rawCookies.get(name) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /client/js/src/main/scala/io/quckoo/client/http/dom/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.quckoo.client.QuckooClient 20 | import io.quckoo.client.core.DriverBackend 21 | 22 | /** 23 | * Created by alonsodomin on 20/09/2016. 24 | */ 25 | package object dom { 26 | 27 | implicit val backend: DriverBackend[HttpProtocol] = HttpDOMBackend 28 | val HttpDOMQuckooClient = QuckooClient[HttpProtocol] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /client/jvm/src/main/scala/io/quckoo/client/http/akka/HttpAkkaQuckooClient.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http.akka 18 | 19 | import akka.actor.ActorSystem 20 | 21 | import io.quckoo.client.QuckooClient 22 | import io.quckoo.client.http._ 23 | 24 | /** 25 | * Created by alonsodomin on 21/09/2016. 26 | */ 27 | object HttpAkkaQuckooClient { 28 | def apply(host: String, port: Int = 80)( 29 | implicit 30 | actorSystem: ActorSystem = ActorSystem("HttpQuckooClient") 31 | ) = { 32 | implicit val backend = new HttpAkkaBackend(host, port) 33 | QuckooClient[HttpProtocol] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/jvm/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/Channel.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.api.TopicTag 20 | 21 | /** 22 | * Created by domingueza on 20/09/2016. 23 | */ 24 | trait Channel[P <: Protocol] { 25 | type Event 26 | 27 | val topicTag: TopicTag[Event] 28 | val unmarshall: Unmarshall[P#EventType, Event] 29 | } 30 | 31 | object Channel { 32 | trait Aux[P <: Protocol, E] extends Channel[P] { type Event = E } 33 | } 34 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/ChannelException.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | /** 20 | * Created by alonsodomin on 28/02/2017. 21 | */ 22 | class ChannelException(val topicName: String) extends Exception -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/ChannelMagnet.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.api.TopicTag 20 | import io.quckoo.serialization.Decoder 21 | 22 | /** 23 | * Created by alonsodomin on 20/09/2016. 24 | */ 25 | trait ChannelMagnet[E] { 26 | implicit def topicTag: TopicTag[E] 27 | implicit def decoder: Decoder[String, E] 28 | 29 | def resolve[P <: Protocol](driver: Driver[P]): Channel.Aux[P, E] = driver.channelFor[E] 30 | } 31 | 32 | object ChannelMagnet { 33 | implicit def apply[E](implicit topicTag0: TopicTag[E], 34 | decoder0: Decoder[String, E]): ChannelMagnet[E] = 35 | new ChannelMagnet[E] { 36 | implicit val topicTag: TopicTag[E] = topicTag0 37 | implicit val decoder: Decoder[String, E] = decoder0 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/Channels.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.api.TopicTag 20 | import io.quckoo.protocol.cluster.MasterEvent 21 | import io.quckoo.protocol.registry.RegistryEvent 22 | import io.quckoo.protocol.scheduler.SchedulerEvent 23 | import io.quckoo.protocol.worker.WorkerEvent 24 | import io.quckoo.serialization.Decoder 25 | 26 | /** 27 | * Created by domingueza on 20/09/2016. 28 | */ 29 | trait Channels[P <: Protocol] { 30 | 31 | type MasterChannel = Channel.Aux[P, MasterEvent] 32 | type WorkerChannel = Channel.Aux[P, WorkerEvent] 33 | type RegistryChannel = Channel.Aux[P, RegistryEvent] 34 | type SchedulerChannel = Channel.Aux[P, SchedulerEvent] 35 | 36 | def createChannel[E: TopicTag](implicit decoder: Decoder[String, E]): Channel.Aux[P, E] 37 | 38 | } 39 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/ClusterCmds.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.net.QuckooState 20 | 21 | /** 22 | * Created by alonsodomin on 19/09/2016. 23 | */ 24 | trait ClusterCmds[P <: Protocol] { 25 | import CmdMarshalling.Auth 26 | 27 | type GetClusterStateCmd = Auth[P, Unit, QuckooState] 28 | 29 | implicit def getClusterStateCmd: GetClusterStateCmd 30 | } 31 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/CmdMarshalling.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | /** 20 | * Created by alonsodomin on 18/09/2016. 21 | */ 22 | trait CmdMarshalling[P <: Protocol] { 23 | type Cmd[_] <: Command[_] 24 | type In 25 | type Rslt 26 | 27 | val marshall: Marshall[Cmd, In, P#Request] 28 | val unmarshall: Unmarshall[P#Response, Rslt] 29 | } 30 | 31 | object CmdMarshalling { 32 | trait Aux[P <: Protocol, Cmd0[_] <: Command[_], In0, Rslt0] extends CmdMarshalling[P] { 33 | type Cmd[X] = Cmd0[X] 34 | type In = In0 35 | type Rslt = Rslt0 36 | } 37 | 38 | trait Anon[P <: Protocol, In, Rslt] extends Aux[P, AnonCmd, In, Rslt] 39 | trait Auth[P <: Protocol, In, Rslt] extends Aux[P, AuthCmd, In, Rslt] 40 | 41 | } 42 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/DriverBackend.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import cats.data.Kleisli 20 | 21 | import monix.reactive.Observable 22 | 23 | import scala.concurrent.Future 24 | 25 | /** 26 | * Created by alonsodomin on 08/09/2016. 27 | */ 28 | trait DriverBackend[P <: Protocol] { 29 | def open[Ch <: Channel[P]](channel: Ch): Kleisli[Observable, Unit, P#EventType] 30 | def send: Kleisli[Future, P#Request, P#Response] 31 | } 32 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/Protocol.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | /** 20 | * Created by alonsodomin on 17/09/2016. 21 | */ 22 | trait Protocol { 23 | type Request 24 | type Response 25 | type EventType 26 | } 27 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/ProtocolSpecs.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | /** 20 | * Created by alonsodomin on 19/09/2016. 21 | */ 22 | trait ProtocolSpecs[P <: Protocol] 23 | extends ClusterCmds[P] with SchedulerCmds[P] with RegistryCmds[P] with SecurityCmds[P] 24 | with Channels[P] 25 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/SecurityCmds.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.auth.{Credentials, Passport} 20 | 21 | /** 22 | * Created by alonsodomin on 19/09/2016. 23 | */ 24 | trait SecurityCmds[P <: Protocol] { 25 | type AuthenticateCmd = CmdMarshalling.Anon[P, Credentials, Passport] 26 | type RefreshPassportCmd = CmdMarshalling.Auth[P, Unit, Passport] 27 | type SingOutCmd = CmdMarshalling.Auth[P, Unit, Unit] 28 | 29 | implicit def authenticateCmd: AuthenticateCmd 30 | implicit def refreshPassportCmd: RefreshPassportCmd 31 | implicit def signOutCmd: SingOutCmd 32 | } 33 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/core/commands.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import io.quckoo.auth.Passport 20 | 21 | import scala.concurrent.duration.FiniteDuration 22 | 23 | /** 24 | * Created by alonsodomin on 08/09/2016. 25 | */ 26 | sealed trait Command[A] { 27 | val payload: A 28 | val timeout: FiniteDuration 29 | } 30 | 31 | final case class AnonCmd[A](payload: A, timeout: FiniteDuration) extends Command[A] 32 | final case class AuthCmd[A](payload: A, timeout: FiniteDuration, passport: Passport) 33 | extends Command[A] 34 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/http/Http.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.quckoo.client.core.ProtocolSpecs 20 | 21 | /** 22 | * Created by alonsodomin on 19/09/2016. 23 | */ 24 | sealed trait Http 25 | extends HttpProtocol with ProtocolSpecs[HttpProtocol] with HttpClusterCmds 26 | with HttpSchedulerCmds with HttpRegistryCmds with HttpSecurityCmds with SSEChannels 27 | 28 | object Http extends Http 29 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/http/HttpBackend.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.quckoo.client.core.DriverBackend 20 | 21 | /** 22 | * Created by alonsodomin on 09/09/2016. 23 | */ 24 | trait HttpBackend extends DriverBackend[HttpProtocol] 25 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/http/HttpClusterCmds.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.circe.generic.auto._ 20 | 21 | import io.quckoo.client.core._ 22 | import io.quckoo.net.QuckooState 23 | import io.quckoo.serialization.json._ 24 | 25 | /** 26 | * Created by alonsodomin on 19/09/2016. 27 | */ 28 | trait HttpClusterCmds extends HttpMarshalling with ClusterCmds[HttpProtocol] { 29 | import CmdMarshalling.Auth 30 | 31 | implicit lazy val getClusterStateCmd: GetClusterStateCmd = 32 | new Auth[HttpProtocol, Unit, QuckooState] { 33 | override val marshall = 34 | marshallEmpty[GetClusterStateCmd](HttpMethod.Get, _ => ClusterStateURI) 35 | override val unmarshall = unmarshallFromJson[GetClusterStateCmd] 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/http/HttpProtocol.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.quckoo.client.core.Protocol 20 | 21 | /** 22 | * Created by alonsodomin on 17/09/2016. 23 | */ 24 | trait HttpProtocol extends Protocol { 25 | type Request = HttpRequest 26 | type Response = HttpResponse 27 | type EventType = HttpServerSentEvent 28 | } 29 | -------------------------------------------------------------------------------- /client/shared/src/main/scala/io/quckoo/client/http/SSEChannels.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.http 18 | 19 | import io.quckoo.api.TopicTag 20 | import io.quckoo.client.core.{Channel, Channels, Unmarshall} 21 | import io.quckoo.serialization.Decoder 22 | 23 | /** 24 | * Created by domingueza on 20/09/2016. 25 | */ 26 | trait SSEChannels extends Channels[HttpProtocol] { 27 | 28 | override def createChannel[E: TopicTag](implicit decoder: Decoder[String, E]) = 29 | new Channel.Aux[HttpProtocol, E] { 30 | override val topicTag = implicitly[TopicTag[E]] 31 | override val unmarshall = Unmarshall[HttpServerSentEvent, E](_.data.as[E]) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /client/shared/src/test/scala/io/quckoo/client/core/TestDriverBackend.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.client.core 18 | 19 | import cats.data.Kleisli 20 | 21 | import io.quckoo.util._ 22 | 23 | import monix.reactive.Observable 24 | 25 | /** 26 | * Created by alonsodomin on 17/09/2016. 27 | */ 28 | private[core] final class TestDriverBackend[P <: Protocol]( 29 | stream: Iterable[P#EventType], 30 | command: P#Request => Attempt[P#Response] 31 | ) extends DriverBackend[P] { 32 | 33 | @inline def send = 34 | Kleisli[Attempt, P#Request, P#Response](command).transform(attempt2Future) 35 | 36 | @inline def open[Ch <: Channel[P]](channel: Ch) = 37 | Kleisli[Observable, Unit, P#EventType](_ => Observable.fromIterable(stream)) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/ConsoleRoute.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import enumeratum._ 20 | 21 | /** 22 | * Created by alonsodomin on 26/03/2016. 23 | */ 24 | sealed trait ConsoleRoute extends EnumEntry with EnumEntry.Lowercase 25 | object ConsoleRoute extends Enum[ConsoleRoute] { 26 | case object Root extends ConsoleRoute 27 | case object Dashboard extends ConsoleRoute 28 | case object Login extends ConsoleRoute 29 | case object Registry extends ConsoleRoute 30 | case object Scheduler extends ConsoleRoute 31 | 32 | val values = findValues 33 | } 34 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/components/Alert.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import io.quckoo.console.layout.{ContextStyle, lookAndFeel} 20 | 21 | import japgolly.scalajs.react._ 22 | import japgolly.scalajs.react.vdom.html_<^._ 23 | 24 | import scalacss.ScalaCssReact._ 25 | 26 | /** 27 | * Created by alonsodomin on 20/02/2016. 28 | */ 29 | object Alert { 30 | case class Props(style: ContextStyle.Value) 31 | 32 | val component = ScalaComponent 33 | .builder[Props]("Alert") 34 | .renderPC { (_, p, c) => 35 | <.div(lookAndFeel.alert(p.style), ^.role := "alert", ^.padding := 5.px, c) 36 | } build 37 | 38 | def apply(style: ContextStyle.Value) = component(Props(style)) _ 39 | 40 | } 41 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/components/NavStyle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import japgolly.univeq.UnivEq 20 | 21 | import scalacss.internal.StyleLookup 22 | 23 | /** 24 | * Created by alonsodomin on 10/07/2016. 25 | */ 26 | object NavStyle extends Enumeration { 27 | val tabs, pills, stacked = Value 28 | 29 | implicit val univEq = UnivEq.force[Value] 30 | implicit val lookup = StyleLookup.scalaMap[Value] 31 | } 32 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/components/Password.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import japgolly.scalajs.react.extra.Reusability 20 | 21 | /** 22 | * Created by alonsodomin on 03/07/2016. 23 | */ 24 | final class Password(val value: String) extends AnyVal 25 | 26 | object Password { 27 | def apply(value: String): Password = new Password(value) 28 | 29 | implicit val reusability: Reusability[Password] = Reusability.by(_.value) 30 | } 31 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/components/TableStyle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import japgolly.univeq.UnivEq 20 | 21 | import scalacss.internal.StyleLookup 22 | 23 | /** 24 | * Created by alonsodomin on 04/03/2017. 25 | */ 26 | object TableStyle extends Enumeration { 27 | val striped, bordered, condensed, hover = Value 28 | 29 | implicit val univEq = UnivEq.force[Value] 30 | implicit val lookup = StyleLookup.scalaMap[Value] 31 | } 32 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/components/ToolBar.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import io.quckoo.console.layout.GlobalStyles 20 | 21 | import japgolly.scalajs.react._ 22 | import japgolly.scalajs.react.vdom.html_<^._ 23 | 24 | import scalacss.ScalaCssReact._ 25 | 26 | /** 27 | * Created by alonsodomin on 05/03/2017. 28 | */ 29 | object ToolBar { 30 | 31 | private[this] val component = ScalaComponent 32 | .builder[Unit]("ToolBar") 33 | .stateless 34 | .render_C { children => 35 | <.div(GlobalStyles.pageToolbar, children) 36 | } 37 | .build 38 | 39 | def apply(children: VdomNode*) = 40 | component(children: _*) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/ActionSubscriber.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.ActionType 20 | 21 | import monix.execution.Ack 22 | import monix.execution.Ack.Continue 23 | import monix.reactive.Observer 24 | 25 | import slogging.LazyLogging 26 | 27 | import scala.concurrent.Future 28 | 29 | /** 30 | * Created by alonsodomin on 02/04/2016. 31 | */ 32 | final class ActionSubscriber[A: ActionType](errorHandler: PartialFunction[Throwable, Unit]) 33 | extends Observer[A] with LazyLogging { 34 | 35 | override def onError(ex: Throwable): Unit = { 36 | logger.debug("Action stream threw an exception.", ex) 37 | if (errorHandler.isDefinedAt(ex)) errorHandler(ex) 38 | } 39 | 40 | override def onComplete(): Unit = () 41 | 42 | override def onNext(elem: A): Future[Ack] = { 43 | ConsoleCircuit.dispatch(elem) 44 | Future.successful(Continue) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/AuthHandler.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.{ActionHandler, ActionResult} 20 | 21 | import io.quckoo.auth.Passport 22 | 23 | /** 24 | * Created by alonsodomin on 26/03/2016. 25 | */ 26 | trait AuthHandler[S] { this: ActionHandler[ConsoleScope, S] => 27 | 28 | def withAuth(f: Passport => ActionResult[ConsoleScope]): ActionResult[ConsoleScope] = 29 | this.modelRW.root 30 | .zoomMap(_.passport)(identity) 31 | .value 32 | .map(f) 33 | .getOrElse(noChange) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/ConsoleHandler.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.{ActionHandler, ModelRW} 20 | 21 | /** 22 | * Created by alonsodomin on 14/05/2017. 23 | */ 24 | abstract class ConsoleHandler[A](modelRW: ModelRW[ConsoleScope, A]) 25 | extends ActionHandler[ConsoleScope, A](modelRW) 26 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/ConsoleScope.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import java.time.ZonedDateTime 20 | 21 | import io.quckoo.auth.Passport 22 | import io.quckoo.net.QuckooState 23 | 24 | import monocle.macros.Lenses 25 | 26 | /** 27 | * Created by alonsodomin on 20/02/2016. 28 | */ 29 | @Lenses final case class ConsoleScope private ( 30 | passport: Option[Passport], 31 | clusterState: QuckooState, 32 | userScope: UserScope, 33 | lastLogin: Option[ZonedDateTime], 34 | subscribed: Boolean 35 | ) 36 | 37 | object ConsoleScope { 38 | 39 | def initial = 40 | ConsoleScope( 41 | passport = None, 42 | clusterState = QuckooState(), 43 | userScope = UserScope.initial, 44 | lastLogin = None, 45 | subscribed = false 46 | ) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/Effects.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import cats.data.NonEmptyList 20 | 21 | import diode._ 22 | 23 | import scala.concurrent.ExecutionContext 24 | 25 | /** 26 | * Created by alonsodomin on 05/07/2016. 27 | */ 28 | object Effects { 29 | 30 | def seq[E <: Effect](effects: NonEmptyList[E])(implicit ec: ExecutionContext): EffectSeq = 31 | seq(effects.head, effects.tail: _*) 32 | 33 | def seq(head: Effect, tail: Effect*)(implicit ec: ExecutionContext): EffectSeq = 34 | new EffectSeq(head, tail, ec) 35 | 36 | def parallel(head: Effect, tail: Effect*)(implicit ec: ExecutionContext): EffectSet = 37 | new EffectSet(head, tail.toSet, ec) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/ExecutionFetcher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.data.Fetch 20 | 21 | import io.quckoo.TaskId 22 | 23 | /** 24 | * Created by alonsodomin on 28/05/2016. 25 | */ 26 | object ExecutionFetcher extends Fetch[TaskId] { 27 | 28 | override def fetch(key: TaskId): Unit = 29 | ConsoleCircuit.dispatch(RefreshExecutions(Set(key))) 30 | 31 | override def fetch(keys: Traversable[TaskId]): Unit = 32 | ConsoleCircuit.dispatch(RefreshExecutions(keys.toSet)) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/ExecutionPlanFetcher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.data.Fetch 20 | 21 | import io.quckoo.PlanId 22 | 23 | /** 24 | * Created by alonsodomin on 14/03/2016. 25 | */ 26 | object ExecutionPlanFetcher extends Fetch[PlanId] { 27 | override def fetch(key: PlanId): Unit = 28 | ConsoleCircuit.dispatch(RefreshExecutionPlans(keys = Set(key))) 29 | 30 | override def fetch(keys: Traversable[PlanId]): Unit = 31 | ConsoleCircuit.dispatch(RefreshExecutionPlans(keys.toSet)) 32 | } 33 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/JobSpecFetcher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.data.Fetch 20 | 21 | import io.quckoo.JobId 22 | 23 | /** 24 | * Created by alonsodomin on 14/03/2016. 25 | */ 26 | object JobSpecFetcher extends Fetch[JobId] { 27 | 28 | override def fetch(key: JobId): Unit = 29 | ConsoleCircuit.dispatch(RefreshJobSpecs(keys = Set(key))) 30 | 31 | override def fetch(keys: Traversable[JobId]): Unit = 32 | ConsoleCircuit.dispatch(RefreshJobSpecs(keys.toSet)) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/UserScope.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.core 18 | 19 | import diode.data._ 20 | 21 | import io.quckoo._ 22 | 23 | import monocle.macros.Lenses 24 | 25 | @Lenses final case class UserScope( 26 | jobSpecs: PotMap[JobId, JobSpec], 27 | executionPlans: PotMap[PlanId, ExecutionPlan], 28 | executions: PotMap[TaskId, TaskExecution] 29 | ) 30 | 31 | object UserScope { 32 | 33 | def initial = UserScope( 34 | jobSpecs = PotMap(JobSpecFetcher), 35 | executionPlans = PotMap(ExecutionPlanFetcher), 36 | executions = PotMap(ExecutionFetcher) 37 | ) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/core/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import diode.{ActionType, Effect} 20 | 21 | import scala.concurrent.ExecutionContext 22 | import scala.language.implicitConversions 23 | 24 | /** 25 | * Created by alonsodomin on 05/07/2016. 26 | */ 27 | package object core { 28 | 29 | implicit def action2Effect[A: ActionType](action: => A)(implicit ec: ExecutionContext): Effect = 30 | Effect.action[A](action) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/layout/ContextStyle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.layout 18 | 19 | import japgolly.univeq.UnivEq 20 | 21 | import scalacss.internal.StyleLookup 22 | 23 | /** 24 | * Created by alonsodomin on 20/02/2016. 25 | */ 26 | object ContextStyle extends Enumeration { 27 | val default, primary, success, info, warning, danger = Value 28 | 29 | implicit val equiv = UnivEq.force[Value] 30 | implicit val lookup = StyleLookup.scalaMap[ContextStyle.Value] 31 | } 32 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/layout/GlobalStyles.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.layout 18 | 19 | import CssSettings._ 20 | 21 | /** 22 | * Created by alonsodomin on 20/02/2016. 23 | */ 24 | object GlobalStyles extends StyleSheet.Inline { 25 | import dsl._ 26 | 27 | val bootstrap = lookAndFeel 28 | 29 | val pageToolbar = style( 30 | marginTop(15 px), 31 | marginBottom(10 px) 32 | ) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/layout/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import scalacss.devOrProdDefaults 20 | 21 | /** 22 | * Created by alonsodomin on 26/04/2017. 23 | */ 24 | package object layout { 25 | val CssSettings = devOrProdDefaults 26 | import CssSettings._ 27 | 28 | val lookAndFeel = new LookAndFeel 29 | } 30 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/BootstrapJQuery.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs 18 | 19 | import org.scalajs.jquery.JQuery 20 | 21 | import scala.scalajs.js 22 | 23 | /** 24 | * Created by alonsodomin on 20/02/2016. 25 | */ 26 | @js.native 27 | trait BootstrapJQuery extends JQuery { 28 | def modal(action: String): BootstrapJQuery = js.native 29 | def modal(options: js.Any): BootstrapJQuery = js.native 30 | } 31 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/BootstrapNotify.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs 18 | 19 | import org.scalajs.jquery.JQueryStatic 20 | 21 | import scala.scalajs.js 22 | import scala.scalajs.js.annotation.JSName 23 | 24 | /** 25 | * Created by alonsodomin on 28/03/2016. 26 | */ 27 | @js.native 28 | trait BootstrapNotify extends JQueryStatic { 29 | 30 | @JSName("notify") 31 | def showNotification(content: String, options: js.Any = js.Dynamic.literal()): this.type = 32 | js.native 33 | 34 | @JSName("notifyDefaults") 35 | def notificationDefaults(options: js.Any): BootstrapNotify = js.native 36 | 37 | @JSName("notifyClose") 38 | def closeNotification(id: String = "all"): BootstrapNotify = js.native 39 | 40 | } 41 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/codemirror/ChangeEvent.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs.codemirror 18 | 19 | import scala.scalajs.js 20 | 21 | /** 22 | * Created by alonsodomin on 03/03/2017. 23 | */ 24 | @js.native 25 | trait Position extends js.Object { 26 | def ch: Int = js.native 27 | def line: Int = js.native 28 | } 29 | 30 | @js.native 31 | trait ChangeEvent extends js.Object { 32 | def from: Position = js.native 33 | def to: Position = js.native 34 | def text: js.Array[String] = js.native 35 | def removed: js.Array[String] = js.native 36 | def origin: String = js.native 37 | } 38 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/codemirror/CodeMirrorReact.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs.codemirror 18 | 19 | import japgolly.scalajs.react.extra.Reusability 20 | 21 | /** 22 | * Created by alonsodomin on 03/03/2017. 23 | */ 24 | object CodeMirrorReact { 25 | implicit val lengthReuse: Reusability[Length] = Reusability.byRef 26 | implicit val readOnlyReuse: Reusability[ReadOnly] = Reusability.byRef 27 | } 28 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/codemirror/LineHandle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs.codemirror 18 | 19 | import scala.scalajs.js 20 | 21 | /** 22 | * Created by alonsodomin on 04/03/2017. 23 | */ 24 | @js.native 25 | trait LineHandle extends js.Object { 26 | def height: Int = js.native 27 | def text: String = js.native 28 | } 29 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/codemirror/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.libs 18 | 19 | import scala.scalajs.js.| 20 | 21 | /** 22 | * Created by alonsodomin on 03/03/2017. 23 | */ 24 | package object codemirror { 25 | 26 | type Length = Int | String 27 | type Width = Length 28 | type Height = Length 29 | 30 | type ReadOnly = Boolean | String 31 | 32 | } 33 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/libs/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import org.scalajs.jquery.{JQuery, JQueryStatic} 20 | 21 | import scala.language.implicitConversions 22 | 23 | /** 24 | * Created by alonsodomin on 02/03/2017. 25 | */ 26 | package object libs { 27 | 28 | // JQuery plugins 29 | 30 | implicit def toBootstrapJQuery(jq: JQuery): BootstrapJQuery = 31 | jq.asInstanceOf[BootstrapJQuery] 32 | 33 | implicit def jq2Notify(jq: JQueryStatic): BootstrapNotify = 34 | jq.asInstanceOf[BootstrapNotify] 35 | 36 | } 37 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/log/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import cats.Order 20 | 21 | /** 22 | * Created by alonsodomin on 07/05/2017. 23 | */ 24 | package object log { 25 | type Logger[A] = PartialFunction[A, LogRecord] 26 | 27 | implicit val logLevelOrdering: Ordering[LogLevel] = Ordering.by(_.value) 28 | 29 | implicit val logLevelOrder: Order[LogLevel] = Order.fromOrdering 30 | 31 | } 32 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/registry/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import io.quckoo.console.core.ConsoleCircuit.Implicits.consoleClock 20 | import io.quckoo.console.core.RegisterJobResult 21 | import io.quckoo.console.log._ 22 | import io.quckoo.protocol.Event 23 | import io.quckoo.protocol.registry.{JobDisabled, JobEnabled} 24 | 25 | /** 26 | * Created by alonsodomin on 14/05/2017. 27 | */ 28 | package object registry { 29 | 30 | final val RegistryLogger: Logger[Event] = { 31 | case RegisterJobResult(validated) => 32 | validated.fold( 33 | errs => LogRecord.error(""), 34 | jobId => LogRecord.info(s"Job '$jobId' has been registered.") 35 | ) 36 | 37 | case JobEnabled(jobId) => 38 | LogRecord.info(s"Job '$jobId' has been enabled") 39 | 40 | case JobDisabled(jobId) => 41 | LogRecord.info(s"Job '$jobId' has been disabled") 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/security/PrincipalWidget.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.security 18 | 19 | import io.quckoo.auth.Principal 20 | import io.quckoo.console.components._ 21 | 22 | import japgolly.scalajs.react._ 23 | import japgolly.scalajs.react.vdom.html_<^._ 24 | 25 | /** 26 | * Created by alonsodomin on 20/02/2016. 27 | */ 28 | object PrincipalWidget { 29 | 30 | private[this] val component = ScalaComponent 31 | .builder[Principal]("UserDisplay") 32 | .render_P { user => 33 | <.span(Icons.user, user.id) 34 | } build 35 | 36 | def apply(user: Principal) = component(user) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/validation/ValidatedField.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.validation 18 | 19 | import io.quckoo.validation.Violation 20 | 21 | /** 22 | * Created by alonsodomin on 01/03/2016. 23 | */ 24 | case class ValidatedField[A](value: Option[A] = None, violation: Option[Violation] = None) { 25 | 26 | def valid = value.isDefined && violation.isEmpty 27 | 28 | def invalid = value.isDefined && violation.nonEmpty 29 | 30 | } 31 | -------------------------------------------------------------------------------- /console/src/main/scala/io/quckoo/console/validation/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import io.quckoo.validation._ 20 | 21 | import japgolly.scalajs.react.CallbackTo 22 | import japgolly.scalajs.react.CatsReact._ 23 | 24 | /** 25 | * Created by alonsodomin on 21/02/2016. 26 | */ 27 | package object validation { 28 | type ValidatorCallback[A] = ValidatorK[CallbackTo, A] 29 | 30 | implicit class ReactValidatorSyntax[A](self: Validator[A]) { 31 | def callback: ValidatorCallback[A] = self.lift[CallbackTo] 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/components/NavBarObserver.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import io.quckoo.console.test.ConsoleTestExports._ 20 | 21 | import org.scalajs.dom.html 22 | 23 | /** 24 | * Created by alonsodomin on 28/07/2016. 25 | */ 26 | class NavBarObserver($ : HtmlDomZipper) { 27 | 28 | val navItems = $.collect0n("li[role=presentation]").mapZippers { z => 29 | val anchor = z("a") 30 | Symbol(anchor.innerText) -> anchor.domAs[html.Anchor] 31 | } toMap 32 | 33 | val activeNavItem = 34 | $.collect01("li.active").mapZippers(zipper => Symbol(zipper("a").innerText)) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/components/NavBarTestDsl.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import io.quckoo.console.test.ConsoleTestExports 20 | 21 | import monocle.macros.Lenses 22 | 23 | import japgolly.scalajs.react.test._ 24 | 25 | /** 26 | * Created by alonsodomin on 29/07/2016. 27 | */ 28 | object NavBarTestDsl { 29 | import ConsoleTestExports._ 30 | import ReactTestUtils._ 31 | 32 | @Lenses 33 | final case class State(currentItem: Option[Symbol] = None) 34 | 35 | val dsl = Dsl[Unit, NavBarObserver, State] 36 | 37 | def selectItem(item: Symbol): dsl.Actions = 38 | dsl 39 | .action(s"Select nav item $item")(Simulate click _.obs.navItems(item)) 40 | .updateState(State.currentItem.set(Some(item))) 41 | 42 | val currentItem = 43 | dsl.focus("Current selected item").value(_.obs.activeNavItem) 44 | 45 | } 46 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/components/TextAreaObserver.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.components 18 | 19 | import io.quckoo.console.test.ConsoleTestExports._ 20 | 21 | import org.scalajs.dom.html 22 | 23 | /** 24 | * Created by alonsodomin on 25/02/2017. 25 | */ 26 | class TextAreaObserver($ : HtmlDomZipper) { 27 | 28 | val textArea = $("textarea").domAs[html.TextArea] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/scheduler/AtTriggerInputObserver.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.scheduler 18 | 19 | import io.quckoo.console.test.ConsoleTestExports._ 20 | 21 | import org.scalajs.dom.html 22 | 23 | class AtTriggerInputObserver($ : HtmlDomZipper) { 24 | 25 | val dateInput = $("#atTrigger_date").domAs[html.Input] 26 | val timeInput = $("#atTrigger_time").domAs[html.Input] 27 | 28 | } 29 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/scheduler/CronTriggerInputObserver.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.scheduler 18 | 19 | import io.quckoo.console.test.ConsoleTestExports._ 20 | 21 | import org.scalajs.dom.html 22 | 23 | /** 24 | * Created by alonsodomin on 03/09/2016. 25 | */ 26 | class CronTriggerInputObserver($ : HtmlDomZipper) { 27 | 28 | val expressionInput = $("#cronTrigger").domAs[html.Input] 29 | val parseError = $.collect01("#cronParseError") 30 | .mapZippers(_.domAs[html.Div]) 31 | .map(_.innerHTML) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/security/LoginObserver.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.security 18 | 19 | import io.quckoo.console.test.ConsoleTestExports._ 20 | 21 | import org.scalajs.dom.html 22 | 23 | /** 24 | * Created by alonsodomin on 10/07/2016. 25 | */ 26 | class LoginObserver($ : HtmlDomZipper) { 27 | 28 | val usernameInput = $("#username").domAs[html.Input] 29 | val passwordInput = $("#password").domAs[html.Input] 30 | val submitButton = $("button:contains('Sign in')").domAs[html.Button] 31 | 32 | val emptyUsername = usernameInput.value.isEmpty 33 | val emptyPassword = passwordInput.value.isEmpty 34 | val canSubmit = !submitButton.disabled 35 | 36 | } 37 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/test/ConsoleTestExports.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console.test 18 | 19 | import teststate.{Exports, ExtScalaJsReact, ExtCats} 20 | import teststate.domzipper.sizzle 21 | 22 | /** 23 | * Created by alonsodomin on 04/03/2017. 24 | */ 25 | object ConsoleTestExports extends Exports with ExtScalaJsReact with ExtCats with sizzle.Exports 26 | -------------------------------------------------------------------------------- /console/src/test/scala/io/quckoo/console/test/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.console 18 | 19 | import teststate.typeclass.Equal 20 | 21 | /** 22 | * Created by alonsodomin on 26/02/2017. 23 | */ 24 | package object test { 25 | 26 | implicit val symbolEq: Equal[Symbol] = Equal.by_== 27 | 28 | } 29 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/Job.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import java.util.concurrent.Callable 20 | 21 | /** 22 | * Created by domingueza on 06/07/15. 23 | */ 24 | trait Job extends Callable[Any] 25 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/JobSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.Show 20 | 21 | import io.quckoo.validation._ 22 | 23 | import monocle.macros.Lenses 24 | 25 | /** 26 | * Created by aalonsodominguez on 10/07/15. 27 | */ 28 | @Lenses final case class JobSpec( 29 | displayName: String, 30 | description: Option[String] = None, 31 | jobPackage: JobPackage, 32 | disabled: Boolean = false 33 | ) 34 | 35 | object JobSpec { 36 | 37 | val valid: Validator[JobSpec] = { 38 | import Validators._ 39 | 40 | val validDisplayName = nonEmpty[String].at("displayName") 41 | val validDetails = JobPackage.valid.at("jobPackage") 42 | 43 | caseClass4(validDisplayName, 44 | any[Option[String]], 45 | validDetails, 46 | any[Boolean])(JobSpec.unapply, JobSpec.apply) 47 | } 48 | 49 | implicit val display: Show[JobSpec] = Show.fromToString[JobSpec] 50 | 51 | } 52 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/Task.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.Show 20 | import cats.syntax.contravariant._ 21 | 22 | /** 23 | * Created by aalonsodominguez on 05/07/15. 24 | */ 25 | final case class Task( 26 | id: TaskId, 27 | jobPackage: JobPackage 28 | //params: Map[String, AnyVal] = Map.empty, 29 | ) 30 | 31 | object Task { 32 | 33 | implicit val showTask: Show[Task] = Show[JobPackage].contramap(_.jobPackage) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io 18 | 19 | import java.util.concurrent.Callable 20 | 21 | /** 22 | * Created by aalonsodominguez on 07/07/15. 23 | */ 24 | package object quckoo { 25 | 26 | final val Logo = 27 | s""" 28 | | ____ __ 29 | | / __ \\__ _______/ /______ ____ 30 | | / / / / / / / ___/ //_/ __ \\/ __ \\ 31 | | / /_/ / /_/ / /__/ ,< / /_/ / /_/ / 32 | | \\___\\_\\__,_/\\___/_/|_|\\____/\\____/ 33 | | v${Info.version} 34 | | 35 | """.stripMargin 36 | 37 | type JobClass = Class[_ <: Callable[_]] 38 | 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/Codec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization 18 | 19 | /** 20 | * Created by alonsodomin on 20/10/2016. 21 | */ 22 | trait Codec[A, Ser] extends Encoder[A, Ser] with Decoder[Ser, A] 23 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/Decoder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization 18 | 19 | import io.quckoo.util.Attempt 20 | 21 | import scala.annotation.implicitNotFound 22 | 23 | /** 24 | * Created by alonsodomin on 20/10/2016. 25 | */ 26 | @implicitNotFound("Can not decode ${In} into ${A} values") 27 | trait Decoder[In, A] { 28 | def decode(input: In): Attempt[A] 29 | } 30 | 31 | object Decoder { 32 | @inline def apply[In, A](implicit ev: Decoder[In, A]): Decoder[In, A] = ev 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/Encoder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization 18 | 19 | import io.quckoo.util.Attempt 20 | 21 | import scala.annotation.implicitNotFound 22 | 23 | /** 24 | * Created by alonsodomin on 20/10/2016. 25 | */ 26 | @implicitNotFound("Can not encode ${A} values into ${Out}") 27 | trait Encoder[A, Out] { 28 | def encode(a: A): Attempt[Out] 29 | } 30 | 31 | object Encoder { 32 | @inline def apply[A, Out](implicit ev: Encoder[A, Out]): Encoder[A, Out] = ev 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/base64/Scheme.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization.base64 18 | 19 | import scala.collection.immutable.HashMap 20 | 21 | /** 22 | * Created by alonsodomin on 20/10/2016. 23 | */ 24 | class Scheme(val encodeTable: IndexedSeq[Char]) { 25 | lazy val decodeTable = HashMap(encodeTable.zipWithIndex: _*) 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/base64/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization 18 | 19 | /** 20 | * Created by alonsodomin on 20/10/2016. 21 | */ 22 | package object base64 { 23 | private[base64] val zero = Array(0, 0).map(_.toByte) 24 | 25 | lazy val DefaultScheme = new Scheme( 26 | ('A' to 'Z') ++ ('a' to 'z') ++ ('0' to '9') ++ Seq('+', '/')) 27 | lazy val UrlScheme = new Scheme(DefaultScheme.encodeTable.dropRight(2) ++ Seq('-', '_')) 28 | 29 | implicit val Base64Codec = new Base64Codec(DefaultScheme) 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/serialization/json/Cron4s.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.serialization.json 18 | 19 | import cats.implicits._ 20 | 21 | import cron4s._ 22 | import cron4s.expr._ 23 | 24 | import io.circe.{Encoder, Decoder, DecodingFailure} 25 | 26 | /** 27 | * Created by alonsodomin on 03/09/2016. 28 | */ 29 | trait Cron4s { 30 | 31 | implicit val cronExprEncoder: Encoder[CronExpr] = 32 | Encoder[String].contramap(_.toString) 33 | 34 | implicit val cronExprDecoder: Decoder[CronExpr] = Decoder.instance { c => 35 | c.as[String] match { 36 | case Right(expr) => Cron(expr).leftMap(_ => DecodingFailure("Cron", c.history)) 37 | case l @ Left(_) => l.asInstanceOf[Decoder.Result[CronExpr]] 38 | } 39 | } 40 | 41 | } 42 | 43 | object cron extends Cron4s -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/time/implicits.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.time 18 | 19 | import java.time.Clock 20 | 21 | /** 22 | * Created by alonsodomin on 11/08/2016. 23 | */ 24 | object implicits { 25 | 26 | implicit val systemClock = Clock.systemUTC 27 | 28 | } 29 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/util/IsTraversable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.util 18 | 19 | /** 20 | * Created by alonsodomin on 21/10/2016. 21 | */ 22 | trait IsTraversable[A] { 23 | type Elem 24 | type T[x] <: Traversable[_] 25 | 26 | def subst(a: A): T[Elem] 27 | } 28 | 29 | object IsTraversable { 30 | def apply[A](implicit ev: IsTraversable[A]): IsTraversable[A] = ev 31 | 32 | implicit def mk[A, E, T0[_] <: Traversable[_]](implicit ev: A => T0[E]): IsTraversable[A] = 33 | new IsTraversable[A] { 34 | type Elem = E 35 | type T[x] = T0[x] 36 | 37 | def subst(a: A): T[E] = ev(a) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/validation/OptionValidators.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.validation 18 | 19 | import cats.{Applicative, Id} 20 | 21 | import Violation.Undefined 22 | 23 | /** 24 | * Created by alonsodomin on 21/10/2016. 25 | */ 26 | trait OptionValidators { 27 | 28 | def definedK[F[_]: Applicative, A]: ValidatorK[F, Option[A]] = 29 | Validator[F, Option[A]](a => Applicative[F].pure(a.isEmpty), _ => Undefined) 30 | 31 | def defined[A]: Validator[Option[A]] = definedK[Id, A] 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/validation/TraversableValidators.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.validation 18 | 19 | import cats.{Applicative, Id} 20 | 21 | import io.quckoo.util.IsTraversable 22 | 23 | /** 24 | * Created by alonsodomin on 21/10/2016. 25 | */ 26 | trait TraversableValidators { 27 | 28 | def nonEmptyK[F[_]: Applicative, A](implicit ev: IsTraversable[A]): ValidatorK[F, A] = 29 | Validator[F, A](a => Applicative[F].pure(ev.subst(a).nonEmpty), _ => Violation.Empty) 30 | 31 | def nonEmpty[A](implicit ev: IsTraversable[A]): Validator[A] = nonEmptyK[Id, A] 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/scala/io/quckoo/validation/Validators.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.validation 18 | 19 | /** 20 | * Created by alonsodomin on 21/10/2016. 21 | */ 22 | object Validators 23 | extends AnyValidators 24 | with OrderValidators 25 | with OptionValidators 26 | with TraversableValidators 27 | with CaseClassValidators 28 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/ArtifactIdSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.implicits._ 20 | 21 | import io.quckoo.validation._ 22 | 23 | import org.scalatest.{FlatSpec, Matchers} 24 | 25 | /** 26 | * Created by alonsodomin on 24/01/2016. 27 | */ 28 | class ArtifactIdSpec extends FlatSpec with Matchers { 29 | import Violation._ 30 | 31 | "ArtifactId" should "not accept empty strings" in { 32 | val expectedError = 33 | PathViolation(Path("organization"), Empty) and 34 | PathViolation(Path("name"), Empty) and 35 | PathViolation(Path("version"), Empty) 36 | 37 | ArtifactId.valid.run(ArtifactId("", "", "")) shouldBe expectedError.invalid[ArtifactId] 38 | } 39 | 40 | it should "accept any other values" in { 41 | val expectedArtifactId = ArtifactId("foo", "bar", "baz") 42 | ArtifactId.valid.run(expectedArtifactId) shouldBe expectedArtifactId.valid[Violation] 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/IdValSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.{Eq, Show} 20 | 21 | import io.quckoo.serialization.json.JsonCodec 22 | import io.quckoo.util.Attempt 23 | 24 | import org.scalatest.{FlatSpec, Matchers} 25 | 26 | /** 27 | * Created by domingueza on 27/02/2017. 28 | */ 29 | abstract class IdValSpec[A : Eq : Show](name: String)(implicit jsonCodec: JsonCodec[A]) extends FlatSpec with Matchers { 30 | 31 | def generateTestId(): A 32 | 33 | name should "be JSON compatible" in { 34 | val givenId = generateTestId() 35 | 36 | jsonCodec.encode(givenId).flatMap(jsonCodec.decode) shouldBe Attempt.success(givenId) 37 | } 38 | 39 | it should "be equal to itself" in { 40 | val givenId = generateTestId() 41 | assert(givenId === givenId) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/JobIdSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import io.quckoo.serialization.json._ 20 | 21 | /** 22 | * Created by alonsodomin on 26/02/2017. 23 | */ 24 | class JobIdSpec extends IdValSpec[JobId]("JobId") { 25 | 26 | override def generateTestId(): JobId = { 27 | val jobSpec = JobSpec("Foo", jobPackage = JobPackage.shell("bar")) 28 | JobId(jobSpec) 29 | } 30 | 31 | it should "be it's package checksum" in { 32 | val givenJobSpec = JobSpec("Foo", jobPackage = JobPackage.shell("bar")) 33 | 34 | val returnedJobId = JobId(givenJobSpec) 35 | 36 | returnedJobId shouldBe JobId(givenJobSpec.jobPackage.checksum) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/NodeIdSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import java.util.UUID 20 | 21 | import io.quckoo.serialization.json._ 22 | 23 | /** 24 | * Created by domingueza on 27/02/2017. 25 | */ 26 | class NodeIdSpec extends IdValSpec[NodeId]("NodeId") { 27 | override def generateTestId(): NodeId = NodeId(UUID.randomUUID()) 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/PlanIdSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import java.util.UUID 20 | 21 | import io.quckoo.serialization.json._ 22 | 23 | /** 24 | * Created by domingueza on 27/02/2017. 25 | */ 26 | class PlanIdSpec extends IdValSpec[PlanId]("PlanId") { 27 | 28 | override def generateTestId(): PlanId = PlanId(UUID.randomUUID()) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /core/src/test/scala/io/quckoo/TaskIdSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import java.util.UUID 20 | 21 | import io.quckoo.serialization.json._ 22 | 23 | /** 24 | * Created by domingueza on 27/02/2017. 25 | */ 26 | class TaskIdSpec extends IdValSpec[TaskId]("TaskId") { 27 | 28 | override def generateTestId(): TaskId = TaskId(UUID.randomUUID()) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | quckoo.io -------------------------------------------------------------------------------- /docs/diagrams/RegisterJobWorkflow.drawing: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/diagrams/RegisterJobWorkflow.drawing -------------------------------------------------------------------------------- /docs/diagrams/ScheduleJobWorkflow.drawing: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/diagrams/ScheduleJobWorkflow.drawing -------------------------------------------------------------------------------- /docs/diagrams/Topology.drawing: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/diagrams/Topology.drawing -------------------------------------------------------------------------------- /docs/img/RegisterJobWorkflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/img/RegisterJobWorkflow.jpg -------------------------------------------------------------------------------- /docs/img/ScheduleJobWorkflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/img/ScheduleJobWorkflow.jpg -------------------------------------------------------------------------------- /docs/img/Topology.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/docs/img/Topology.jpg -------------------------------------------------------------------------------- /examples/jobs/src/main/java/io/quckoo/examples/HelloWorldJob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.examples; 18 | 19 | import io.quckoo.Job; 20 | 21 | /** 22 | * Created by alonsodomin on 27/07/2016. 23 | */ 24 | public class HelloWorldJob implements Job { 25 | 26 | @Override 27 | public Object call() throws Exception { 28 | System.out.println("Hello World!"); 29 | return null; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /examples/jobs/src/main/java/io/quckoo/examples/parameters/PowerOfNJob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.examples.parameters; 18 | 19 | import io.quckoo.Job; 20 | 21 | /** 22 | * Created by aalonsodominguez on 24/07/15. 23 | */ 24 | public class PowerOfNJob implements Job { 25 | 26 | public int n = 0; 27 | 28 | @Override 29 | public Object call() throws Exception { 30 | int res = n * n; 31 | return String.format("n * n = %d", res); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /examples/producers/src/main/scala/io/quckoo/examples/CliOptions.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.examples 18 | 19 | import java.util.{HashMap => JHashMap, Map => JMap} 20 | 21 | import scala.collection.JavaConverters._ 22 | 23 | /** 24 | * Created by aalonsodominguez on 04/10/2015. 25 | */ 26 | object CliOptions { 27 | 28 | final val QuckooContactPoints = "quckoo.contact-points" 29 | 30 | } 31 | 32 | case class CliOptions(clusterNodes: Seq[String] = Seq()) { 33 | import CliOptions._ 34 | 35 | def asJavaMap: JMap[String, Object] = { 36 | val map = new JHashMap[String, Object]() 37 | map.put(QuckooContactPoints, clusterNodes.map { node => 38 | s"akka.tcp://QuckooClusterSystem@$node" 39 | }.asJava) 40 | map 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /examples/producers/src/universal/conf/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /master/src/main/assets/css/_globals.scss: -------------------------------------------------------------------------------- 1 | $bodyOffset: 60px; -------------------------------------------------------------------------------- /master/src/main/assets/css/_header.scss: -------------------------------------------------------------------------------- 1 | @import "globals.scss"; 2 | 3 | /* The fixed navbar requires changing the padding */ 4 | body { 5 | padding-top: $bodyOffset; 6 | } -------------------------------------------------------------------------------- /master/src/main/assets/css/_imports.scss: -------------------------------------------------------------------------------- 1 | @import "lib/animatewithsass/animate.scss"; 2 | 3 | @import "lib/codemirror/lib/codemirror"; 4 | @import "lib/codemirror/theme/monokai"; 5 | @import "lib/codemirror/theme/solarized"; -------------------------------------------------------------------------------- /master/src/main/assets/css/application.scss: -------------------------------------------------------------------------------- 1 | @import "imports.scss"; 2 | @import "globals.scss"; 3 | @import "header.scss"; 4 | 5 | .center-container { 6 | position: relative; 7 | } 8 | 9 | #loginPanel { 10 | width: 350px; 11 | height: 300px; 12 | position: absolute; 13 | left: 50%; 14 | top: 50%; 15 | margin-left: -150px; 16 | margin-top: 40px; 17 | } 18 | 19 | .modal-dialog { 20 | max-height: 80%; 21 | } 22 | 23 | /*.modal-dialog,*/ 24 | .modal-content { 25 | /* 80% of window height */ 26 | height: 100%; 27 | } 28 | 29 | .modal-body { 30 | /* 100% = dialog height, 120px = header + footer */ 31 | max-height: 600px; 32 | overflow-y: scroll; 33 | } 34 | 35 | .modal-footer { 36 | overflow-y: initial !important; 37 | height: 70%; 38 | max-height: calc(100% - 120px); 39 | } 40 | 41 | .modal-header { 42 | max-height: 70%; 43 | } 44 | 45 | // Required by BootstrapNotify 46 | 47 | [data-notify="progressbar"] { 48 | margin-bottom: 0px; 49 | position: absolute; 50 | bottom: 0px; 51 | left: 0px; 52 | width: 100%; 53 | height: 5px; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /master/src/main/assets/img/hourglass.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alonsodomin/quckoo/84b339cbc0f3ef7e3fb8d1ae02ed04c27af2a9e6/master/src/main/assets/img/hourglass.gif -------------------------------------------------------------------------------- /master/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/QuckooRoles.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster 18 | 19 | /** 20 | * Created by alonsodomin on 25/02/2017. 21 | */ 22 | object QuckooRoles { 23 | 24 | final val Registry = "registry" 25 | final val Scheduler = "scheduler" 26 | 27 | } 28 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/config/model.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.config 18 | 19 | import com.typesafe.config.Config 20 | 21 | import io.quckoo.config._ 22 | import io.quckoo.resolver.config.IvyConfig 23 | 24 | import pureconfig._ 25 | 26 | import eu.timepit.refined.pureconfig._ 27 | 28 | import scala.concurrent.duration.FiniteDuration 29 | import scala.util.Try 30 | 31 | final case class ClusterSettings( 32 | resolver: IvyConfig, 33 | taskQueue: TaskQueueSettings, 34 | http: HttpSettings 35 | ) 36 | 37 | object ClusterSettings { 38 | final val Namespace = "quckoo" 39 | 40 | def apply(config: Config): Try[ClusterSettings] = 41 | Try(loadConfigOrThrow[ClusterSettings](config, Namespace)) 42 | 43 | } 44 | 45 | final case class HttpSettings( 46 | bindInterface: IPv4, 47 | bindPort: PortNumber, 48 | requestTimeout: FiniteDuration 49 | ) 50 | final case class TaskQueueSettings(maxWorkTimeout: FiniteDuration) 51 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/core/ClusterStreams.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.core 18 | 19 | import akka.NotUsed 20 | import akka.stream.scaladsl.Source 21 | import io.quckoo.protocol.cluster.MasterEvent 22 | import io.quckoo.protocol.worker.WorkerEvent 23 | 24 | /** 25 | * Created by alonsodomin on 04/04/2016. 26 | */ 27 | trait ClusterStreams { 28 | 29 | def masterTopic: Source[MasterEvent, NotUsed] 30 | 31 | def workerTopic: Source[WorkerEvent, NotUsed] 32 | 33 | } 34 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/core/QuckooServer.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.core 18 | 19 | import io.quckoo.api.{Cluster, Registry, Scheduler} 20 | import io.quckoo.cluster.registry.RegistryStreams 21 | import io.quckoo.cluster.scheduler.SchedulerStreams 22 | 23 | /** 24 | * Created by alonsodomin on 14/10/2015. 25 | */ 26 | trait QuckooServer 27 | extends Auth with Cluster with ClusterStreams with Registry with RegistryStreams with Scheduler 28 | with SchedulerStreams 29 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/core/UserAuthenticator.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.core 18 | 19 | import akka.actor.{Actor, ActorLogging, Props} 20 | 21 | import io.quckoo.auth.UserId 22 | 23 | import scala.concurrent.duration.FiniteDuration 24 | 25 | /** 26 | * Created by alonsodomin on 14/10/2015. 27 | */ 28 | object UserAuthenticator { 29 | 30 | case class Authenticate(userId: UserId, password: Array[Char]) 31 | case class AuthenticationSuccess() 32 | case object AuthenticationFailed 33 | 34 | def props(sessionTimeout: FiniteDuration): Props = 35 | Props(classOf[UserAuthenticator], sessionTimeout) 36 | 37 | } 38 | 39 | class UserAuthenticator(sessionTimeout: FiniteDuration) extends Actor with ActorLogging { 40 | import UserAuthenticator._ 41 | 42 | def receive = { 43 | case Authenticate(userId, password) => 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/http/StaticResources.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.http 18 | 19 | import akka.http.scaladsl.server.Directives._ 20 | import akka.http.scaladsl.server.Route 21 | 22 | import io.quckoo.Info 23 | import io.quckoo.console.html.index 24 | 25 | /** 26 | * Created by alonsodomin on 07/07/2016. 27 | */ 28 | trait StaticResources { 29 | 30 | private[this] final val AssetsPath = "assets" 31 | private[this] final val PublicDir = "public/" 32 | 33 | def staticResources: Route = 34 | pathEndOrSingleSlash { 35 | get { 36 | complete(index(Info.version)) 37 | } 38 | } ~ pathPrefix(AssetsPath / Remaining) { file => 39 | // optionally compresses the response with Gzip or Deflate 40 | // if the client accepts compressed responses 41 | encodeResponse { 42 | getFromResource(PublicDir + file) 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/http/TimeoutDirectives.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.http 18 | 19 | import akka.http.scaladsl.server.Directives._ 20 | import akka.http.scaladsl.server._ 21 | 22 | import io.quckoo.api._ 23 | import io.quckoo.util.Attempt 24 | 25 | import scala.concurrent.duration._ 26 | 27 | /** 28 | * Created by alonsodomin on 30/10/2016. 29 | */ 30 | trait TimeoutDirectives { 31 | 32 | val DefaultTimeout = 2500 millis 33 | 34 | def extractTimeout(default: FiniteDuration): Directive1[FiniteDuration] = 35 | optionalHeaderValueByName(RequestTimeoutHeader).map(_.flatMap { timeoutValue => 36 | Attempt(timeoutValue.toLong).map(_ millis).toOption 37 | } getOrElse default) 38 | 39 | } 40 | 41 | object TimeoutDirectives extends TimeoutDirectives 42 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/journal/QuckooJournal.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.journal 18 | 19 | import akka.actor.ActorSystem 20 | import akka.persistence.query.{PersistenceQuery, Offset} 21 | 22 | /** 23 | * Created by alonsodomin on 23/12/2015. 24 | */ 25 | trait QuckooJournal { 26 | type ReadRepr <: ReadJournalRepr 27 | 28 | implicit def actorSystem: ActorSystem 29 | 30 | protected val journalId: String 31 | 32 | lazy val read = 33 | PersistenceQuery(actorSystem).readJournalFor[ReadRepr](journalId) 34 | 35 | def firstOffset: Offset 36 | 37 | } 38 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/journal/QuckooProductionJournal.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.journal 18 | 19 | import akka.actor.ActorSystem 20 | import akka.persistence.query.{Offset, TimeBasedUUID} 21 | import akka.persistence.cassandra.query.scaladsl.CassandraReadJournal 22 | 23 | /** 24 | * Created by alonsodomin on 10/09/2016. 25 | */ 26 | class QuckooProductionJournal(implicit val actorSystem: ActorSystem) extends QuckooJournal { 27 | type ReadRepr = CassandraReadJournal 28 | 29 | protected val journalId = CassandraReadJournal.Identifier 30 | 31 | def firstOffset: Offset = TimeBasedUUID(read.firstOffset) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/journal/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster 18 | 19 | import akka.persistence.query.scaladsl.{CurrentEventsByTagQuery, ReadJournal} 20 | 21 | /** 22 | * Created by alonsodomin on 10/09/2016. 23 | */ 24 | package object journal { 25 | 26 | type ReadJournalRepr = ReadJournal with CurrentEventsByTagQuery 27 | 28 | } 29 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | /** 20 | * Created by alonsodomin on 04/11/2016. 21 | */ 22 | package object cluster { 23 | final val SystemName = "QuckooClusterSystem" 24 | } 25 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/registry/RegistrySettings.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.registry 18 | 19 | import akka.actor.Props 20 | 21 | /** 22 | * Created by alonsodomin on 24/04/2016. 23 | */ 24 | final case class RegistrySettings(resolverProps: Props) 25 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/registry/RegistryStreams.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.registry 18 | 19 | import akka.NotUsed 20 | import akka.stream.scaladsl.Source 21 | import io.quckoo.protocol.registry.RegistryEvent 22 | 23 | /** 24 | * Created by alonsodomin on 28/03/2016. 25 | */ 26 | trait RegistryStreams { 27 | 28 | def registryTopic: Source[RegistryEvent, NotUsed] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/registry/RegistryTagEventAdapter.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.registry 18 | 19 | import akka.persistence.journal.{Tagged, WriteEventAdapter} 20 | import io.quckoo.protocol.registry.RegistryEvent 21 | 22 | /** 23 | * Created by alonsodomin on 10/04/2016. 24 | */ 25 | class RegistryTagEventAdapter extends WriteEventAdapter { 26 | override def manifest(event: Any): String = "" 27 | 28 | override def toJournal(event: Any): Any = event match { 29 | case evt: RegistryEvent => Tagged(evt, Set(Registry.EventTag)) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /master/src/main/scala/io/quckoo/cluster/scheduler/SchedulerStreams.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.scheduler 18 | 19 | import akka.NotUsed 20 | import akka.stream.scaladsl.Source 21 | 22 | import io.quckoo.protocol.scheduler.SchedulerEvent 23 | 24 | /** 25 | * Created by alonsodomin on 01/04/2016. 26 | */ 27 | trait SchedulerStreams { 28 | 29 | def schedulerTopic: Source[SchedulerEvent, NotUsed] 30 | 31 | } 32 | -------------------------------------------------------------------------------- /master/src/main/twirl/io/quckoo/console/index.scala.html: -------------------------------------------------------------------------------- 1 | @(version: String) 2 | 3 | @main(s"Quckoo Console $version") { 4 |
5 | } -------------------------------------------------------------------------------- /master/src/main/twirl/io/quckoo/console/main.scala.html: -------------------------------------------------------------------------------- 1 | @(title: String)(content: Html) 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | @title 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | @content 21 | @scalajs.html.scripts("quckoo-console", name => s"/assets/$name", name => getClass.getResource(s"/public/$name") != null) 22 | 23 | -------------------------------------------------------------------------------- /master/src/multi-jvm/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /master/src/multi-jvm/scala/io/quckoo/multijvm/ScalaTestMultiNodeSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.multijvm 18 | 19 | import akka.remote.testkit.MultiNodeSpecCallbacks 20 | import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} 21 | 22 | /** 23 | * Created by aalonsodominguez on 27/08/15. 24 | */ 25 | trait ScalaTestMultiNodeSpec extends MultiNodeSpecCallbacks with WordSpecLike with BeforeAndAfterAll with Matchers { 26 | 27 | override protected def beforeAll(): Unit = multiNodeSpecBeforeAll() 28 | 29 | override protected def afterAll(): Unit = multiNodeSpecAfterAll() 30 | 31 | } 32 | -------------------------------------------------------------------------------- /master/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /master/src/test/scala/io/quckoo/cluster/journal/QuckooTestJournal.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster.journal 18 | 19 | import akka.actor.ActorSystem 20 | import akka.persistence.query.{Offset, Sequence} 21 | import akka.persistence.inmemory.query.scaladsl.InMemoryReadJournal 22 | 23 | /** 24 | * Created by alonsodomin on 10/09/2016. 25 | */ 26 | class QuckooTestJournal(implicit val actorSystem: ActorSystem) extends QuckooJournal { 27 | type ReadRepr = InMemoryReadJournal 28 | 29 | protected val journalId = InMemoryReadJournal.Identifier 30 | 31 | def firstOffset: Offset = Sequence(0L) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /master/src/test/scala/io/quckoo/testkit/QuckooActorClusterSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.testkit 18 | 19 | import akka.cluster.Cluster 20 | 21 | import org.scalatest.Suite 22 | 23 | /** 24 | * Created by alonsodomin on 17/02/2017. 25 | */ 26 | abstract class QuckooActorClusterSuite(name: String) extends QuckooActorSuite(name) { 27 | 28 | override protected def beforeAll(): Unit = { 29 | super.beforeAll() 30 | 31 | val address = Cluster(system).selfAddress 32 | Cluster(system).join(address) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /master/src/universal/conf/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | work-dir = ${quckoo.home-dir}"/resolver" 7 | resolution-cache-dir = ${quckoo.resolver.work-dir}"/cache" 8 | repository-cache-dir = ${quckoo.resolver.work-dir}"/local" 9 | 10 | repositories = [ ] 11 | } 12 | 13 | store { 14 | cassandra { 15 | host = "" 16 | 17 | port = 0 18 | } 19 | } 20 | 21 | task-queue { 22 | max-work-timeout = 10m 23 | } 24 | } 25 | 26 | cassandra-journal.contact-points = [ ${quckoo.store.cassandra.host}":"${quckoo.store.cassandra.port} ] 27 | cassandra-snapshot-store.contact-points = [ ${quckoo.store.cassandra.host}":"${quckoo.store.cassandra.port} ] -------------------------------------------------------------------------------- /master/src/universal/conf/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /project/QuckooMultiJvmTesting.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | 4 | import com.typesafe.sbt.SbtMultiJvm 5 | import com.typesafe.sbt.SbtMultiJvm.autoImport._ 6 | 7 | import de.heikoseeberger.sbtheader.HeaderPlugin 8 | import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport._ 9 | 10 | import QuckooAppKeys._ 11 | 12 | object QuckooMultiJvmTesting extends AutoPlugin { 13 | 14 | override def requires: Plugins = QuckooApp && SbtMultiJvm && HeaderPlugin 15 | 16 | override def projectConfigurations: Seq[Configuration] = Seq(MultiJvm) 17 | 18 | override def projectSettings: Seq[Def.Setting[_]] = Seq( 19 | libraryDependencies ++= Seq( 20 | "com.typesafe.akka" %% "akka-multi-node-testkit" % Dependencies.version.akka.main, 21 | "org.scoverage" %% "scalac-scoverage-runtime" % "1.3.1" 22 | ).map(_ % MultiJvm), 23 | parallelExecution in MultiJvm := false, 24 | jvmOptions in MultiJvm := (sigarLoaderOptions in Test).value :+ "-Xmx512M" 25 | ) ++ headerSettings(MultiJvm) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.1.1 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | // Comment to get more information during initialization 2 | logLevel := Level.Warn 3 | 4 | // Project management plugins 5 | addSbtPlugin("de.heikoseeberger" % "sbt-header" % "4.0.0") 6 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") 7 | addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0") 8 | addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.7") 9 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.0") 10 | addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.15") 11 | addSbtPlugin("com.dwijnand" % "sbt-travisci" % "1.1.1") 12 | 13 | // Web plugins 14 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.22") 15 | addSbtPlugin("org.portable-scala" % "sbt-crossproject" % "0.3.1") 16 | addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.3.1") 17 | addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.0.6") 18 | addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.11") 19 | addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.3.13") 20 | 21 | // Server side plugins 22 | addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") 23 | addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.3") 24 | addSbtPlugin("com.typesafe.sbt" % "sbt-multi-jvm" % "0.4.0") 25 | addSbtPlugin("com.lightbend.sbt" % "sbt-aspectj" % "0.11.0") 26 | addSbtPlugin("com.tapad" % "sbt-docker-compose" % "1.0.34") 27 | 28 | // Code generators 29 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") 30 | -------------------------------------------------------------------------------- /sandbox/consul/etc/quckoo/master/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | repositories = [ ] 7 | } 8 | } 9 | 10 | akka { 11 | extensions = ["de.heikoseeberger.constructr.akka.ConstructrExtension"] 12 | 13 | cluster { 14 | auto-down-unreachable-after = 0s 15 | down-removal-margin = 100ms 16 | unreachable-nodes-reaper-interval = 250ms 17 | 18 | failure-detector { 19 | acceptable-heartbeat-pause = 1s 20 | hearbeat-interval = 250ms 21 | threshold = 4.0 22 | } 23 | } 24 | } 25 | 26 | constructr { 27 | coordination { 28 | host = "consul_agent" 29 | port = 8500 30 | } 31 | 32 | consul.agent-name = "consul_agent" 33 | } 34 | 35 | kamon.statsd { 36 | hostname = "graphite" 37 | port = 8125 38 | 39 | simple-metric-key-generator.application = "Quckoo" 40 | 41 | subscriptions { 42 | histogram = [ "**" ] 43 | min-max-counter = [ "**" ] 44 | gauge = [ "**" ] 45 | counter = [ "**" ] 46 | trace = [ "**" ] 47 | trace-segment = [ "**" ] 48 | akka-actor = [ "**" ] 49 | akka-dispatcher = [ "**" ] 50 | akka-router = [ "**" ] 51 | system-metric = [ "**" ] 52 | http-server = [ "**" ] 53 | } 54 | } -------------------------------------------------------------------------------- /sandbox/consul/etc/quckoo/master/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sandbox/consul/etc/quckoo/worker/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | repositories = [ ] 7 | } 8 | } 9 | 10 | kamon.statsd { 11 | hostname = "graphite" 12 | port = 8125 13 | 14 | simple-metric-key-generator.application = "Quckoo" 15 | 16 | subscriptions { 17 | histogram = [ "**" ] 18 | min-max-counter = [ "**" ] 19 | gauge = [ "**" ] 20 | counter = [ "**" ] 21 | trace = [ "**" ] 22 | trace-segment = [ "**" ] 23 | akka-actor = [ "**" ] 24 | akka-dispatcher = [ "**" ] 25 | akka-router = [ "**" ] 26 | system-metric = [ "**" ] 27 | http-server = [ "**" ] 28 | } 29 | } -------------------------------------------------------------------------------- /sandbox/consul/etc/quckoo/worker/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sandbox/standalone/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | cassandra: 4 | image: cassandra 5 | hostname: cassandra 6 | ports: 7 | - 9042:9042 8 | - 7000:7000 9 | - 9160:9160 10 | 11 | grafana: 12 | image: grafana/grafana 13 | hostname: grafana 14 | ports: 15 | - 3000:3000 16 | links: 17 | - prometheus 18 | 19 | prometheus: 20 | image: prom/prometheus 21 | hostname: prometheus 22 | ports: 23 | - 9090:9090 24 | volumes: 25 | - ./etc/prometheus/config.yml:/etc/prometheus/prometheus.yml 26 | 27 | master1: 28 | image: quckoo/master 29 | hostname: "master-01" 30 | ports: 31 | - 8095:8095 32 | - 2551:2551 33 | - 9095:9095 34 | links: 35 | - cassandra 36 | volumes: 37 | - ./etc/quckoo:/opt/quckoo/conf 38 | command: --seed --cs cassandra:9042 -b master1:2551 39 | 40 | master2: 41 | image: quckoo/master 42 | hostname: "master-02" 43 | ports: 44 | - 8096:8095 45 | - 2552:2551 46 | - 9096:9095 47 | links: 48 | - cassandra 49 | - master1 50 | volumes: 51 | - ./etc/quckoo:/opt/quckoo/conf 52 | command: --nodes master1:2551 --cs cassandra:9042 -b master2:2552 53 | 54 | worker: 55 | image: quckoo/worker 56 | hostname: "worker" 57 | ports: 58 | - 5001:5001 59 | - 9097:9095 60 | links: 61 | - master1 62 | - master2 63 | volumes: 64 | - ./etc/quckoo:/opt/quckoo/conf 65 | command: --master master1:2551,master2:2551 -b worker:5001 66 | -------------------------------------------------------------------------------- /sandbox/standalone/etc/prometheus/config.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | scrape_timeout: 10s 4 | evaluation_interval: 15s 5 | alerting: 6 | alertmanagers: 7 | - static_configs: 8 | - targets: [] 9 | scheme: http 10 | timeout: 10s 11 | scrape_configs: 12 | - job_name: prometheus 13 | scrape_interval: 15s 14 | scrape_timeout: 10s 15 | metrics_path: /metrics 16 | scheme: http 17 | static_configs: 18 | - targets: 19 | - localhost:9090 20 | - master1:9095 21 | - master2:9095 22 | - worker:9095 -------------------------------------------------------------------------------- /sandbox/standalone/etc/quckoo/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | repositories = [ ] 7 | } 8 | } 9 | 10 | kamon.statsd { 11 | hostname = "graphite" 12 | port = 8125 13 | 14 | simple-metric-key-generator.application = "Quckoo" 15 | 16 | subscriptions { 17 | histogram = [ "**" ] 18 | min-max-counter = [ "**" ] 19 | gauge = [ "**" ] 20 | counter = [ "**" ] 21 | trace = [ "**" ] 22 | trace-segment = [ "**" ] 23 | akka-actor = [ "**" ] 24 | akka-dispatcher = [ "**" ] 25 | akka-router = [ "**" ] 26 | system-metric = [ "**" ] 27 | http-server = [ "**" ] 28 | } 29 | } -------------------------------------------------------------------------------- /sandbox/standalone/etc/quckoo/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sandbox/vagrant/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Building project..." 4 | cd /vagrant 5 | 6 | sbt docker:publishLocal coreJVM/publish exampleJobs/publish 7 | 8 | -------------------------------------------------------------------------------- /sandbox/vagrant/docker-quckoo.yml: -------------------------------------------------------------------------------- 1 | master_1: 2 | image: quckoo/master 3 | container_name: master-01 4 | ports: 5 | - 8095:8095 6 | - 2551:2551 7 | volumes: 8 | - /vagrant/sandbox/vagrant/etc/quckoo:/opt/quckoo/conf 9 | command: -b 192.168.50.25:2551 --nodes 192.168.50.25:2551,192.168.50.25:2552 --cs 192.168.50.25:9042 10 | 11 | master_2: 12 | image: quckoo/master 13 | container_name: master-02 14 | ports: 15 | - 8096:8095 16 | - 2552:2551 17 | volumes: 18 | - /vagrant/sandbox/vagrant/etc/quckoo:/opt/quckoo/conf 19 | command: -b 192.168.50.25:2552 --nodes 192.168.50.25:2551,192.168.50.25:2552 --cs 192.168.50.25:9042 20 | 21 | worker_1: 22 | image: quckoo/worker 23 | container_name: worker-01 24 | links: 25 | - master_1:master_1 26 | - master_2:master_2 27 | ports: 28 | - 5001:5001 29 | volumes: 30 | - /vagrant/sandbox/vagrant/etc/quckoo:/opt/quckoo/conf 31 | command: --master 192.168.50.25:2551,192.168.50.25:2552 -b 192.168.50.25:5001 32 | 33 | worker_2: 34 | image: quckoo/worker 35 | container_name: worker-02 36 | links: 37 | - master_1:master_1 38 | - master_2:master_2 39 | ports: 40 | - 5002:5001 41 | volumes: 42 | - /vagrant/sandbox/vagrant/etc/quckoo:/opt/quckoo/conf 43 | command: --master 192.168.50.25:2551,192.168.50.25:2552 -b 192.168.50.25:5002 44 | -------------------------------------------------------------------------------- /sandbox/vagrant/docker-support.yml: -------------------------------------------------------------------------------- 1 | cassandra: 2 | image: cassandra 3 | container_name: cassandra 4 | ports: 5 | - 9042:9042 6 | - 7000:7000 7 | - 9160:9160 8 | volumes: 9 | - /var/lib/cassandra:/var/lib/cassandra 10 | 11 | artifactory: 12 | image: docker.bintray.io/jfrog/artifactory-oss 13 | container_name: artifactory 14 | ports: 15 | - 8081:8081 16 | 17 | -------------------------------------------------------------------------------- /sandbox/vagrant/etc/quckoo/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | repositories = [ 7 | { name: "Artifactory Releases", url: "http://192.168.50.25:8081/artifactory/libs-release/" }, 8 | { name: "Artifactory Snapshots", url: "http://192.168.50.25:8081/artifactory/libs-snapshot/" } 9 | ] 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /sandbox/vagrant/etc/quckoo/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sandbox/vagrant/etc/sbt/0.13/artifactory.sbt: -------------------------------------------------------------------------------- 1 | publishTo := { 2 | val baseUrl = "http://192.168.50.25:8081/artifactory/" 3 | val artifactoryUrl = if (isSnapshot.value) { 4 | baseUrl + "libs-snapshot-local;build.timestamp=" + System 5 | .currentTimeMillis() 6 | } else { 7 | baseUrl + "libs-release-local" 8 | } 9 | Some("Artifactory Realm" at artifactoryUrl) 10 | } 11 | credentials += Credentials("Artifactory Realm", 12 | "192.168.50.25", 13 | "admin", 14 | "password") 15 | -------------------------------------------------------------------------------- /scripts/travis-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sbt_cmd="sbt ++$TRAVIS_SCALA_VERSION" 4 | 5 | test_cmd="$sbt_cmd clean coverage test" 6 | validate_cmd="$sbt_cmd coverage master/multi-jvm:test" 7 | coverage_cmd="$sbt_cmd coverageReport && $sbt_cmd coverageAggregate" 8 | 9 | build_cmd="$test_cmd && $coverage_cmd" 10 | 11 | eval $build_cmd -------------------------------------------------------------------------------- /scripts/travis-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Installing SASS compiler..." 4 | gem install compass 5 | 6 | echo "Installing Node..." 7 | nvm install node 8 | 9 | echo "Installing PhantomJS 2..." 10 | npm install -g phantomjs-prebuilt -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/cluster/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | /** 20 | * Created by aalonsodominguez on 17/08/15. 21 | */ 22 | package object cluster { 23 | 24 | final val BaseConfigNamespace = "quckoo" 25 | 26 | } 27 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/cluster/pattern/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.cluster 18 | 19 | import akka.actor.Scheduler 20 | import akka.pattern.after 21 | 22 | import scala.concurrent.{ExecutionContext, Future} 23 | import scala.concurrent.duration.FiniteDuration 24 | 25 | /** 26 | * Created by alonsodomin on 30/09/2016. 27 | */ 28 | package object pattern { 29 | 30 | def retry[T](f: => Future[T], delay: FiniteDuration, retries: Int)(implicit ec: ExecutionContext, 31 | s: Scheduler): Future[T] = 32 | f recoverWith { 33 | case _ if retries > 0 => after(delay, s)(retry(f, delay, retries - 1)) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/Artifact.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect 18 | 19 | import java.net.URL 20 | 21 | import cats.{Eq, Show} 22 | import cats.implicits._ 23 | 24 | import io.quckoo.ArtifactId 25 | 26 | /** 27 | * Created by aalonsodominguez on 17/07/15. 28 | */ 29 | object Artifact { 30 | 31 | implicit val artifactEq: Eq[Artifact] = Eq.fromUniversalEquals 32 | 33 | implicit val artifactShow: Show[Artifact] = Show.show { artifact => 34 | val classpath = artifact.classpath.mkString(":") 35 | show"${artifact.artifactId} :: $classpath" 36 | } 37 | 38 | } 39 | 40 | final case class Artifact(artifactId: ArtifactId, classpath: List[URL]) { 41 | 42 | lazy val classLoader: ClassLoader = new ArtifactClassLoader(classpath.toArray) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/ReflectOp.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect 18 | 19 | import io.quckoo.{Job, JobClass} 20 | 21 | /** 22 | * Created by alonsodomin on 04/05/2017. 23 | */ 24 | sealed trait ReflectOp[A] 25 | object ReflectOp { 26 | case class LoadJobClass(artifact: Artifact, className: String) extends ReflectOp[JobClass] 27 | case class CreateJob(jobClass: JobClass) extends ReflectOp[Job] 28 | case class RunJob(job: Job) extends ReflectOp[Unit] 29 | } 30 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/ReflectorInterpreter.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect 18 | 19 | import cats.{Monad, ~>} 20 | 21 | /** 22 | * Created by alonsodomin on 04/05/2017. 23 | */ 24 | class ReflectorInterpreter[F[_]: Monad](impl: Reflector[F]) extends (ReflectOp ~> F) { 25 | 26 | override def apply[A](fa: ReflectOp[A]): F[A] = fa match { 27 | case ReflectOp.LoadJobClass(artifact, className) => 28 | impl.loadJobClass(artifact, className) 29 | case ReflectOp.CreateJob(jobClass) => impl.createJob(jobClass) 30 | case ReflectOp.RunJob(job) => impl.runJob(job) 31 | } 32 | 33 | } 34 | 35 | object ReflectorInterpreter { 36 | 37 | implicit def deriveInterpreter[F[_]: Monad]( 38 | implicit reflector: Reflector[F] 39 | ): ReflectorInterpreter[F] = 40 | new ReflectorInterpreter[F](reflector) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/javareflect/JavaReflector.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect.javareflect 18 | 19 | import cats.effect.IO 20 | import cats.syntax.show._ 21 | 22 | import io.quckoo.reflect.{Artifact, Reflector} 23 | import io.quckoo.{Job, JobClass} 24 | 25 | import slogging.LazyLogging 26 | 27 | /** 28 | * Created by alonsodomin on 04/05/2017. 29 | */ 30 | class JavaReflector private[reflect] () extends Reflector[IO] with LazyLogging { 31 | 32 | override def loadJobClass(artifact: Artifact, className: String): IO[JobClass] = IO { 33 | logger.debug("Loading job class {} from artifact {}", className, artifact.artifactId.show) 34 | artifact.classLoader.loadClass(className).asInstanceOf[JobClass] 35 | } 36 | 37 | override def createJob(jobClass: JobClass): IO[Job] = IO { 38 | jobClass.newInstance().asInstanceOf[Job] 39 | } 40 | 41 | override def runJob(job: Job): IO[Unit] = IO { job.call(); () } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/javareflect/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect 18 | 19 | import cats.effect.IO 20 | 21 | /** 22 | * Created by alonsodomin on 06/05/2017. 23 | */ 24 | package object javareflect { 25 | 26 | implicit val javaReflector: Reflector[IO] = new JavaReflector 27 | 28 | } 29 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/ops.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.reflect 18 | 19 | import cats.free.Free 20 | 21 | import io.quckoo.{Job, JobClass} 22 | 23 | /** 24 | * Created by alonsodomin on 04/05/2017. 25 | */ 26 | object ops extends Reflector[ReflectIO] { 27 | 28 | override def loadJobClass(artifact: Artifact, className: String): ReflectIO[JobClass] = 29 | Free.liftF(ReflectOp.LoadJobClass(artifact, className)) 30 | 31 | override def createJob(jobClass: JobClass): ReflectIO[Job] = 32 | Free.liftF(ReflectOp.CreateJob(jobClass)) 33 | 34 | override def runJob(job: Job): ReflectIO[Unit] = 35 | Free.liftF(ReflectOp.RunJob(job)) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/reflect/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.Monad 20 | import cats.free.Free 21 | 22 | /** 23 | * Created by alonsodomin on 04/05/2017. 24 | */ 25 | package object reflect { 26 | type ReflectIO[A] = Free[ReflectOp, A] 27 | 28 | implicit class ReflectIOOps[A](val self: ReflectIO[A]) extends AnyVal { 29 | 30 | def to[F[_]: Monad](implicit interpreter: ReflectorInterpreter[F]): F[A] = 31 | self.foldMap(interpreter) 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/resolver/ResolverInterpreter.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.resolver 18 | 19 | import cats.{Monad, ~>} 20 | 21 | /** 22 | * Created by alonsodomin on 04/05/2017. 23 | */ 24 | final class ResolverInterpreter[F[_]: Monad] private (impl: Resolver[F]) extends (ResolverOp ~> F) { 25 | 26 | override def apply[A](fa: ResolverOp[A]): F[A] = fa match { 27 | case ResolverOp.Validate(artifactId) => impl.validate(artifactId) 28 | case ResolverOp.Download(artifactId) => impl.download(artifactId) 29 | } 30 | 31 | } 32 | 33 | object ResolverInterpreter { 34 | 35 | implicit def deriveInstance[F[_]: Monad](implicit impl: Resolver[F]): ResolverInterpreter[F] = 36 | new ResolverInterpreter[F](impl) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/resolver/ResolverOp.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.resolver 18 | 19 | import cats.data.ValidatedNel 20 | import io.quckoo.reflect.Artifact 21 | import io.quckoo.{ArtifactId, DependencyError} 22 | 23 | /** 24 | * Created by alonsodomin on 03/05/2017. 25 | */ 26 | sealed trait ResolverOp[A] 27 | object ResolverOp { 28 | case class Validate(artifactId: ArtifactId) 29 | extends ResolverOp[ValidatedNel[DependencyError, ArtifactId]] 30 | case class Download(artifactId: ArtifactId) 31 | extends ResolverOp[ValidatedNel[DependencyError, Artifact]] 32 | } 33 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/resolver/config/IvyConfig.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.resolver.config 18 | 19 | import java.io.File 20 | 21 | import io.quckoo.resolver.{MavenRepository, Repository} 22 | 23 | /** 24 | * Created by domingueza on 03/11/2016. 25 | */ 26 | final case class IvyConfig( 27 | baseDir: File, 28 | resolutionCacheDir: File, 29 | repositoryCacheDir: File, 30 | ivyHome: Option[File] = None, 31 | repositories: List[MavenRepository] = List.empty 32 | ) { 33 | 34 | def createFolders(): Unit = { 35 | val folders = List(baseDir, resolutionCacheDir, repositoryCacheDir) ++ ivyHome 36 | folders.foreach(_.mkdirs()) 37 | } 38 | 39 | } 40 | 41 | object IvyConfig { 42 | 43 | final val DefaultRepositories = Seq( 44 | Repository.mavenCentral, 45 | Repository.mavenLocal 46 | //Repository.sbtLocal("local") 47 | ) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/resolver/ops.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.resolver 18 | 19 | import cats.free.Free 20 | import io.quckoo.ArtifactId 21 | import io.quckoo.reflect.Artifact 22 | 23 | /** 24 | * Created by alonsodomin on 03/05/2017. 25 | */ 26 | object ops extends Resolver[ResolverIO] { 27 | 28 | def validate(artifactId: ArtifactId): ResolverIO[Resolved[ArtifactId]] = 29 | Free.liftF(ResolverOp.Validate(artifactId)) 30 | 31 | def download(artifactId: ArtifactId): ResolverIO[Resolved[Artifact]] = 32 | Free.liftF(ResolverOp.Download(artifactId)) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /shared/src/main/scala/io/quckoo/resolver/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | import cats.Monad 20 | import cats.data.ValidatedNel 21 | import cats.free.Free 22 | 23 | /** 24 | * Created by alonsodomin on 04/05/2017. 25 | */ 26 | package object resolver { 27 | type ResolverIO[A] = Free[ResolverOp, A] 28 | type Resolved[A] = ValidatedNel[DependencyError, A] 29 | 30 | implicit class ResolverIOOps[A](val self: ResolverIO[A]) extends AnyVal { 31 | def to[F[_]: Monad](implicit interpreter: ResolverInterpreter[F]): F[A] = 32 | self.foldMap(interpreter) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /shared/src/test/java/io/quckoo/resolver/DummyJavaJob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.resolver; 18 | 19 | import io.quckoo.Job; 20 | 21 | /** 22 | * Created by aalonsodominguez on 26/07/15. 23 | */ 24 | public class DummyJavaJob implements Job { 25 | 26 | public int value = 0; 27 | 28 | @Override 29 | public Object call() throws Exception { 30 | System.out.println("DummyJavaJob invoked! value=" + value); 31 | return null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /shared/src/test/resources/application.conf: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Antonio Alonso Dominguez 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 | 15 | akka { 16 | logLevel = INFO 17 | } 18 | 19 | quckoo.resolver = { 20 | work-dir = "target/ivy" 21 | } 22 | 23 | kamon { 24 | system-metrics { 25 | sigar-enabled = false 26 | jmx-enabled = false 27 | } 28 | 29 | modules { 30 | kamon-system-metrics.auto-start = no 31 | } 32 | } -------------------------------------------------------------------------------- /shared/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-support/jvm/src/main/scala/io/quckoo/testkit/QuckooActorSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.testkit 18 | 19 | import akka.actor.ActorSystem 20 | import akka.testkit.TestKit 21 | 22 | import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} 23 | 24 | import slogging._ 25 | 26 | /** 27 | * Created by alonsodomin on 17/02/2017. 28 | */ 29 | abstract class QuckooActorSuite(name: String) 30 | extends TestKit(ActorSystem(name)) with WordSpecLike with Matchers with BeforeAndAfterAll { 31 | 32 | override protected def beforeAll(): Unit = { 33 | LoggerConfig.factory = SLF4JLoggerFactory() 34 | LoggerConfig.level = LogLevel.DEBUG 35 | } 36 | 37 | override protected def afterAll(): Unit = 38 | TestKit.shutdownActorSystem(system) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /test-support/shared/src/main/scala/io/quckoo/testkit/ImplicitClock.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.testkit 18 | 19 | import java.time._ 20 | 21 | /** 22 | * Created by domingueza on 27/08/15. 23 | */ 24 | trait ImplicitClock { 25 | 26 | final val FixedInstant = Instant.ofEpochMilli(893273L) 27 | final val ZoneUTC = ZoneId.of("UTC") 28 | 29 | implicit lazy val clock = Clock.fixed(FixedInstant, ZoneUTC) 30 | 31 | def currentDateTime = ZonedDateTime.now(clock) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /util/js/src/main/scala/io/quckoo/md5/MD5_js.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.md5 18 | 19 | import scala.scalajs.js.typedarray._ 20 | 21 | object MD5 { 22 | 23 | // $COVERAGE-OFF$ 24 | def checksum(input: String): String = 25 | SparkMD5.hash(input) 26 | // $COVERAGE-ON$ 27 | 28 | } 29 | -------------------------------------------------------------------------------- /util/js/src/main/scala/io/quckoo/md5/SparkMD5.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.md5 18 | 19 | import scala.scalajs.js 20 | import scala.scalajs.js.annotation._ 21 | 22 | @js.native 23 | @JSGlobal 24 | object SparkMD5 extends js.Object { 25 | 26 | def hash(str: String, raw: Boolean = false): String = js.native 27 | 28 | @js.native 29 | class ArrayBuffer() extends js.Object { 30 | def append(chunk: js.typedarray.ArrayBuffer): Unit = js.native 31 | def end(raw: Boolean = false): String = js.native 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /util/js/src/test/scala/io/quckoo/md5/JsMD5Spec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.md5 18 | 19 | import org.scalatest._ 20 | 21 | class JsMD5Spec extends FlatSpec with Matchers { 22 | 23 | "MD5" should "generate MD5 checksums" in { 24 | val givenInput = "foo" 25 | val expectedChecksum = "acbd18db4cc2f85cedef654fccc4a4d8" 26 | 27 | val returnedChecksum = MD5.checksum(givenInput) 28 | 29 | returnedChecksum shouldBe expectedChecksum 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /util/jvm/src/main/scala/io/quckoo/md5/MD5_jvm.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.md5 18 | 19 | import java.security.MessageDigest 20 | import java.nio.charset.StandardCharsets 21 | 22 | object MD5 { 23 | 24 | // $COVERAGE-OFF$ 25 | def checksum(input: String): String = { 26 | val md = MessageDigest.getInstance("MD5") 27 | md.update(input.getBytes(StandardCharsets.UTF_8)) 28 | 29 | val digest = md.digest() 30 | val builder = new StringBuilder() 31 | digest.foreach { byte => 32 | builder.append(f"${byte & 0xff}%02x") 33 | } 34 | builder.toString 35 | } 36 | // $COVERAGE-ON$ 37 | 38 | } 39 | -------------------------------------------------------------------------------- /util/jvm/src/test/scala/io/quckoo/md5/JvmMD5Spec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.md5 18 | 19 | import org.scalatest._ 20 | 21 | class JvmMD5Spec extends FlatSpec with Matchers { 22 | 23 | "MD5" should "generate MD5 checksums" in { 24 | val givenInput = "foo" 25 | val expectedChecksum = "acbd18db4cc2f85cedef654fccc4a4d8" 26 | 27 | val returnedChecksum = MD5.checksum(givenInput) 28 | 29 | returnedChecksum shouldBe expectedChecksum 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "0.2.0-SNAPSHOT" 2 | -------------------------------------------------------------------------------- /worker/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /worker/src/main/scala/io/quckoo/worker/config/model.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.worker.config 18 | 19 | import akka.actor.ActorPath 20 | import com.typesafe.config.Config 21 | 22 | import io.quckoo.config._ 23 | import io.quckoo.resolver.config.IvyConfig 24 | 25 | import pureconfig._ 26 | 27 | import scala.util.Try 28 | 29 | class ContactPoint(val actorPath: ActorPath) extends AnyVal 30 | 31 | final case class ControllerSettings( 32 | contactPoints: Set[ContactPoint] 33 | ) 34 | 35 | final case class WorkerSettings( 36 | worker: ControllerSettings, 37 | resolver: IvyConfig 38 | ) 39 | 40 | object WorkerSettings { 41 | final val Namespace = "quckoo" 42 | 43 | def apply(config: Config): Try[WorkerSettings] = 44 | Try(loadConfigOrThrow[WorkerSettings](config, Namespace)) 45 | } 46 | -------------------------------------------------------------------------------- /worker/src/main/scala/io/quckoo/worker/core/TaskExecutor.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.worker.core 18 | 19 | import akka.actor.{Actor, ActorLogging} 20 | 21 | import io.quckoo.QuckooError 22 | 23 | /** 24 | * Created by alonsodomin on 16/02/2017. 25 | */ 26 | object TaskExecutor { 27 | 28 | case object Run 29 | sealed trait Response extends Product with Serializable 30 | final case class Failed(error: QuckooError) extends Response 31 | final case class Completed(result: Any) extends Response 32 | 33 | } 34 | 35 | trait TaskExecutor extends Actor with ActorLogging 36 | -------------------------------------------------------------------------------- /worker/src/main/scala/io/quckoo/worker/core/TaskExecutorProvider.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.worker.core 18 | 19 | import akka.actor.{ActorRef, ActorRefFactory} 20 | 21 | import io.quckoo.Task 22 | 23 | /** 24 | * Created by alonsodomin on 16/02/2017. 25 | */ 26 | trait TaskExecutorProvider { 27 | 28 | def executorFor(context: WorkerContext, task: Task)( 29 | implicit actorRefFactory: ActorRefFactory 30 | ): ActorRef 31 | 32 | } 33 | -------------------------------------------------------------------------------- /worker/src/main/scala/io/quckoo/worker/core/WorkerContext.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.worker.core 18 | 19 | import cats.effect.IO 20 | 21 | import io.quckoo.resolver.Resolver 22 | 23 | /** 24 | * Created by alonsodomin on 16/02/2017. 25 | */ 26 | trait WorkerContext { 27 | 28 | implicit def resolver: Resolver[IO] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /worker/src/main/scala/io/quckoo/worker/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo 18 | 19 | /** 20 | * Created by alonsodomin on 04/11/2016. 21 | */ 22 | package object worker { 23 | final val SystemName = "QuckooWorkerSystem" 24 | } 25 | -------------------------------------------------------------------------------- /worker/src/test/resources/application.conf: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Antonio Alonso Dominguez 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 | 15 | quckoo.resolver = { 16 | work-dir = "target/ivy" 17 | } 18 | 19 | akka { 20 | loglevel = "DEBUG" 21 | 22 | actor.provider = "akka.remote.RemoteActorRefProvider" 23 | } 24 | 25 | kamon { 26 | system-metrics { 27 | sigar-enabled = false 28 | jmx-enabled = false 29 | } 30 | 31 | modules { 32 | kamon-system-metrics.auto-start = no 33 | } 34 | } -------------------------------------------------------------------------------- /worker/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /worker/src/test/scala/io/quckoo/worker/config/WorkerSettingsSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 A. Alonso Dominguez 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 io.quckoo.worker.config 18 | 19 | import com.typesafe.config.ConfigFactory 20 | 21 | import org.scalatest.{FlatSpec, Inside, Matchers} 22 | 23 | import scala.util.Success 24 | 25 | /** 26 | * Created by alonsodomin on 04/11/2016. 27 | */ 28 | class WorkerSettingsSpec extends FlatSpec with Matchers with Inside { 29 | 30 | "WorkerSettings" should "load the default configuration settings" in { 31 | val config = ConfigFactory.load() 32 | 33 | val returnedSettings = WorkerSettings(config) 34 | inside(returnedSettings) { 35 | case Success(settings) => 36 | settings.worker.contactPoints should not be empty 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /worker/src/universal/conf/application.conf: -------------------------------------------------------------------------------- 1 | quckoo { 2 | home-dir = "." 3 | home-dir = ${?QUCKOO_HOME} 4 | 5 | resolver { 6 | work-dir = ${quckoo.home-dir}"/resolver" 7 | resolution-cache-dir = ${quckoo.resolver.work-dir}"/cache" 8 | repository-cache-dir = ${quckoo.resolver.work-dir}"/local" 9 | 10 | repositories = [ ] 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /worker/src/universal/conf/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------