Coder Social home page Coder Social logo

line / centraldogma Goto Github PK

View Code? Open in Web Editor NEW
576.0 32.0 114.0 91.29 MB

Highly-available version-controlled service configuration repository based on Git, ZooKeeper and HTTP/2

Home Page: https://line.github.io/centraldogma/

License: Apache License 2.0

Java 92.35% Thrift 0.41% CSS 0.78% JavaScript 4.20% HTML 1.73% Python 0.27% TypeScript 0.25% Shell 0.01%
service-configuration configuration-management version-control vcs repository git zookeeper configuration configuration-server config

centraldogma's People

Contributors

amaembo avatar arhont375 avatar armerian avatar baont avatar dependabot[bot] avatar geminikim avatar github-actions[bot] avatar hokkun-dayo avatar huydx avatar hyangtack avatar ikhoon avatar imasahiro avatar inch772 avatar jaesungchris avatar jmostella avatar jrhee17 avatar karbonitekream avatar kcvlex avatar liying2010 avatar lujiefsi avatar mauhiz avatar minwoox avatar mono0x avatar runivn avatar syleeeee avatar taiga-nada avatar thachlp avatar theweaver avatar trustin avatar yyuunn0044 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

centraldogma's Issues

Retry idempotent operations automatically

There are various situations where an operation can fail:

  • A read operation may fail when a client attempts to access the revision in a replica with replication delay. In this case, the failure can be easily recovered by retrying after a small delay.
  • A replica may go offline due to some reason (e.g. machine dead, process killed, ...) and thus an operation may fail unexpectedly. If the operation is a read operation, we can just retry against another replica.

Currently, the client library exposes the situations mentioned above to our users as they are, forcing them to implement the recovery and retry logic by themselves. centraldogma-client should take care of them so that they don't have to.

We may also want to insert an artificial delay into watchRepository() or watchFile() operation so that the successive read operations have less chance of getting RevisionNotFoundException, as well as implementing the forementioned automatic retry mechanism.

Remove Thrift support in favor of RESTful API

.. because:

  • libthrift isn't stable enough yet, e.g. 0.10.0 introduced breaking changes since 0.9.x. We do not want to ship two client library JARs - one for Thrift 0.9 and the other for 0.10.0.
  • A client library can have fewer dependencies, especially without libthrift and Armeria.

To make this come true, we need to:

  • #64 Revise our RESTful API & implementation so that it covers all features provided by the current Thrift service.
  • Rewrite the client library so it uses the RESTful API.

UI for reverting to an old revision

In an emergency situation, a user may want to revert a repository into a certain revision, which is basically pushing a revert commit. There's currently no simple and quick way to do that; a user has to set up Git-to-CD sync, to send a PR with a revert commit and to merge it. It would be done much quicker in emergency if CD web UI has a dedicated UI.

UnavailableSecurityManagerException during authentication

Although only logged at DEBUG level, it's always better avoid this sort of failure because exception instantiation is expensive.

Looking from the exception messages, this can be fixed by one of the following:

  • setting the SecurityManager in a subject context or
  • binding and unbinding the SecurityManager to/from the thread local context using ThreadLocalContext.bind(SecurityManager) and ThreadLocalContext.unbindSecurityManager(). (not preferred, because thread local variable is involved)
21:38:35.949 [armeria-common-blocking-tasks-3-1] DEBUG org.apache.shiro.subject.support.DefaultSubjectContext - No SecurityManager available in subject context map.  Falling back to SecurityUtils.getSecurityManager() lookup.
21:38:35.950 [armeria-common-blocking-tasks-3-1] DEBUG org.apache.shiro.subject.support.DefaultSubjectContext - No SecurityManager available via SecurityUtils.  Heuristics exhausted.
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
	at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
	at org.apache.shiro.subject.support.DefaultSubjectContext.resolveSecurityManager(DefaultSubjectContext.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.ensureSecurityManager(DefaultSecurityManager.java:411)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:333)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:183)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:283)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256)
	at com.linecorp.centraldogma.server.internal.admin.authentication.LoginService.lambda$null$0(LoginService.java:69)
	at com.linecorp.armeria.common.AbstractRequestContext.lambda$makeContextAware$1(AbstractRequestContext.java:72)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.lang.Thread.run(Thread.java:748)

