• This repository has been archived on 27/Feb/2024
  • Stars
    star
    143
  • Rank 257,007 (Top 6 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created over 9 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Scala based lightweight service framework using zookeeper, gRPC, and other popular technologies.

Wookiee Platform

Build Status Latest Release License

Fastest way to get going with Wookiee check out the Quickstart Guide.

Wookiee is Licensed under the Apache 2.0 License, for more information see LICENSE

Usage

Wookiee is meant to save you from the endless tedium of creating yet another micro service. It provides a common Main class (HarnessService) and tacks on a ton of out of the box conveniences.

So think of Wookiee when you...

  • ...are trying to track down what library you put the eleventh health check implementation of your career in for you to copy paste
  • ...just aren't sure whether you want to use Colossus or Akka Http and you'd like to be able to swap between the two in a few minutes or just run both at once!
  • ...need to get metrics recording in your service and reporting out to Graphite and you want to be able to do it with zero lines of setup code
  • ...have found that interacting with the old school Scala(Java) main() method reminds you too much of being in college and you begin to doubt you've improved at all
  • ...don't have the patience to throw together an artisanal configuration reader for the hundredth time because your cycles are more important, dang it!
  • ...want the new intern to be able to create their own new Services using a really simple template with tons of examples since your company runs all their Services on one framework
  • ...would rather focus on the functionality of your Akka Actors than worrying about linking up health checks, starting everything up, and sending out PoisonPills on shutdown
  • ...have no appetite for creating a new logger variable for every single class you want to hear from
  • ...need to integrate a new technology but find it unsavory to write thirty lines of "hotNewTech.start(config); ...; hotNewTech.whatever(); ...; hotNewTech.close()" in every codebase
  • ...just want to be able to get straight to the fun stuff!

Adding to Pom

Add the jfrog repo to your project first:

<repositories>
    <repository>
        <id>JFrog</id>
        <url>http://oss.jfrog.org/oss-release-local</url>
    </repository>
</repositories>

Add latest version of wookiee, either Scala 2.12 or 2.13 varietals:

<dependency>
    <groupId>com.oracle.infy</groupId>
    <artifactId>wookiee-core_2.12</artifactId>
    <version>${wookiee.version}</version>
</dependency>

What's Included

The Wookiee platform repository contains the core, supporting components and a test library. It is built primarily on Scala and Akka. It contains example projects as well as Maven archetypes for creating various service and creating a component. Wookiee is split into 2 primary components, the Wookiee library and the system components. The Wookiee library is comprised of the of the following components:

  • Command Manager - Adds and Executes commands.
  • Component Manager - Loads up component Jars and managers
  • Service Manager - Loads up user services, this is where the primary business logic for the application would reside
  • Health Provider - provides framework for health in components and services
  • Logging - provides basic logging capability for components and services
  • Util - Utility libraries for common functions in the code.

Command Manager

The command manager is the central actor for routing all execution of commands in our system. A command is simply the primary execution point for specific set of work. For more information see the Commands documentation.

Loading System Components

The Wookiee library loads various components when it starts up. Each component is derived through 1 of 3 methods:

  1. It checks the sub folders found in the root folder defined in the application config under the key "components.component-path". The name of the folder will be the name of the actor that is initialized by the component manager. Each component folder will contain a lib folder with all the jars that the component uses as well as the component jar. A conf file must be located in the component folder for configuration of the component. For specifics around individual components, the configuration file and the expected pattern for the component see Components section in this doc.

  2. It checks for jars in the aforementioned folder under the key "components.component-path". The jars there are expected to be shaded jars that contain all the needed libraries and config for the component in the jar. Any configuration can be overridden in your primary conf file using the config from the reference conf in the jar.

  3. It loads a component from a class based on the configuration that is loaded into the system. This list of components are found in the main configuration under the key "components.lib-components". The value of the key is a list of strings that simply point to the config for the component.

  4. It loads a component automatically based on a key in the config file for that component "dynamic-component". If the key is set to true in the config it will load up the component.*

*Note If a list of components are set under the key "component.lib-components" there would be no components loaded automatically, essentially the last type would be switched off.

Loading Services

Services that are built for Wookiee are also loaded into memory by the core. The exception to this would be if Wookiee is used just as a library or embedded in an application. In this case the service in this context is not really a service but rather an application. In general however, if Wookiee is to be used as a library it would most likely be more beneficial to use the individual system components in search for the specific functionality that your App requires. Services are loaded in a similar fashion to the components, where the services are located in sub folders found in the root folder defined in the application config under the key "services.service-path". The primary difference being that classes are loaded into a separate class loader instead of the root Wookiee class loader. (** note ** not the system class loader)

In most cases services will be loaded as mentioned above, however one can also load the service dynamically which will be described below:

Local Messaging

There is a cluster component which allows for messaging across a cluster. However by default Wookiee will include local messaging. The messaging works identically to how clustered messaging works, and is based on a simple PubSub methodology.

Health

Standardized health checks is provided by the library. The ActorHealth trait will apply default health functionality to any actor that leverages the trait. By default, a developer would only have to insert the following code into their actor class

class ActorClass extends ActorHealth {
	def receive = health orElse {
		case Message => "Do something here"
	}
}

The above code will give the actor basic health functionality, this will do three things:

  • receive messages using the HealthCheck message and return a healthy healthcheck status
  • implement the default getHealth function which defines the health for the actor
  • implement the checkHealth function we will get the health of the current actor using the getHealth function above and then execute the request on the child actors and get the health status for them.

Generally a developer would want to override the getHealth function to give customized health check status for the actor. Example:

	override def getHealth : Future[HealthComponent] = {
		Future {
			Math.random.toInt match {
				case s if s > 50 =>
					HealthComponent(self.path.name, ComponentState.NORMAL, "Random health check is NORMAL")
				case s if s > 10 && s <= 50 =>
					HealthComponent(self.path.name, ComponentState.DEGRADED, "Random health check is DEGRADED")
				case s if s <= 10 =>
					HealthComponent(self.path.name, ComponentState.CRITICAL, "Random health check is CRITICAL")
			}
		}
	}

This code will create a random health check result based on the value of the random int. As shown the ComponentState can be either NORMAL, DEGRADED or CRITICAL. Lastly if needed a developer can override the checkHealth function that will handle the message, which will by default use getHealth to get the health of the current actor and then traverse the children to get their health, however if there is a requirement to modify this behavior you can simply override it.

Configuration Watching

The file specified in config.file will actually be watched for any changes to it and a message will be sent to all HActors (message: ConfigChange()). To hook into this most easily, extend the ConfigHelper class like so:

import com.oracle.infy.wookiee.config.ConfigHelper
import com.oracle.infy.wookiee.app.HActor

class ConfigWatchingActor extends HActor with ConfigHelper {
    override def renewConfiguration() {
        super.renewConfiguration()
        renewableConfig // Do something with your updated config object
    }
}

Logging

Standardized logging is provided by the library. This can be applied to any actor using the trait ActorLoggingAdapter. This will give you the "log" variable which will allow you to write info, debug, warn, error and trace messages to the log. If you need to add logging to a non-actor based class, possibly like an object you can use the following code.

	val externalLogger = LoggerFactory.getLogger(this.getClass)

Wookiee can be used as both a library and a service. To use it as a service a developer would be required to simply execute the HarnessService app, for use as a library the developer would be required to add a dependency in the project's pom and then initialize Wookiee manually. Alternatively the developer could add a dependency for a single component to the POM and use it separately. For more information on leveraging a single component see the doc specific to that component.

Releases

How To

There are several aspects to utilizing the functionality contained with Wookiee and it's supporting libraries. This section outlines the available functionality and how to best utilize the Wookiee Platform.

Development Environment

The purpose of this section is to aggregate notes and processes in setting up development environment for creating services for Wookiee.

Instructions

Increasing Artifact Version

To bump the version of Wookiee Core/Test simply increase it in the pom file. If you are building a branch then it will automatically insert the branch name before SNAPSHOT. So for example if the pom has 2.0-SNAPSHOT as a version the final artifact will end up as 2.0-$branch-SNAPSHOT. If you create a tagged release in github, or if you change the pom to a version that doesn't contain "SNAPSHOT" then the final artifact version will be literally what was in the tag/pom.

Creating a service

As services are what provides functionality to the Wookiee container, this section provides information on how to create a basic service.

Instructions

Creating a component

Components provide pluggable core functionality in to Wookiee. This allows developers to pick and choose the kind of functionality that they want.

Instructions

Components

A component is dynamically loaded in Wookiee. This allows for a developer to then only load the components that they wish to use as part of the Wookiee Platform. A component is defined by a class object with the Component trait found in the wookiee-core project. Wookiee will start up any component that is found in location that is defined by the component-path key in the harness configuration file.

wookiee-system {
  # This is the path to the location of the components (defaults to "components")
  # Should just contain the jar for the component
  component-path = "components"
  ...
}
  1. Akka Http Component
  2. Memcache Component
  3. Cache Component
  4. Cluster Component
  5. Colossus Component
  6. ETCD Component
  7. JSON Component
  8. Kafka Component
  9. Metrics Component
  10. Netty Component
  11. Socko Component
  12. Spray Component
  13. Zookeeper Component

Configuring a component

Each component loaded in Wookiee should provide a default configuration that will fit most situations. The Wookiee Platform uses Typesafe Config to load configurations at runtime in layers. A component's default configuration should be given the lowest priority, the reference conf, following the layered priority schema set by Typesafe Config. This can be problematic at times, as third party libs and components with equally prioritized, overlapping configurations are combined in the application. To ensure component configurations take precedence, place components jars at the beginning of the classpath. One approach is to separate components from third party libs in the distribution.

Maven dist.xml

<assembly>
    <id>bin</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>tar.gz</format>
    </formats>
    <files>
        <file>
            <source>${project.build.directory}/${project.build.finalName}.jar</source>
        </file>
    </files>
    <dependencySets>
        <dependencySet>
            <useProjectArtifact>false</useProjectArtifact>
            <outputDirectory>/lib/thirdparty</outputDirectory>
            <scope>runtime</scope>
            <excludes>
                <exclude>*:wookiee*:jar</exclude>
            </excludes>
        </dependencySet>
        <dependencySet>
            <useProjectArtifact>false</useProjectArtifact>
            <outputDirectory>/lib/components</outputDirectory>
            <scope>runtime</scope>
            <includes>
                <include>*:wookiee*:jar</include>
            </includes>
        </dependencySet>
    </dependencySets>
</assembly>

Run command:

java -cp *:lib/components/*:lib/thirdparty/* com.oracle.infy.wookiee.app.HarnessService

wookiee-grpc

Installation

wookiee-grpc is available for Scala 2.12 and 2.13. There are no plans to support scala 2.11 or lower.

libraryDependencies += "com.oracle.infy" %% "wookiee-grpc" % "2.2.8"

Setup ScalaPB

We use ScalaPB to generate source code from a .proto file. You can use other plugins/code generators if you wish. wookiee-grpc will work as long as you have io.grpc.ServerServiceDefinition for the server and something that accept io.grpc.ManagedChannel for the client.

Declare your gRPC service using proto3 syntax and save it in src/main/protobuf/myService.proto

syntax = "proto3";

package com.oracle.infy.wookiee;

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string resp = 1;
}

service MyService {
  rpc greet(HelloRequest) returns (HelloResponse) {}
}

Add ScalaPB plugin to plugin.sbt file

addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.6")
libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.11.8"

Configure the project in build.sbt so that ScalaPB can generate code

    Compile / PB.targets := Seq(
      scalapb.gen() -> (Compile / sourceManaged).value / "scalapb"
    ),
    libraryDependencies ++= Seq(
      "io.grpc" % "grpc-netty" % scalapb.compiler.Version.grpcJavaVersion,
      "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion
    )
  )

In the sbt shell, type protocGenerate to generate scala code based on the .proto file. ScalaPB will generate code and put it under target/scala-2.13/src_managed/main.

Using wookiee-grpc

After the code has been generated by ScalaPB, you can use wookiee-grpc for service discoverability and load balancing.

wookiee-grpc is written using functional concepts. One key concept is side-effect management/referential transparency. We use cats-effect (https://typelevel.org/cats-effect/) internally. If you want to use cats-effect, you can use the methods that return IO[_]. Otherwise, use the methods prefixed with unsafe. When using unsafe methods, you are expected to handle any exceptions

Imports

Add the following imports:

import com.oracle.infy.wookiee.grpc.model.{Host, HostMetadata}
import com.oracle.infy.wookiee.grpc.settings._
import com.oracle.infy.wookiee.grpc._
import com.oracle.infy.wookiee.grpc.model.LoadBalancers._
import io.grpc._

Creating a Server

    val serverSettingsF: ServerSettings = ServerSettings(
      discoveryPath = zookeeperDiscoveryPath,
      serverServiceDefinition = ssd,
      // This is an optional arg. wookiee-grpc will try to resolve the address automatically.
      // If you are running this locally, its better to explicitly set the hostname
      host = Host(0, "localhost", 9091, HostMetadata(0, quarantined = false)),
      authSettings = None,
      sslServerSettings = None,
      bossExecutionContext = mainEC,
      workerExecutionContext = mainEC,
      applicationExecutionContext = mainEC,
      bossThreads = bossThreads,
      workerThreads = mainECParallelism,
      curatorFramework = curator
    )

    val serverF: Future[WookieeGrpcServer] = WookieeGrpcServer.start(serverSettingsF).unsafeToFuture()

Creating a Client Channel

    val wookieeGrpcChannel: WookieeGrpcChannel = WookieeGrpcChannel
      .of(
        ChannelSettings(
          serviceDiscoveryPath = zookeeperDiscoveryPath,
          eventLoopGroupExecutionContext = blockingEC,
          channelExecutionContext = mainEC,
          offloadExecutionContext = blockingEC,
          eventLoopGroupExecutionContextThreads = bossThreads,
//           Load Balancing Policy
//             One of:
//               RoundRobinPolicy
//               RoundRobinWeightedPolicy
//               RoundRobinHashedPolicy
          lbPolicy = RoundRobinPolicy,
          curatorFramework = curator,
          sslClientSettings = None,
          clientAuthSettings = None
        )
      )
      .unsafeRunSync()

    val stub: MyServiceGrpc.MyServiceStub = MyServiceGrpc.stub(wookieeGrpcChannel.managedChannel)

Executing a gRPC Call

    val gRPCResponseF: Future[HelloResponse] = for {
      server <- serverF
      resp <- stub
        .withInterceptors(new ClientInterceptor {
          override def interceptCall[ReqT, RespT](
              method: MethodDescriptor[ReqT, RespT],
              callOptions: CallOptions,
              next: Channel
          ): ClientCall[ReqT, RespT] = {
            next.newCall(
              method,
              // Set the WookieeGrpcChannel.hashKeyCallOption when using RoundRobinHashedPolicy
              callOptions.withOption(WookieeGrpcChannel.hashKeyCallOption, "Some hash")
            )
          }
        })
        .greet(HelloRequest("world!"))
      _ <- wookieeGrpcChannel.shutdown().unsafeToFuture()
      _ <- server.shutdown().unsafeToFuture()
    } yield resp

    println(Await.result(gRPCResponseF, Duration.Inf))
    curator.close()
    zkFake.close()
    ()

###Setting up load balancing methods in channel settings

There are three load balancing policies that ship with wookiee-grpc. The load balancing policies are set up within the gRPC Channel Settings.

  • Round Robin

    A simple round robin policy that alternates between hosts as calls are executed. It's fairly simplistic.

  • Round Robin Weighted

    This load balancer takes server load into consideration and distributes calls to the server with the lowest current usage. If all loads are equivalent, it defaults to simple Round Robin behavior.

  • Round Robin Hashed

    Provides "stickiness" for the gRPC host. If you want a particular host to serve the request for all the calls with a particular key, you can use this policy. For example, if you want a single server to service all requests that use the key "foo", you can set the WookieeGrpcChannel.hashKeyCallOption on every call. This will ensure that all gRPC calls using the same hash will be executed on the same server.

    val gRPCResponseF: Future[HelloResponse] = for {
      server <- serverF
      resp <- stub
        .withInterceptors(new ClientInterceptor {
          override def interceptCall[ReqT, RespT](
              method: MethodDescriptor[ReqT, RespT],
              callOptions: CallOptions,
              next: Channel
          ): ClientCall[ReqT, RespT] = {
            next.newCall(
              method,
              // Set the WookieeGrpcChannel.hashKeyCallOption when using RoundRobinHashedPolicy
              callOptions.withOption(WookieeGrpcChannel.hashKeyCallOption, "Some hash")
            )
          }
        })
        .greet(HelloRequest("world!"))
      _ <- wookieeGrpcChannel.shutdown().unsafeToFuture()
      _ <- server.shutdown().unsafeToFuture()
    } yield resp

    println(Await.result(gRPCResponseF, Duration.Inf))
    curator.close()
    zkFake.close()
    ()

Putting it all together

Here is an example of a complete gRPC solution

import java.lang.Thread.UncaughtExceptionHandler
import java.util.concurrent.{Executors, ForkJoinPool, ThreadFactory}
import cats.effect.{Blocker, ContextShift, IO, Timer}
//wookiee-grpc imports
import com.oracle.infy.wookiee.grpc.model.{Host, HostMetadata}
import com.oracle.infy.wookiee.grpc.settings._
import com.oracle.infy.wookiee.grpc._
import com.oracle.infy.wookiee.grpc.model.LoadBalancers._
import io.grpc._
//wookiee-grpc imports
import org.typelevel.log4cats.Logger
// This is from ScalaPB generated code
import com.oracle.infy.wookiee.myService.MyServiceGrpc.MyService
import com.oracle.infy.wookiee.myService.{HelloRequest, HelloResponse, MyServiceGrpc}
import org.typelevel.log4cats.slf4j.Slf4jLogger
import io.grpc.ServerServiceDefinition
import org.apache.curator.test.TestingServer

import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

object Example {

  def main(args: Array[String]): Unit = {
    val bossThreads = 10
    val mainECParallelism = 10

    // wookiee-grpc is written using functional concepts. One key concept is side-effect management/referential transparency
    // We use cats-effect (https://typelevel.org/cats-effect/) internally.
    // If you want to use cats-effect, you can use the methods that return IO[_]. Otherwise, use the methods prefixed with `unsafe`.
    // When using `unsafe` methods, you are expected to handle any exceptions

    val uncaughtExceptionHandler = new UncaughtExceptionHandler {
      override def uncaughtException(t: Thread, e: Throwable): Unit = {
        System.err.println("Got an uncaught exception on thread " ++ t.getName ++ " " ++ e.toString)
      }
    }

    val tf = new ThreadFactory {
      override def newThread(r: Runnable): Thread = {
        val t = new Thread(r)
        t.setName("blocking-" ++ t.getId.toString)
        t.setUncaughtExceptionHandler(uncaughtExceptionHandler)
        t.setDaemon(true)
        t
      }
    }

    // The blocking execution context must create daemon threads if you want your app to shutdown
    val blockingEC = ExecutionContext.fromExecutorService(Executors.newCachedThreadPool(tf))
    // This is the execution context used to execute your application specific code
    implicit val mainEC: ExecutionContext = ExecutionContext.fromExecutor(
      new ForkJoinPool(
        mainECParallelism,
        ForkJoinPool.defaultForkJoinWorkerThreadFactory,
        uncaughtExceptionHandler,
        true
      )
    )

    // Use a separate execution context for the timer
    val timerEC = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())

    implicit val cs: ContextShift[IO] = IO.contextShift(mainEC)
    implicit val blocker: Blocker = Blocker.liftExecutionContext(blockingEC)
    implicit val timer: Timer[IO] = IO.timer(timerEC)
    implicit val logger: Logger[IO] = Slf4jLogger.create[IO].unsafeRunSync()

    val zookeeperDiscoveryPath = "/discovery"

    // This is just to demo, use an actual Zookeeper quorum.
    val zkFake = new TestingServer()
    val connStr = zkFake.getConnectString

    val curator = WookieeGrpcUtils.createCurator(connStr, 5.seconds, blockingEC).unsafeRunSync()
    curator.start()

    val ssd: ServerServiceDefinition = MyService.bindService(
      (request: HelloRequest) => {
        println("received request")
        Future.successful(HelloResponse("Hello " ++ request.name))
      },
      mainEC
    )

    //Creating a Server
    val serverSettingsF: ServerSettings = ServerSettings(
      discoveryPath = zookeeperDiscoveryPath,
      serverServiceDefinition = ssd,
      // This is an optional arg. wookiee-grpc will try to resolve the address automatically.
      // If you are running this locally, its better to explicitly set the hostname
      host = Host(0, "localhost", 9091, HostMetadata(0, quarantined = false)),
      authSettings = None,
      sslServerSettings = None,
      bossExecutionContext = mainEC,
      workerExecutionContext = mainEC,
      applicationExecutionContext = mainEC,
      bossThreads = bossThreads,
      workerThreads = mainECParallelism,
      curatorFramework = curator
    )

    val serverF: Future[WookieeGrpcServer] = WookieeGrpcServer.start(serverSettingsF).unsafeToFuture()
    //Creating a Server

    //channelSettings
    val wookieeGrpcChannel: WookieeGrpcChannel = WookieeGrpcChannel
      .of(
        ChannelSettings(
          serviceDiscoveryPath = zookeeperDiscoveryPath,
          eventLoopGroupExecutionContext = blockingEC,
          channelExecutionContext = mainEC,
          offloadExecutionContext = blockingEC,
          eventLoopGroupExecutionContextThreads = bossThreads,
//           Load Balancing Policy
//             One of:
//               RoundRobinPolicy
//               RoundRobinWeightedPolicy
//               RoundRobinHashedPolicy
          lbPolicy = RoundRobinPolicy,
          curatorFramework = curator,
          sslClientSettings = None,
          clientAuthSettings = None
        )
      )
      .unsafeRunSync()

    val stub: MyServiceGrpc.MyServiceStub = MyServiceGrpc.stub(wookieeGrpcChannel.managedChannel)
    //channelSettings

    //grpcCall
    val gRPCResponseF: Future[HelloResponse] = for {
      server <- serverF
      resp <- stub
        .withInterceptors(new ClientInterceptor {
          override def interceptCall[ReqT, RespT](
              method: MethodDescriptor[ReqT, RespT],
              callOptions: CallOptions,
              next: Channel
          ): ClientCall[ReqT, RespT] = {
            next.newCall(
              method,
              // Set the WookieeGrpcChannel.hashKeyCallOption when using RoundRobinHashedPolicy
              callOptions.withOption(WookieeGrpcChannel.hashKeyCallOption, "Some hash")
            )
          }
        })
        .greet(HelloRequest("world!"))
      _ <- wookieeGrpcChannel.shutdown().unsafeToFuture()
      _ <- server.shutdown().unsafeToFuture()
    } yield resp

    println(Await.result(gRPCResponseF, Duration.Inf))
    curator.close()
    zkFake.close()
    ()
    //grpcCall
  }
}

Example.main(Array.empty[String])
// received request
// HelloResponse(Hello world!,UnknownFieldSet(Map()))

Contributing

This project is not accepting external contributions at this time. For bugs or enhancement requests, please file a GitHub issue unless it’s security related. When filing a bug remember that the better written the bug is, the more likely it is to be fixed. If you think you’ve found a security vulnerability, do not raise a GitHub issue and follow the instructions in our security policy.

Security

Please consult the security guide for our responsible security vulnerability disclosure process

License

Copyright (c) 2004, 2023 Oracle and/or its affiliates. Released under the Apache License Version 2.0

More Repositories

1

graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
Java
20,237
star
2

docker-images

Official source of container configurations, images, and examples for Oracle products and projects
Shell
6,160
star
3

opengrok

OpenGrok is a fast and usable source code search and cross reference engine, written in Java
Java
3,971
star
4

truffleruby

A high performance implementation of the Ruby programming language, built on GraalVM.
Ruby
3,018
star
5

helidon

Java libraries for writing microservices
Java
2,596
star
6

visualvm

VisualVM is an All-in-One Java Troubleshooting Tool
Java
2,563
star
7

node-oracledb

Oracle Database driver for Node.js maintained by Oracle Corp.
JavaScript
2,174
star
8

graaljs

A ECMAScript 2022 compliant JavaScript implementation built on GraalVM. With polyglot language interoperability support. Running Node.js applications!
C++
1,418
star
9

tribuo

Tribuo - A Java machine learning library
Java
1,211
star
10

railcar

RailCar: Rust implementation of the Open Containers Initiative oci-runtime
Rust
1,115
star
11

oracle-db-examples

Examples of applications and tool usage for Oracle Database
Java
958
star
12

graalpython

A Python 3 implementation built on GraalVM
Python
957
star
13

mysql-operator

Create, operate and scale self-healing MySQL clusters in Kubernetes
Go
868
star
14

python-cx_Oracle

Python interface to Oracle Database now superseded by python-oracledb
C
861
star
15

vagrant-projects

Vagrant projects for Oracle products and other examples
Shell
840
star
16

graphpipe

Machine Learning Model Deployment Made Simple
Makefile
725
star
17

terraform-provider-oci

Terraform Oracle Cloud Infrastructure provider
Go
622
star
18

bpftune

bpftune uses BPF to auto-tune Linux systems
C
615
star
19

smith

Smith: A microcontainer builder
Go
602
star
20

fastr

A high-performance implementation of the R programming language, built on GraalVM.
Java
598
star
21

oraclejet

Oracle JET is a modular JavaScript Extension Toolkit for developers working on client-side applications.
479
star
22

db-sample-schemas

Oracle Database Sample Schemas
PLSQL
435
star
23

coherence

Oracle Coherence Community Edition
Java
408
star
24

dotnet-db-samples

.NET code samples for Oracle database developers #OracleDotNet
C#
381
star
25

apex

Official Oracle APEX repo for sample code, starter apps, plug-ins, and more! #orclapex
354
star
26

graalvm-reachability-metadata

Repository which contains community-driven collection of GraalVM reachability metadata for open-source libraries.
Java
352
star
27

oci-cli

Command Line Interface for Oracle Cloud Infrastructure
Python
343
star
28

centos2ol

Script and documentation to switch CentOS/Rocky Linux to Oracle Linux
Shell
330
star
29

oci-python-sdk

Oracle Cloud Infrastructure SDK for Python
Python
303
star
30

crashcart

CrashCart: sideload binaries into a running container
Rust
275
star
31

oracle-db-tools

This project is a repository of sample code that will demonstrate various concepts to assist developers in building applications around Oracle Database technologies. SDKs and scripts will be available to integrate with SQL Developer, Data Modeler, Oracle REST Data Services and DBaaS.
JavaScript
274
star
32

python-oracledb

Python driver for Oracle Database conforming to the Python DB API 2.0 specification. This is the renamed, new major release of cx_Oracle
Python
256
star
33

oci-designer-toolkit

OCI designer toolKIT (OKIT) is a set of tools for enabling design, deploy and visualise OCI environments through a graphical web based interface.
JavaScript
254
star
34

linux-uek

Oracle Linux UEK: Unbreakable Enterprise Kernel
253
star
35

odpi

ODPI-C: Oracle Database Programming Interface for Drivers and Applications
C
235
star
36

weblogic-kubernetes-operator

WebLogic Kubernetes Operator
Java
225
star
37

netsuite-suitecloud-sdk

SuiteCloud Software Development Kit (SuiteCloud SDK) are the set of tools that allow you to customize accounts and create SuiteApps through SuiteCloud Development Framework (SDF).
JavaScript
184
star
38

oracle-r2dbc

R2DBC Driver for Oracle Database
Java
183
star
39

javavscode

Java platform support for Visual Studio Code for full featured Java development (edit-compile-debug & test cycle)
TypeScript
179
star
40

terraform-kubernetes-installer

Terraform Installer for Kubernetes on Oracle Cloud Infrastructure
HCL
178
star
41

oci-java-sdk

Oracle Cloud Infrastructure SDK for Java
Java
163
star
42

pgql-lang

PGQL is an SQL-based query language for property graphs
Java
158
star
43

speedle

Speedle is an open source project for access control.
Go
156
star
44

oci-ansible-collection

Oracle Cloud Infrastructure Ansible Collection provides an easy way to provision and manage resources in Oracle Cloud using Ansible.
Python
152
star
45

oci-go-sdk

Go SDK for Oracle Cloud Infrastructure
Go
150
star
46

cordova-plugin-wkwebview-file-xhr

Cordova Plugin for WebView File XHR
JavaScript
140
star
47

weblogic-deploy-tooling

WebLogic Deploy Tooling
Python
140
star
48

solaris-userland

Open Source software in Solaris using gmake based build system to drive building various software components.
C
137
star
49

macaron

Macaron is an extensible supply-chain security analysis framework from Oracle Labs that supports a wide range of build systems and CI/CD services. It can be used to prevent supply chain attacks, detect malicious Python packages, or check conformance to frameworks, such as SLSA. Documentation:
Python
134
star
50

sd4j

Stable diffusion pipeline in Java using ONNX Runtime
Java
131
star
51

analytical-sql-examples

NO LONGER MAINTAINED. Code samples for Oracle's analytical SQL features
PLSQL
127
star
52

container-images

Oracle Linux container images
124
star
53

oracle-database-operator

The Oracle Database Operator for Kubernetes (a.k.a. OraOperator) helps developers, DBAs, DevOps and GitOps teams reduce the time and complexity of deploying and managing Oracle Databases. It eliminates the dependency on a human operator or administrator for the majority of database operations.
Go
120
star
54

oracle-linux

Scripts, examples, and tutorials to get started with Oracle Linux
Shell
115
star
55

kernel-fuzzing

Fuzzers for the Linux kernel
Hack
109
star
56

oci-cloud-controller-manager

Kubernetes Cloud Controller Manager implementation for Oracle Cloud Infrastucture
Go
109
star
57

oci-ansible-modules

DEPRECATED - Please migrate to the new OCI Ansible collection (https://github.com/oracle/oci-ansible-collection).
Python
106
star
58

cloud-native-devops-workshop

Oracle's Cloud Native and DevOps Workshop on Oracle Cloud
JavaScript
106
star
59

weblogic-monitoring-exporter

WebLogic Monitoring Exporter exposes metrics and monitoring data through REST APIs for consumption by other tools (e.g. Prometheus)
Java
105
star
60

macest

Model Agnostic Confidence Estimator (MACEST) - A Python library for calibrating Machine Learning models' confidence scores
Jupyter Notebook
99
star
61

hospitality-api-docs

This repository stores REST API specifications and accompanying Postman collections for Oracle Hospitality APIs.
HTML
99
star
62

cloudtestdrive

HTML
95
star
63

font-apex

Font APEX is an open source icon library from the Oracle APEX team.
CSS
93
star
64

coherence-operator

Oracle Coherence Operator
Go
93
star
65

ktf

Kernel Test Framework - a unit test framework for the Linux kernel
Shell
88
star
66

kubernetes-vault-kms-plugin

Go
74
star
67

dtrace-utils

DTrace-utils contains the DTrace port to Linux
C
74
star
68

oci-grafana-metrics

Grafana datasource plugin for OCI metrics
Go
71
star
69

hiq

HiQ - Observability And Optimization In Modern AI Era
Python
68
star
70

accelerated-data-science

ADS is the Oracle Data Science Cloud Service's python SDK supporting, model ops (train/eval/deploy), along with running workloads on Jobs and Pipeline resources.
Python
67
star
71

graphpipe-go

GraphPipe for go
Go
66
star
72

soda-for-java

SODA (Simple Oracle Document Access) for Java is an Oracle library for writing Java apps that work with JSON (and not only JSON!) in the Oracle Database. SODA allows your Java app to use the Oracle Database as a NoSQL document store.
Java
65
star
73

oci-typescript-sdk

Oracle Cloud Infrastructure SDK for TypeScript and JavaScript
TypeScript
64
star
74

oracle-functions-samples

Examples demonstrating how to use Oracle Functions
61
star
75

yo

A fast and simple command line OCI client
Python
60
star
76

solaris-ips

Solaris IPS: Image Packaging System
Python
57
star
77

weblogic-image-tool

WebLogic Image Tool
Java
57
star
78

nvm-direct

A C library to support applications that map Non-Volatile Memory into their address space for load/store access.
C
56
star
79

microservices-datadriven

Sample code of application examples to build microservices with converged Oracle database and multi-cloud / hybrid cloud services
CSS
56
star
80

bots-node-sdk

Oracle Bots Node.js SDK
TypeScript
51
star
81

db-appdev-vm

Database Application Development Virtual Machine
Shell
50
star
82

souffle

DEPRECATED. Soufflé is a translator of declarative Datalog programs into the C++ language.
C++
49
star
83

xml-sample-demo

Oracle Database XMLDB Code samples
VBScript
48
star
84

oci-service-broker

Oracle Cloud Infrastructure Service Broker is an open source implementation of Open service broker API Spec for OCI services. Customers can use this implementation to install Open Service Broker in Oracle Container Engine for Kubernetes or in other Kubernetes clusters.
Java
48
star
85

free

Free Oracle technologies for Developers
HTML
47
star
86

oraclesolaris-contrib

oraclesolaris-contrib is a repository focussed on the Oracle Solaris 11.4 StatsStore, using methodologies like REST to connect to Oracle Solaris 11.4 and the new features being introduced in Oracle Solaris 11.4 OS.
Jupyter Notebook
46
star
87

oci-utils

Oracle Cloud Infrastructure utilities
Python
45
star
88

content-and-experience-toolkit

The Oracle Content Management Toolkit and SDKs help you develop custom applications that consume content that is managed in the OCM repository. These applications can be developed in the Content Management Cloud or using 3rd party tools.
JavaScript
45
star
89

navarkos

Enables a Kubernetes federation to automatically manage multi-cluster infrastructure
Go
44
star
90

nosql-examples

This is a top level repository for code examples related to the use of Oracle NoSQL Database.
HTML
44
star
91

rwloadsim

RWP*Load Simulator - your tool for scripting, simulation and much more. Like having a bit of bash and SQL, a nip of C or Java, a dash of awk, a grain of sed plus drops of secret sauce in one single tool. See https://blogs.oracle.com/database/rwploadsim-oracle-db-performance-simluator for the announcement on the Oracle database blog.
C
44
star
92

fmw-chef-cookbook

Official repository of samples that show how to use Chef to provision Oracle Fusion Middleware (FMW) products.
Ruby
43
star
93

oci-dotnet-sdk

Oracle Cloud Infrastructure SDK for .NET
C#
43
star
94

graphpipe-py

GraphPipe for python
Python
42
star
95

terraform-examples

Terraform Examples for Oracle Cloud Infrastructure and Platfrom
41
star
96

heatwave-tpch

SQL scripts for HeatWave benchmarking
41
star
97

oci-data-science-ai-samples

This repo contains a series of tutorials and code examples highlighting different features of the OCI Data Science and AI services, along with a release vehicle for experimental programs.
Jupyter Notebook
41
star
98

oracle-db-appdev-monitoring

Metrics exporter and samples for unified observability for data-centric app dev and microservices
Go
41
star
99

dbt-oracle

dbt (data build tool) adapter for Oracle Autonomous Database
Python
40
star
100

offline-persistence-toolkit

Offline Persistence Toolkit for Javascript Applications
JavaScript
40
star