/cc @hyangtack

Compact a client-provided commit before storing to ZooKeeper

ZooKeeperCommandExecutor currently serializes a PushCommand as-is. This can cause unexpectedly large log entry to be stored in ZooKeeper, which has limited capacity. We should:

  • Calculate the diff between the changeset provided in a PushCommand and the HEAD,
  • Perform `Repository.commit() with the calculated diff and
  • Store the calculated diff into ZooKeeper.

Such an optimization could reduce the size of a serialized log entry dramatically when a user issues multiple UPSERTs on existing files.

CD-to-CD mirroring

We currently support only Git-to-CD mirroring. Having CD-to-CD mirroring will allow us run satelite replicas which are mirrored from another CD cluster in a different data center.

Automated replica setup and recovery

Currently, there's no automated way to set up a new replica or to replace a broken replica. A user has to perform rsync from an existing healthy replica's data directory using command-line interface, which is obviously error-prone.

We should implement internal remote API:

  • restricted to inter-replica communication
  • dedicated to replica setup and recovery

.. so that configuring a new replica is as simple as running a single command. For example:

$ cd centraldogma/bin
$ ./setup-replica 192.168.0.100:36462 # the IP address and port of an existing healthy replica
... retrieves conf/* and lib/ext/* ...
... generates UUID and writes to conf/dogma.json ...
... retrieves all repository data ...
$ ./startup
... a new replica joins the cluster ...

In case of recovery, you could simply wipe out the existing data and conf directory and run setup-replica.

Add working copy support to command line client

Like git clone so that a user can:

  • Retrieve the content of a CD repository into a file system, so that he or she can feed it into other third party components such as a shell script.
  • Push a commit that contains multiple changes.

Support binary files

Some customers want to store binary files in CD. I think it's fine as long as it's not too large.

Related issue: #35 because binary files tend to be larger than our typical text files.

Remove noises from gradle build output

There are so many noises from gradle build output that are emitted from assertThatThrownBy(....);
We need to remove those expected noises so a user can focus on real problems.

CentralDogmaSessionDAO inefficiency

On each login or logout, Shiro SecurityManager ends up creating four commits into our session repository, which can increase the number of commits in the session repository very quickly. Quick investigation of login process shows that:

  • Subject.Builder.buildSubject() generates three commits
    1. Initialization commit by createSession(context) in AbstractNativeSessionManager.start(context)
    2. Redundant commit of (1) by applyGlobalSessionTimeout(session) in AbstractNativeSessionManager.start(context).
    3. Updating the current principal
  • Subject.login() generates two more comments:
    1. Updating the current principal again, because currentPrincipals.equals(existingPrincipals) returns false at DefaultSubjectDao.java:218 due to mismatching realm name.
      • It seems like we don't need to specify a principal when creating a Subject at all. Removing the Subject.Builder.principal() call, which was specified right before buildSubject(), gets rid of the third commit in buildSubject().
    2. Updating the boolean flag that tells if the session is authenticated or not.

I expect something similar occurs for logout, making a commit for each attribute updates before the session removal, which is totally inefficient.

Give this observation, it seems like Shiro has no notion of 'transaction' or 'delayed update' to reduce the number of SessionDao.update() or SessionDao.create() calls, leading CentralDogmaSessionDAO produce unnecessary commits. We need to work aroud this or to work with the upstream to fix this. Or, did the upstream fix this issue already in a newer release? We are using a little bit old version of Shiro.

/cc @hyangtack

Compress the response content if it's large enough

The response we sent is sometimes fairly large. Sometimes it's greater than 300KiB. We could save quite a bit of bandwidth by compressing it.

  • Recognize accept-encoding HTTP header and compress the response on the fly.
    • Support gzip, deflate and brotli
  • Cache the compressed result if possible.

This will require the work on the Armeria side first.

Server-side metrics

Expose stats about:

  • JVM and OS
  • Netty (needs Armeria-side work)
  • HTTP requests
  • Which replica is a leader?
  • Whether a replica is runing in read-only mode

Switch from Angular.js to Vue.js

Angular.js is showing its age and thus we should migrate to something with brighter future. During the migration, we also may want to migrate from Bootstrap to Material design

Do not expose `internal.thrift.CentralDogmaException`

When the Java client library fails, internal.thrift.CentralDogmaException is raised. This exposes an internal class as well as our implementation detail (Thrift). We should convert it into a protocol-agnostic generic exception type.

UI for editing mirror settings

Creating and editing mirror settings require manual JSON editing which is time-consuming and error-prone. We should provide a dedicated UI for a meta repository so that a user cannot make a mistake when configuring a mirror.

Also, for some reason, when a bad mirror setting leaked into a meta repository, the UI should provide an easy way to figure out what's wrong with his/her setting.

Enforce hard-limit on file size

We currently do not enforce any limit of the size of a file, which can cause troubles such as OOME when a user attempts to push a very large file.

We currently enforce 10 MiB hard limit on request content, but a user may want to increase the maximum allowed content length while limiting the size of an individual file. Think about a commit that contains multiple files whose total size is greater than 10 MiB while their each size is less than 1 MiB.

Flaky test: GitRepositoryTest.testHistory_correctRangeOfResult

GitRepositoryTest.testHistory_correctRangeOfResult: FAILURE
com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest > testHistory_correctRangeOfResult FAILED
    org.junit.ComparisonFailure: expected:<Revision([4])> but was:<Revision([5])>
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest.testHistory_correctRangeOfResult(GitRepositoryTest.java:708)

Provide a generic facility to show per-project and global notifications

A Central Dogma project (or its repositories) is updated automatically by a machine. e.g. Git-to-CD mirroring. When such a task fails, there's no way to know the reason of the failure other than digging into the log files, which is very inconvenient.

We should provide a generic API that allows such tasks to send a notification/log message so that a user can browse them via web admin UI or watchable API call.

Provide a way to close Watcher in CentralDogmaBean

When you create a bean instance using CentralDogmaBeanFactory, the Watcher is made and there's no way to close it actively. It is, currently, closed with an exception when the watching server is down and therefore, it pollutes the output.

Flaky test: ZooKeeperCommandExecutorTest.testLogWatch

2017-10-10 09:11:10.711 [INFO ](c.l.c.s.i.r.ZooKeeperCommandExecutor) [Curator-LeaderSelector-1] Releasing leadership: m2
2017-10-10 09:11:10.718 [ERROR](o.a.c.f.r.l.LeaderSelector) [Curator-LeaderSelector-1] The leader threw an exception
java.lang.IllegalStateException: instance must be started before calling this method
	at org.apache.curator.shaded.com.google.common.base.Preconditions.checkState(Preconditions.java:176)
	at org.apache.curator.framework.imps.CuratorFrameworkImpl.delete(CuratorFrameworkImpl.java:359)
	at org.apache.curator.framework.recipes.locks.LockInternals.deleteOurPath(LockInternals.java:339)
	at org.apache.curator.framework.recipes.locks.LockInternals.releaseLock(LockInternals.java:123)
	at org.apache.curator.framework.recipes.locks.InterProcessMutex.release(InterProcessMutex.java:154)
	at org.apache.curator.framework.recipes.leader.LeaderSelector.doWork(LeaderSelector.java:449)
	at org.apache.curator.framework.recipes.leader.LeaderSelector.doWorkLoop(LeaderSelector.java:466)
	at org.apache.curator.framework.recipes.leader.LeaderSelector.access$100(LeaderSelector.java:65)
	at org.apache.curator.framework.recipes.leader.LeaderSelector$2.call(LeaderSelector.java:246)
	at org.apache.curator.framework.recipes.leader.LeaderSelector$2.call(LeaderSelector.java:240)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Store revision-commitId mapping in a dedicated store

GitRepository currently uses a tag to maintain the mappings between revisions and commitIds. It has the following problems:

  • When using the default refstorage implementation (refdir), it creates a symbolic link for each revision, which is slow and which creates too many files in the long term.
  • When using the 'reftree' refstorage implementation, the disk usage of the repository increases way too much (more than 2x). Also, it becomes impossible to browse the repository using vanilla git command because reftree is a jGit-only extension.

I'd like to experiment with storing the revision-commitId mappings in a dedicated store like B-tree.

Related: https://github.com/lmdbjava/lmdbjava

Access control

We need to implement per-app/user and per-organization/group access control, such as who or which group can read or write which path patterns. We may need to store which user belongs to which group in Central Dogma's internal storage.

/cc @tokuhirom

Pagination when browsing history

No pagination has been implemented in the history view of the administrative UI. This can cause a problem as the number of commits increases.

Client library with fewer dependencies

A user want to use CentralDogma with Netty 4.0 (e.g. Apache Flink uses 4.0) but because Armeria uses methods that is newly added in Netty 4.1, it causes NoSuchMethod exception.

Currently, he/she can relocate Netty 4.1 by himself/herself.

To solve this, we can 1) make Armeria shade Netty or 2) refactor the client library so it has Armeria-based provider and URLConnection-based provider.

Related: line/armeria#705

Allow choosing diff format for JSON

Currently, a diff of a JSON file will always be represented in JSON patch format, which may not be a desired behavior when a user expects unified format. For example, some languages might not have proper JSON patch implementation.

We need to generalize this feature so a user can potentially ask for an alternative diff format for any file formats.

Add an option that appends a certain label next to web page title

Currently, there's no easy way to know if the CD instance he or she is accessing belongs to BETA or RELEASE zone. We currently show the host name of the instance, but it's not clear enough. We could add a simple text value option whose value is appended to the web page title. e.g. 'Central Dogma (BETA, {hostname})'

Flaky test: ZooKeeperCommandExecutorTest.testLogWatch

com.linecorp.centraldogma.server.internal.replication.ZooKeeperCommandExecutorTest > testLogWatch FAILED
 Wanted but not invoked:
 function.apply(
 CreateProjectCommand{type=CREATE_PROJECT, projectName=foo}
 );
 -> at com.linecorp.centraldogma.server.internal.replication.ZooKeeperCommandExecutorTest.testLogWatch(ZooKeeperCommandExecutorTest.java:119)
 Actually, there were zero interactions with this mock.
 at com.linecorp.centraldogma.server.internal.replication.ZooKeeperCommandExecutorTest.testLogWatch(ZooKeeperCommandExecutorTest.java:119)

Flaky test: GitRepositoryTest.testEmptyCommitWithRedundantRenames

GitRepositoryTest.testEmptyCommitWithRedundantRenames: FAILURE
com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest > testEmptyCommitWithRedundantRenames FAILED
    java.lang.AssertionError: 
    Expecting a throwable with cause being an instance of:
     <com.linecorp.centraldogma.server.internal.storage.repository.RedundantChangeException>
    but was an instance of:
     <com.linecorp.centraldogma.server.internal.storage.repository.ChangeConflictException: non-existent file/directory: Change{type=RENAME, path=/testEmptyCommitWithRedundantRenames/0.json}>
        at com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest.testEmptyCommitWithRedundantRenames(GitRepositoryTest.java:411)

README file support

When a user browses a repository, it would be useful if the administrative console displays the content of the README file in the current directory, just like GitHub does with the README.* files.

Also, a user may be interested in what a project is for. We need to think about a way to supply a README for a project because we cannot put files into a project. Probably into the meta repository?

Flaky test: GitRepositoryTest.testHistory_correctRangeOfResult

com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest > testHistory_correctRangeOfResult FAILED

    org.junit.ComparisonFailure: expected:<Revision([4])> but was:<Revision([5])>

        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)

        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

        at com.linecorp.centraldogma.server.internal.storage.repository.git.GitRepositoryTest.testHistory_correctRangeOfResult(GitRepositoryTest.java:708)

Deploy the tarball to Maven central

.. which would simplify the automated retrieval and verification of a tarball. For example, a user may want to build the Central Dogma distribution derived from the official tarball, like adding some extra jars to lib/ext and overriding some configuration files such as dogma.json and logback.xml.

Client-side filesystem cache

.. so that:

  • client applications do not refuse to start due to the inability to retrieve the configuration
  • clients send fewer number of requests potentially

Note that a user should be allowed to disable this feature just in case he or she wants to make sure the latest revision is always retrieved.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.