├── .gitignore ├── README.md ├── auth ├── build.gradle └── src │ ├── main │ └── java │ │ ├── io │ │ └── buildpal │ │ │ └── auth │ │ │ ├── Authenticator.java │ │ │ ├── LdapAuthenticator.java │ │ │ ├── VaultAuthenticator.java │ │ │ ├── util │ │ │ └── AuthConfigUtils.java │ │ │ └── vault │ │ │ ├── JCEVaultVerticle.java │ │ │ ├── Vault.java │ │ │ └── VaultService.java │ │ └── module-info.java │ └── test │ └── java │ └── io │ └── buildpal │ └── auth │ ├── util │ └── AuthConfigUtilsTest.java │ └── vault │ └── VaultTest.java ├── build.gradle ├── build.sh ├── core ├── build.gradle └── src │ ├── main │ ├── antlr │ │ └── io │ │ │ └── buildpal │ │ │ └── core │ │ │ └── query │ │ │ └── Query.g4 │ └── java │ │ ├── io │ │ └── buildpal │ │ │ └── core │ │ │ ├── config │ │ │ └── Constants.java │ │ │ ├── domain │ │ │ ├── Build.java │ │ │ ├── DataItem.java │ │ │ ├── Entity.java │ │ │ ├── Phase.java │ │ │ ├── Pipeline.java │ │ │ ├── PipelineJs.java │ │ │ ├── Project.java │ │ │ ├── Repository.java │ │ │ ├── Secret.java │ │ │ ├── Status.java │ │ │ ├── User.java │ │ │ ├── Workspace.java │ │ │ ├── builder │ │ │ │ └── Builder.java │ │ │ └── validation │ │ │ │ ├── BasicValidator.java │ │ │ │ ├── BuildValidator.java │ │ │ │ ├── DataItemValidator.java │ │ │ │ ├── PipelineJsValidator.java │ │ │ │ ├── PipelineValidator.java │ │ │ │ ├── ProjectValidator.java │ │ │ │ ├── RepositoryValidator.java │ │ │ │ ├── SecretValidator.java │ │ │ │ ├── UserValidator.java │ │ │ │ └── Validator.java │ │ │ ├── pipeline │ │ │ ├── Plugin.java │ │ │ └── event │ │ │ │ ├── Command.java │ │ │ │ ├── CommandKey.java │ │ │ │ ├── Event.java │ │ │ │ └── EventKey.java │ │ │ ├── process │ │ │ └── ExternalProcess.java │ │ │ ├── query │ │ │ ├── QueryEngine.java │ │ │ ├── QueryEvaluator.java │ │ │ ├── QuerySpec.java │ │ │ ├── operand │ │ │ │ └── Operand.java │ │ │ ├── operation │ │ │ │ ├── BooleanOperation.java │ │ │ │ ├── DoubleOperation.java │ │ │ │ ├── InstantOperation.java │ │ │ │ ├── LongOperation.java │ │ │ │ ├── NullOperation.java │ │ │ │ ├── Operation.java │ │ │ │ └── StringOperation.java │ │ │ └── sort │ │ │ │ ├── Sort.java │ │ │ │ └── Sorter.java │ │ │ └── util │ │ │ ├── DataUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── ResultUtils.java │ │ │ ├── StringUtils.java │ │ │ ├── Utils.java │ │ │ └── VertxUtils.java │ │ └── module-info.java │ └── test │ └── java │ └── io │ └── buildpal │ └── core │ └── util │ ├── DataUtilsTest.java │ └── FileUtilsTest.java ├── db ├── build.gradle └── src │ └── main │ └── java │ ├── io │ └── buildpal │ │ └── db │ │ ├── DbManager.java │ │ ├── DbManagers.java │ │ └── file │ │ ├── BuildManager.java │ │ ├── FileDbManager.java │ │ ├── PipelineManager.java │ │ ├── ProjectManager.java │ │ ├── RepositoryManager.java │ │ ├── SecretManager.java │ │ └── UserManager.java │ └── module-info.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── node ├── build.gradle └── src │ ├── main │ └── java │ │ ├── io │ │ └── buildpal │ │ │ └── node │ │ │ ├── Node.java │ │ │ ├── NodeLauncher.java │ │ │ ├── auth │ │ │ ├── LoginAuthHandler.java │ │ │ └── LogoutAuthHandler.java │ │ │ ├── data │ │ │ ├── BuildScavenger.java │ │ │ └── NodeTracker.java │ │ │ ├── engine │ │ │ ├── Engine.java │ │ │ └── Flow.java │ │ │ └── router │ │ │ ├── BaseRouter.java │ │ │ ├── BuildRouter.java │ │ │ ├── CrudRouter.java │ │ │ ├── PipelineRouter.java │ │ │ ├── SecretRouter.java │ │ │ ├── StaticRouter.java │ │ │ ├── UserRouter.java │ │ │ └── WorkspaceRouter.java │ │ └── module-info.java │ └── test │ └── java │ └── io │ └── buildpal │ └── node │ └── EngineTest.java ├── oci ├── build.gradle └── src │ └── main │ └── java │ ├── io │ └── buildpal │ │ └── oci │ │ ├── DockerClientVerticle.java │ │ └── DockerStreamerSansHeader.java │ └── module-info.java ├── settings.gradle └── workspace ├── build.gradle └── src └── main ├── java ├── io │ └── buildpal │ │ └── workspace │ │ ├── ScriptVerticle.java │ │ ├── WorkspaceVerticle.java │ │ └── vcs │ │ ├── BaseVersionController.java │ │ ├── FileSystemController.java │ │ ├── GitController.java │ │ ├── P4Controller.java │ │ ├── SyncResult.java │ │ └── VersionController.java └── module-info.java └── resources ├── js ├── Container.js ├── ContainerArgs.js ├── ObjectUtils.js ├── Phase.js ├── Pipeline.js ├── Shell.js └── Workspace.js └── templates ├── footer.js └── header.js /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.iml 2 | **/.gradle 3 | **/.idea 4 | **/build 5 | **/.DS_Store 6 | **/.vertx 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Buildpal - docker/k8s native CI/CD tool 2 | ## Introduction 3 | Builpal is an open source CI/CD tool with first class support for pipelines. Built on top of the excellent reactive toolkit vertx, Buildpal runs your pipelines on docker containers. Buildpal is a good alternative for folks who prefer code over various configuration files and formats. You define pipelines in JavaScript (Java support is on its way). You can run multiple phases of a pipeline in parallel and cut down on your build times. Your pipeline can also build a docker image as the final outcome of a successful build. 4 | 5 | ## Project status 6 | This project is currently in experimental stage. We are trying to experiment with the new Java Platform Module System (JPMS) and Vert.x to design and develop a modern, responsive, resilient and message driven continuous integration (CI) system. Git and Perforce are the two currently supported source control systems. 7 | 8 | ## Getting started 9 | Buildpal runs on docker and co-ordinates builds by spinning additional containers. Make sure you have a version of docker that supports creation of named data volumes (version 1.13 or higher). 10 | 11 | Assuming you have docker installed, run the following command for a quick start: 12 | ```bash 13 | docker volume create buildpal-data && \ 14 | docker run -d --name buildpal -v /var/run/docker.sock:/var/run/docker.sock -v buildpal-data:/buildpal/data -p 8080:8080 -p 55555:55555 buildpal/buildpal 15 | ``` 16 | The initial admin password gets printed to the console. Look at the log by running the following command: 17 | ```bash 18 | docker logs buildpal 19 | ``` 20 | 21 | ### Creating a pipeline 22 | * For the default installation, you can access the app at http://localhost:8080 23 | * Login using your admin credentials. User name is "admin" (without the quotes) 24 | * Navigate to the repositories tab to define your repository 25 | * Once you create a repository, navigate to the pipelines tab 26 | * Now use the javascript editor to define your pipeline that runs combination of parallel or sequential phases. 27 | 28 | For setup and usage refer to our user guide. 29 | 30 | ## Development 31 | Builpal platform is developed on top of [vert.x](http://vertx.io/) using JDK 9 and Java Platform Module System. 32 | 33 | To start contributing, do the following: 34 | * Install the latest version of JDK 9. 35 | * Use git to clone the source code from https://github.com/buildpal/buildpal-platform.git 36 | * Buildal uses gradle. You can compile the code by running the gradle wrapper "gradlew.[sh|bat] clean build" 37 | -------------------------------------------------------------------------------- /auth/build.gradle: -------------------------------------------------------------------------------- 1 | javaModule.name = "io.buildpal.auth" 2 | 3 | dependencies { 4 | implementation "io.vertx:vertx-auth-jwt:$vertxVersion" 5 | implementation "io.vertx:vertx-web:$vertxVersion" 6 | implementation "org.apache.commons:commons-lang3:$commonsLangVersion" 7 | 8 | api project(":core") 9 | } 10 | -------------------------------------------------------------------------------- /auth/src/main/java/io/buildpal/auth/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.auth; 18 | 19 | import io.buildpal.core.domain.User; 20 | import io.vertx.core.AsyncResult; 21 | import io.vertx.core.Handler; 22 | 23 | public interface Authenticator { 24 | void authenticate(User user, Handler> handler); 25 | } 26 | -------------------------------------------------------------------------------- /auth/src/main/java/io/buildpal/auth/LdapAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.auth; 18 | 19 | import io.buildpal.core.domain.User; 20 | import io.vertx.core.AsyncResult; 21 | import io.vertx.core.Future; 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.json.JsonObject; 24 | import io.vertx.core.logging.Logger; 25 | import io.vertx.core.logging.LoggerFactory; 26 | 27 | import javax.naming.Context; 28 | import javax.naming.NamingException; 29 | import javax.naming.directory.Attributes; 30 | import javax.naming.directory.DirContext; 31 | import javax.naming.directory.InitialDirContext; 32 | import java.text.MessageFormat; 33 | import java.util.ArrayList; 34 | import java.util.Hashtable; 35 | import java.util.List; 36 | 37 | import static io.buildpal.auth.util.AuthConfigUtils.getDisplayNameAttributeID; 38 | import static io.buildpal.auth.util.AuthConfigUtils.getLdapUrl; 39 | import static io.buildpal.auth.util.AuthConfigUtils.getUserDnPatterns; 40 | import static io.buildpal.core.util.VertxUtils.future; 41 | 42 | public class LdapAuthenticator implements Authenticator { 43 | private static final Logger logger = LoggerFactory.getLogger(LdapAuthenticator.class); 44 | 45 | private final static String SUN_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; 46 | private final static String SIMPLE_AUTHENTICATION = "simple"; 47 | 48 | private String url; 49 | private List userDnPatterns; 50 | private String[] displayNameAttributeID; 51 | 52 | public LdapAuthenticator(JsonObject config) { 53 | url = getLdapUrl(config); 54 | userDnPatterns = getUserDnPatterns(config); 55 | displayNameAttributeID = getDisplayNameAttributeID(config); 56 | } 57 | 58 | @Override 59 | public void authenticate(User user, Handler> handler) { 60 | Future authFuture = future(handler); 61 | 62 | for (String userDn : prepareUserDns(user.getUserName())) { 63 | 64 | User authenticatedUser = bindUser(userDn, user); 65 | 66 | if (authenticatedUser != null) { 67 | authFuture.complete(authenticatedUser); 68 | return; 69 | } 70 | } 71 | 72 | authFuture.complete(null); 73 | } 74 | 75 | private User bindUser(String userDn, User user) { 76 | logger.debug("LDAP bind operation for user: " + userDn); 77 | 78 | Hashtable env = new Hashtable<>(); 79 | 80 | env.put(Context.SECURITY_AUTHENTICATION, SIMPLE_AUTHENTICATION); 81 | env.put(Context.SECURITY_PRINCIPAL, userDn); 82 | env.put(Context.SECURITY_CREDENTIALS, user.getPassword()); 83 | env.put(Context.INITIAL_CONTEXT_FACTORY, SUN_CONTEXT_FACTORY); 84 | env.put(Context.PROVIDER_URL, url); 85 | 86 | DirContext dirContext = null; 87 | 88 | try { 89 | dirContext = new InitialDirContext(env); 90 | 91 | User authenticatedUser = new User() 92 | .setUserName(user.getUserName()) 93 | .setType(User.Type.LDAP); 94 | 95 | if (displayNameAttributeID != null) { 96 | Attributes attr = dirContext.getAttributes(userDn, displayNameAttributeID); 97 | 98 | if (attr != null) { 99 | authenticatedUser.setName(attr.get(displayNameAttributeID[0]).get().toString()); 100 | } 101 | } 102 | 103 | return authenticatedUser.normalize(); 104 | 105 | } catch (NamingException ex) { 106 | logger.error("Unable to bind user: " + userDn, ex); 107 | 108 | } finally { 109 | close(dirContext); 110 | } 111 | 112 | return null; 113 | } 114 | 115 | private List prepareUserDns(String username) { 116 | List userDns = new ArrayList<>(userDnPatterns.size()); 117 | String[] args = new String[] { username }; 118 | 119 | for (MessageFormat userDnPattern : userDnPatterns) { 120 | userDns.add(userDnPattern.format(args)); 121 | } 122 | 123 | return userDns; 124 | } 125 | 126 | private void close(DirContext dirContext) { 127 | if (dirContext == null) return; 128 | 129 | try { 130 | dirContext.close(); 131 | 132 | } catch (NamingException e) { 133 | // Do nothing --silent close. 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /auth/src/main/java/io/buildpal/auth/VaultAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.auth; 18 | 19 | import io.buildpal.auth.util.AuthConfigUtils; 20 | import io.buildpal.auth.vault.VaultService; 21 | import io.buildpal.core.domain.User; 22 | import io.vertx.core.AsyncResult; 23 | import io.vertx.core.Future; 24 | import io.vertx.core.Handler; 25 | import io.vertx.core.json.JsonObject; 26 | import io.vertx.core.logging.Logger; 27 | import io.vertx.core.logging.LoggerFactory; 28 | 29 | import java.util.Arrays; 30 | 31 | import static io.buildpal.core.config.Constants.DATA; 32 | import static io.buildpal.core.util.VertxUtils.future; 33 | 34 | public class VaultAuthenticator implements Authenticator { 35 | private static final Logger logger = LoggerFactory.getLogger(VaultAuthenticator.class); 36 | 37 | private final VaultService vaultService; 38 | 39 | public VaultAuthenticator(VaultService vaultService) { 40 | this.vaultService = vaultService; 41 | } 42 | 43 | @Override 44 | public void authenticate(User user, Handler> handler) { 45 | Future authFuture = future(handler); 46 | 47 | // Get the hash and verify. 48 | vaultService.retrieveHash(user.getUserName(), rh -> { 49 | 50 | if (rh.succeeded()) { 51 | 52 | authFuture.complete(verifyHash(user, rh.result())); 53 | 54 | } else { 55 | logger.error("Unable to authenticate user.", rh.cause()); 56 | authFuture.complete(null); 57 | } 58 | }); 59 | } 60 | 61 | private User verifyHash(User user, JsonObject hashedData) { 62 | try { 63 | byte[] actualHash = AuthConfigUtils.hash(user.getPassword().toCharArray(), user.getSalt()); 64 | byte[] expectedHash = hashedData.getBinary(DATA); 65 | 66 | if (Arrays.equals(actualHash, expectedHash)) return user; 67 | 68 | } catch (Exception ex) { 69 | logger.error("Unable to authenticate user.", ex); 70 | } 71 | 72 | return null; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /auth/src/main/java/io/buildpal/auth/util/AuthConfigUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.auth.util; 18 | 19 | import io.vertx.core.json.JsonArray; 20 | import io.vertx.core.json.JsonObject; 21 | import org.apache.commons.lang3.StringUtils; 22 | 23 | import javax.crypto.SecretKey; 24 | import javax.crypto.SecretKeyFactory; 25 | import javax.crypto.spec.PBEKeySpec; 26 | import java.security.NoSuchAlgorithmException; 27 | import java.security.spec.InvalidKeySpecException; 28 | import java.text.MessageFormat; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import java.util.Objects; 32 | 33 | import static io.buildpal.core.config.Constants.KEY; 34 | 35 | public class AuthConfigUtils { 36 | private static final String AUTH = "auth"; 37 | private static final String VAULT = "vault"; 38 | private static final String LDAP = "ldap"; 39 | private static final String LDAP_PROTOCOL = "ldap://"; 40 | private static final String URL = "url"; 41 | private static final String USER_DN_PATTERNS = "userDnPatterns"; 42 | private static final String USER_DISPLAY_NAME_ATTRIBUTE_ID = "userDisplayNameAttributeID"; 43 | 44 | private static final String LDAP_URL_ERROR = "Ldap's \"url\" must be specified and valid"; 45 | private static final String USER_DN_PATTERNS_ERROR = "Ldap's \"userDnPatterns\" must be an array of patterns"; 46 | 47 | private static final String PBKDF2_WITH_HMAC = "PBKDF2WithHmacSHA512"; 48 | private static final int KEY_LENGTH = 256; 49 | private static final int ITERATIONS = 2; 50 | 51 | private static final JsonObject EMPTY = new JsonObject(); 52 | 53 | public static JsonObject getAuthConfig(JsonObject config) { 54 | return config.getJsonObject(AUTH, EMPTY); 55 | } 56 | 57 | public static JsonObject getVaultConfig(JsonObject config) { 58 | return getAuthConfig(config) 59 | .getJsonObject(VAULT, EMPTY); 60 | } 61 | 62 | public static String getVaultKey(JsonObject config) { 63 | String key = getVaultConfig(config) 64 | .getString(KEY); 65 | 66 | return Objects.requireNonNull(key, "Vault key must be configured"); 67 | } 68 | 69 | public static boolean isLdapEnabled(JsonObject config) { 70 | return getAuthConfig(config) 71 | .containsKey(LDAP); 72 | } 73 | 74 | public static JsonObject getLdapConfig(JsonObject config) { 75 | return getAuthConfig(config) 76 | .getJsonObject(LDAP, EMPTY); 77 | } 78 | 79 | public static String getLdapUrl(JsonObject config) { 80 | String ldapUrl = getLdapConfig(config).getString(URL); 81 | 82 | if (StringUtils.isBlank(ldapUrl)) throw new AssertionError(LDAP_URL_ERROR); 83 | 84 | if (!ldapUrl.startsWith(LDAP_PROTOCOL)) throw new AssertionError(LDAP_URL_ERROR); 85 | 86 | return ldapUrl; 87 | } 88 | 89 | public static List getUserDnPatterns(JsonObject config) { 90 | JsonArray dnPatterns = Objects.requireNonNull(getLdapConfig(config).getJsonArray(USER_DN_PATTERNS), 91 | USER_DN_PATTERNS_ERROR); 92 | 93 | List userDnPatterns = new ArrayList<>(); 94 | 95 | for (int i=0; i> saveHandler) { 47 | 48 | Future saveFuture = future(saveHandler); 49 | 50 | eb.send(SAVE_DATA_ADDRESS, data, smh -> { 51 | if (smh.succeeded()) { 52 | boolean saved = smh.result().body().getBoolean(SUCCESS, false); 53 | 54 | if (saved) { 55 | saveFuture.complete(); 56 | 57 | } else { 58 | saveFuture.fail("Unable to save data in vault."); 59 | } 60 | 61 | } else { 62 | saveFuture.fail(smh.cause()); 63 | } 64 | }); 65 | } 66 | 67 | public void save(String name, String data, byte[] salt, Handler> saveHandler) { 68 | 69 | Future saveFuture = future(saveHandler); 70 | 71 | JsonObject message = new JsonObject().put(NAME, name).put(DATA, data).put(SALT, salt); 72 | 73 | eb.send(SAVE_HASH_ADDRESS, message, smh -> { 74 | if (smh.succeeded()) { 75 | boolean saved = smh.result().body().getBoolean(SUCCESS, false); 76 | 77 | if (saved) { 78 | saveFuture.complete(); 79 | 80 | } else { 81 | saveFuture.fail("Unable to save hash in vault."); 82 | } 83 | 84 | } else { 85 | saveFuture.fail(smh.cause()); 86 | } 87 | }); 88 | } 89 | 90 | public void retrieve(String name, Handler> retrieveHandler) { 91 | Future retrieveFuture = future(retrieveHandler); 92 | JsonObject data = new JsonObject().put(NAME, name); 93 | 94 | eb.send(RETRIEVE_DATA_ADDRESS, data, rh -> { 95 | if (rh.succeeded()) { 96 | JsonObject json = rh.result().body(); 97 | 98 | if (json != null) { 99 | retrieveFuture.complete(json); 100 | 101 | } else { 102 | retrieveFuture.fail("Unable to retrieve data from vault."); 103 | } 104 | 105 | } else { 106 | retrieveFuture.fail(rh.cause()); 107 | } 108 | }); 109 | } 110 | 111 | public void retrieveHash(String name, Handler> retrieveHandler) { 112 | Future retrieveFuture = future(retrieveHandler); 113 | JsonObject data = new JsonObject().put(NAME, name); 114 | 115 | eb.send(RETRIEVE_HASH_ADDRESS, data, rh -> { 116 | if (rh.succeeded()) { 117 | JsonObject json = rh.result().body(); 118 | 119 | if (json != null) { 120 | retrieveFuture.complete(json); 121 | 122 | } else { 123 | retrieveFuture.fail("Unable to retrieve hash from vault."); 124 | } 125 | 126 | } else { 127 | retrieveFuture.fail(rh.cause()); 128 | } 129 | }); 130 | } 131 | } -------------------------------------------------------------------------------- /auth/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.auth { 18 | exports io.buildpal.auth; 19 | exports io.buildpal.auth.vault; 20 | exports io.buildpal.auth.util; 21 | 22 | requires java.naming; 23 | 24 | requires vertx.core; 25 | requires vertx.auth.jwt; 26 | requires vertx.web; 27 | 28 | requires org.apache.commons.lang3; 29 | 30 | requires io.buildpal.core; 31 | } -------------------------------------------------------------------------------- /auth/src/test/java/io/buildpal/auth/util/AuthConfigUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.auth.util; 18 | 19 | import io.buildpal.auth.vault.Vault; 20 | import org.junit.Assert; 21 | import org.junit.Test; 22 | 23 | import java.util.Arrays; 24 | 25 | import static io.buildpal.core.config.Constants.PATH; 26 | 27 | public class AuthConfigUtilsTest { 28 | public static final char[] KEY = "junit_key".toCharArray(); 29 | 30 | public static final byte[] SALT = "junit_salt".getBytes(); 31 | 32 | @Test 33 | public void hashTest() throws Exception { 34 | 35 | Vault vault = new Vault(KEY, PATH); 36 | 37 | byte[] hash1 = AuthConfigUtils.hash("test".toCharArray(), SALT); 38 | byte[] hash2 = AuthConfigUtils.hash("test".toCharArray(), SALT); 39 | byte[] hash3 = AuthConfigUtils.hash("tEst".toCharArray(), SALT); 40 | 41 | Assert.assertTrue("Hashes of the same string should be equal.", 42 | Arrays.equals(hash1, hash2)); 43 | Assert.assertFalse("Hashes of the different strings should not be equal.", 44 | Arrays.equals(hash2, hash3)); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /auth/src/test/java/io/buildpal/auth/vault/VaultTest.java: -------------------------------------------------------------------------------- 1 | package io.buildpal.auth.vault; 2 | 3 | import io.buildpal.auth.util.AuthConfigUtils; 4 | import io.vertx.core.json.JsonObject; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.util.Arrays; 9 | 10 | import static io.buildpal.auth.util.AuthConfigUtilsTest.KEY; 11 | import static io.buildpal.auth.util.AuthConfigUtilsTest.SALT; 12 | import static io.buildpal.core.domain.Entity.NAME; 13 | 14 | public class VaultTest { 15 | 16 | private static final String PATH = "build/vault.jceks"; 17 | 18 | 19 | @Test 20 | public void saveAndRetrieveHashTest() throws Exception { 21 | 22 | Vault vault = new Vault(KEY, PATH); 23 | String key = "test"; 24 | 25 | byte[] hash = AuthConfigUtils.hash(key.toCharArray(), SALT); 26 | vault.save(key, new Vault.Data(hash)); 27 | 28 | Vault.Data data = vault.retrieve(key); 29 | 30 | Assert.assertTrue("Hashes of the same string should be equal.", 31 | Arrays.equals(hash, data.getHashBytes())); 32 | } 33 | 34 | @Test 35 | public void saveAndRetrieveTest() throws Exception { 36 | 37 | Vault vault = new Vault(KEY, PATH); 38 | String name = "testJson"; 39 | 40 | JsonObject data = new JsonObject().put(NAME, name).put("someData", "abc"); 41 | vault.save(name, data); 42 | 43 | JsonObject savedData = vault.retrieveJson(name); 44 | 45 | Assert.assertTrue("Saved data and retrieved data should contain the same key and values.", 46 | savedData.encode().equals(data.encode())); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | task wrapper(type: Wrapper) { 2 | gradleVersion = '4.4.1' 3 | } 4 | 5 | buildscript { 6 | repositories { 7 | maven { 8 | url "https://plugins.gradle.org/m2/" 9 | } 10 | } 11 | 12 | dependencies { 13 | classpath "gradle.plugin.org.gradle.java:experimental-jigsaw:0.1.1" 14 | } 15 | } 16 | 17 | subprojects { 18 | apply plugin: "java-library" 19 | apply plugin: "org.gradle.java.experimental-jigsaw" 20 | 21 | group "io.buildpal" 22 | version "2.0-SNAPSHOT" 23 | 24 | sourceCompatibility = 1.9 25 | 26 | repositories { 27 | mavenLocal() 28 | mavenCentral() 29 | maven { 30 | url "https://oss.sonatype.org/content/repositories/snapshots" 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation "io.vertx:vertx-core:$vertxVersion" 36 | testImplementation "junit:junit:4.12" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cleanDockerContainers() { 4 | echo "${GREEN}Cleaning docker containers...${NC}\n" 5 | 6 | docker stop $(docker ps -a -q) 7 | docker rm $(docker ps -a -q) 8 | 9 | echo "${GREEN}Cleaned docker containers.${NC}\n" 10 | } 11 | 12 | 13 | cleanBuildpalImageAndVolume() { 14 | echo "${GREEN}Cleaning buildpal latest image and volumes...${NC}\n" 15 | 16 | docker rmi -f buildpal/buildpal:latest 17 | docker volume rm buildpal-data 18 | docker volume rm buildpal-system 19 | 20 | echo "${GREEN}Cleaned buildpal image and volumes.${NC}\n" 21 | } 22 | 23 | buildDockerImage() { 24 | echo "${GREEN}Buidling buildpal docker image...${NC}\n" 25 | 26 | rm -rf ${BUILDPAL_SUPPORT}/web 27 | cp -R ${BUILDPAL_UI}/web ${BUILDPAL_SUPPORT}/web 28 | 29 | rm ${BUILDPAL_DEPS}/auth-${BUILDPAL_VERSION}.jar 30 | rm ${BUILDPAL_DEPS}/core-${BUILDPAL_VERSION}.jar 31 | rm ${BUILDPAL_DEPS}/db-${BUILDPAL_VERSION}.jar 32 | rm ${BUILDPAL_DEPS}/node-${BUILDPAL_VERSION}.jar 33 | rm ${BUILDPAL_DEPS}/oci-${BUILDPAL_VERSION}.jar 34 | rm ${BUILDPAL_DEPS}/workspace-${BUILDPAL_VERSION}.jar 35 | 36 | cp ${SCRIPT_DIR}/auth/build/libs/auth-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/auth-${BUILDPAL_VERSION}.jar 37 | cp ${SCRIPT_DIR}/core/build/libs/core-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/core-${BUILDPAL_VERSION}.jar 38 | cp ${SCRIPT_DIR}/db/build/libs/db-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/db-${BUILDPAL_VERSION}.jar 39 | cp ${SCRIPT_DIR}/node/build/libs/node-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/node-${BUILDPAL_VERSION}.jar 40 | cp ${SCRIPT_DIR}/oci/build/libs/oci-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/oci-${BUILDPAL_VERSION}.jar 41 | cp ${SCRIPT_DIR}/workspace/build/libs/workspace-${BUILDPAL_VERSION}.jar ${BUILDPAL_DEPS}/workspace-${BUILDPAL_VERSION}.jar 42 | 43 | rm -rf ${BUILDPAL_SUPPORT}/libs 44 | cp -R ${BUILDPAL_DEPS} ${BUILDPAL_SUPPORT}/libs/ 45 | 46 | cd ${BUILDPAL_SUPPORT} 47 | 48 | docker build -t buildpal/buildpal:latest . 49 | 50 | echo "\nStarting docker container for buildpal..." 51 | 52 | docker volume create buildpal-data 53 | docker volume create buildpal-system 54 | 55 | docker run -d \ 56 | --name buildpal \ 57 | -v /var/run/docker.sock:/var/run/docker.sock \ 58 | -v buildpal-system:/buildpal/system \ 59 | -v buildpal-data:/buildpal/data \ 60 | -p 8080:8080 -p 55555:55555 -p 9080:9080 \ 61 | -e ZOOKEEPER_CONNECTION_STRING=192.168.1.248:2181 \ 62 | -e PUBLIC_FQDN=192.168.1.248 \ 63 | buildpal/buildpal 64 | 65 | echo "${GREEN}Started docker container for buildpal!${NC}\n\n" 66 | 67 | docker logs -f buildpal 68 | 69 | } 70 | 71 | buildWebUI() { 72 | echo "${GREEN}Compiling buildpal web UI...${NC}\n" 73 | cd ${BUILDPAL_UI} 74 | ojet build --release 75 | cd ${SCRIPT_DIR} 76 | } 77 | 78 | buildPlatform() { 79 | echo "${GREEN}Compiling buildpal platform...${NC}\n" 80 | cd ${SCRIPT_DIR} 81 | ./gradlew clean build 82 | } 83 | 84 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 85 | 86 | if [[ -z "${JAVA_HOME}" ]]; then 87 | echo "Please set JAVA_HOME environment variable" 88 | exit 1 89 | fi 90 | 91 | if [[ -z "${JAVA_LINK}" ]]; then 92 | echo "Please set JAVA_LINK environment variable - point it to jlink executable" 93 | exit 1 94 | fi 95 | 96 | if [[ -z "${BUILDPAL_DEPS}" ]]; then 97 | echo "Using default BUILDPAL_DEPS value" 98 | BUILDPAL_DEPS=../buildpal-deps 99 | fi 100 | 101 | if [[ -z "${BUILDPAL_SUPPORT}" ]]; then 102 | echo "Using default BUILDPAL_SUPPORT value" 103 | BUILDPAL_SUPPORT=../buildpal-support 104 | fi 105 | 106 | if [[ -z "${BUILDPAL_UI}" ]]; then 107 | echo "Using default BUILDPAL_UI value" 108 | BUILDPAL_UI=../../buildpal-ui 109 | fi 110 | 111 | 112 | 113 | RED='\033[0;31;47m' 114 | GREEN='\033[0;32m' 115 | NC='\033[0m' 116 | 117 | BUILDPAL_VERSION="2.0-SNAPSHOT" 118 | 119 | if [ -d "${BUILDPAL_DEPS}" ] && [ -d "${BUILDPAL_SUPPORT}" ]; then 120 | 121 | buildPlatform; 122 | buildWebUI; 123 | 124 | cleanDockerContainers; 125 | cleanBuildpalImageAndVolume; 126 | buildDockerImage; 127 | 128 | else 129 | echo "${RED}Make sure you point 'BUILDPAL_DEPS' and 'BUILDPAL_SUPPORT' to valid folders.${NC}\n" 130 | fi 131 | -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "antlr" 3 | } 4 | 5 | javaModule.name = "io.buildpal.core" 6 | 7 | dependencies { 8 | implementation "org.apache.commons:commons-lang3:$commonsLangVersion" 9 | 10 | antlr "org.antlr:antlr4:$antlrVersion" 11 | } 12 | 13 | generateGrammarSource { 14 | arguments += ["-visitor"] 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/antlr/io/buildpal/core/query/Query.g4: -------------------------------------------------------------------------------- 1 | // Reference link - https://tools.ietf.org/html/draft-ietf-scim-api-12#section-3.2.2 2 | 3 | grammar Query; 4 | 5 | @header { 6 | package io.buildpal.core.query; 7 | } 8 | 9 | filter 10 | : NOT? SP? '(' filter ')' #parenExp 11 | | filter SP LOGICAL_OPERATOR SP filter #logicalExp 12 | | attrPath SP 'pr' #presentExp 13 | | attrPath SP op=( 'eq' | 'ne' | 'gt' | 'lt' | 'ge' | 'le' | 'co' | 'sw' | 'ew' ) SP value #compareExp 14 | 15 | ; 16 | 17 | NOT 18 | : 'not' 19 | ; 20 | 21 | LOGICAL_OPERATOR 22 | : 'and' | 'or' 23 | ; 24 | 25 | BOOLEAN 26 | : 'true' | 'false' 27 | ; 28 | 29 | NULL 30 | : 'null' 31 | ; 32 | 33 | EQ : 'eq' ; 34 | NE : 'ne' ; 35 | GT : 'gt' ; 36 | LT : 'lt' ; 37 | GE : 'ge' ; 38 | LE : 'le' ; 39 | CO : 'co' ; 40 | SW : 'sw' ; 41 | EW : 'ew' ; 42 | 43 | attrPath 44 | : ATTRNAME subAttr? 45 | ; 46 | 47 | subAttr 48 | : '.' attrPath 49 | ; 50 | 51 | ATTRNAME 52 | : ALPHA ATTR_NAME_CHAR* ; 53 | 54 | fragment ATTR_NAME_CHAR 55 | : '-' | '_' | ':' | DIGIT | ALPHA 56 | ; 57 | 58 | fragment DIGIT 59 | : ('0'..'9') 60 | ; 61 | 62 | fragment ALPHA 63 | : ( 'A'..'Z' | 'a'..'z' ) 64 | ; 65 | 66 | value 67 | : BOOLEAN #boolean 68 | | NULL #null 69 | | STRING #string 70 | | DOUBLE #double 71 | | '-'? INT EXP? #long 72 | | INSTANT #instant 73 | ; 74 | 75 | STRING 76 | : '"' (ESC | ~ ["\\])* '"' 77 | ; 78 | 79 | fragment ESC 80 | : '\\' (["\\/bfnrt] | UNICODE) 81 | ; 82 | 83 | fragment UNICODE 84 | : 'u' HEX HEX HEX HEX 85 | ; 86 | 87 | fragment HEX 88 | : [0-9a-fA-F] 89 | ; 90 | 91 | DOUBLE 92 | : '-'? INT '.' [0-9] + EXP? 93 | ; 94 | 95 | // INT no leading zeros. 96 | INT 97 | : '0' | [1-9] [0-9]* 98 | ; 99 | 100 | // EXP we use "\-" since "-" means "range" inside [...] 101 | EXP 102 | : [Ee] [+\-]? INT 103 | ; 104 | 105 | INSTANT 106 | : 'i' '"' (ESC | ~ ["\\])* '"' 107 | ; 108 | 109 | SP 110 | : ' ' 111 | ; 112 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/config/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.config; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | /** 22 | * Shared constants across all modules. 23 | */ 24 | public class Constants { 25 | public static final JsonObject EMPTY_JSON = new JsonObject(); 26 | 27 | public static final String SYSTEM_FOLDER_PATH = "systemFolderPath"; 28 | public static final String DATA_FOLDER_PATH = "dataFolderPath"; 29 | 30 | public static final String ADMIN = "admin"; 31 | 32 | public static final String ITEMS = "items"; 33 | public static final String ITEM = "item"; 34 | 35 | public static final String KEY = "key"; 36 | public static final String DATA = "data"; 37 | public static final String SALT = "salt"; 38 | public static final String SUBJECT = "subject"; 39 | public static final String SYSTEM = "system"; 40 | 41 | public static final String DASH = "-"; 42 | public static final String DOT = "."; 43 | public static final String PIPE = "\\|"; 44 | public static final String COMMA = ","; 45 | 46 | public static final String PATH = "path"; 47 | public static final String TAIL = "tail"; 48 | 49 | public static final String SUCCESS = "success"; 50 | 51 | public static final String BUILD_UPDATE_ADDRESS = "build.update"; 52 | public static final String DELETE_CONTAINERS_ADDRESS = "oci.containers.delete"; 53 | public static final String KILL_CONTAINERS_ADDRESS = "oci.containers.kill"; 54 | public static final String SAVE_USER_AFFINITY_ADDRESS = "user.affinity.save"; 55 | public static final String DELETE_WORKSPACE_ADDRESS = "workspace.delete"; 56 | 57 | public final static String BUILDPAL_DATA_VOLUME = "buildpal-data"; 58 | 59 | public static final String NODE = "node"; 60 | public static final String DOCKER_VERTICLE = "dockerVerticle"; 61 | 62 | public static final String HTTP_PORT = "httpPort"; 63 | public static final String HOST = "host"; 64 | 65 | public static int getDockerVerticleHttpPort(JsonObject config, int defaultValue) { 66 | return config.getJsonObject(DOCKER_VERTICLE, EMPTY_JSON).getInteger(HTTP_PORT, defaultValue); 67 | } 68 | 69 | public static String getDockerVerticleHostOrIP(JsonObject config, String defaultValue) { 70 | return config.getJsonObject(DOCKER_VERTICLE, EMPTY_JSON).getString(HOST, defaultValue); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/DataItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | import org.apache.commons.lang3.StringUtils; 21 | 22 | import static org.apache.commons.lang3.StringUtils.EMPTY; 23 | 24 | public class DataItem extends Entity { 25 | 26 | public static final String DEFAULT_VALUE = "defaultValue"; 27 | 28 | static final String VALUE = "value"; 29 | 30 | private static final String DATA_KEY = "${data.%s}"; 31 | 32 | public enum Type { 33 | STRING 34 | } 35 | 36 | public DataItem() { 37 | super(); 38 | } 39 | 40 | public DataItem(JsonObject jsonObject) { 41 | super(jsonObject); 42 | } 43 | 44 | public Type getType() { 45 | if (jsonObject.containsKey(TYPE)) { 46 | try { 47 | return Type.valueOf(jsonObject.getString(TYPE)); 48 | 49 | } catch (IllegalArgumentException ex) { 50 | return null; 51 | } 52 | } 53 | 54 | return null; 55 | } 56 | 57 | public DataItem setType(Type type) { 58 | jsonObject.put(TYPE, type.name()); 59 | return this; 60 | } 61 | 62 | public boolean hasDefaultValue() { 63 | return jsonObject.containsKey(DEFAULT_VALUE) && StringUtils.isNotBlank(getDefaultValue()); 64 | } 65 | 66 | public String value() { 67 | return jsonObject.getString(VALUE, getDefaultValue()); 68 | } 69 | 70 | public DataItem setValue(String value) { 71 | if (StringUtils.isNotBlank(value)) { 72 | jsonObject.put(VALUE, value.trim()); 73 | } 74 | 75 | return this; 76 | } 77 | 78 | public String getDefaultValue() { 79 | return jsonObject.getString(DEFAULT_VALUE, EMPTY); 80 | } 81 | 82 | public DataItem setDefaultValue(String defaultValue) { 83 | if (StringUtils.isNotBlank(defaultValue)) { 84 | jsonObject.put(DEFAULT_VALUE, defaultValue.trim()); 85 | } 86 | 87 | return this; 88 | } 89 | 90 | public String key() { 91 | return String.format(DATA_KEY, getID()); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Entity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.buildpal.core.util.Utils; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | import java.time.Clock; 23 | import java.time.Instant; 24 | 25 | /** 26 | * Wrapper that holds the JSON representation of a domain entity. 27 | */ 28 | public abstract class Entity { 29 | 30 | public static final String ID = "id"; 31 | public static final String NAME = "name"; 32 | public static final String DESC = "description"; 33 | public static final String TYPE = "type"; 34 | 35 | public static final String UTC_CREATED_DATE = "utcCreatedDate"; 36 | public static final String UTC_LAST_MODIFIED_DATE = "utcLastModifiedDate"; 37 | public static final String CREATED_BY = "createdBy"; 38 | public static final String LAST_MODIFIED_BY = "lastModifiedBy"; 39 | 40 | protected JsonObject jsonObject; 41 | 42 | public Entity() { 43 | this.jsonObject = new JsonObject(); 44 | } 45 | 46 | public Entity(JsonObject jsonObject) { 47 | this.jsonObject = jsonObject; 48 | } 49 | 50 | @SuppressWarnings("unchecked") 51 | public E merge(JsonObject jsonObject) { 52 | this.jsonObject.mergeIn(jsonObject); 53 | return (E) this; 54 | } 55 | 56 | @SuppressWarnings("unchecked") 57 | public E reload(JsonObject jsonObject) { 58 | this.jsonObject = jsonObject; 59 | return (E) this; 60 | } 61 | 62 | public JsonObject json() { 63 | return jsonObject; 64 | } 65 | 66 | public String getID() { 67 | return jsonObject.getString(ID); 68 | } 69 | 70 | @SuppressWarnings("unchecked") 71 | public E setID(String id) { 72 | jsonObject.put(ID, id); 73 | return (E) this; 74 | } 75 | 76 | public String getName() { 77 | return jsonObject.getString(NAME); 78 | } 79 | 80 | @SuppressWarnings("unchecked") 81 | public E setName(String name) { 82 | jsonObject.put(NAME, name); 83 | return (E) this; 84 | } 85 | 86 | String getDescription() { 87 | return jsonObject.getString(DESC); 88 | } 89 | 90 | @SuppressWarnings("unchecked") 91 | public E setDescription(String description) { 92 | jsonObject.put(DESC, description); 93 | return (E) this; 94 | } 95 | 96 | public Instant getUtcCreatedDate() { 97 | return jsonObject.getInstant(UTC_CREATED_DATE); 98 | } 99 | 100 | @SuppressWarnings("unchecked") 101 | public E setUtcCreatedDate(Instant utcCreatedDate) { 102 | jsonObject.put(UTC_CREATED_DATE, utcCreatedDate); 103 | return (E) this; 104 | } 105 | 106 | public Instant getUtcLastModifiedDate() { 107 | return jsonObject.getInstant(UTC_LAST_MODIFIED_DATE); 108 | } 109 | 110 | @SuppressWarnings("unchecked") 111 | public E setUtcLastModifiedDate(Instant utcLastModifiedDate) { 112 | jsonObject.put(UTC_LAST_MODIFIED_DATE, utcLastModifiedDate); 113 | return (E) this; 114 | } 115 | 116 | public String getCreatedBy() { 117 | return jsonObject.getString(CREATED_BY); 118 | } 119 | 120 | @SuppressWarnings("unchecked") 121 | public E setCreatedBy(String createdBy) { 122 | jsonObject.put(CREATED_BY, createdBy); 123 | return (E) this; 124 | } 125 | 126 | public String getLastModifiedBy() { 127 | return jsonObject.getString(LAST_MODIFIED_BY); 128 | } 129 | 130 | @SuppressWarnings("unchecked") 131 | public E setLastModifiedBy(String lastModifiedBy) { 132 | jsonObject.put(LAST_MODIFIED_BY, lastModifiedBy); 133 | return (E) this; 134 | } 135 | 136 | public static > void populate(Any entity, String subject) { 137 | Instant utcNow = Instant.now(Clock.systemUTC()); 138 | 139 | entity.setID(Utils.newID()) 140 | .setUtcCreatedDate(utcNow) 141 | .setCreatedBy(subject) 142 | .setUtcLastModifiedDate(utcNow) 143 | .setLastModifiedBy(subject); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Pipeline.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonArray; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | public class Pipeline extends Entity { 26 | 27 | public static final String REPOSITORY_ID = "repositoryID"; 28 | public static final String JS = "js"; 29 | 30 | public static final String DATA_LIST = "dataList"; 31 | 32 | public Pipeline() { 33 | super(); 34 | } 35 | 36 | public Pipeline(JsonObject jsonObject) { 37 | super(jsonObject); 38 | } 39 | 40 | public String getRepositoryID() { 41 | return jsonObject.getString(REPOSITORY_ID); 42 | } 43 | 44 | public Pipeline setRepositoryID(String repositoryID) { 45 | jsonObject.put(REPOSITORY_ID, repositoryID); 46 | return this; 47 | } 48 | 49 | public Repository getRepository() { 50 | JsonObject repository = jsonObject.getJsonObject(Repository.REPOSITORY); 51 | 52 | if (repository == null) return null; 53 | 54 | return new Repository(repository); 55 | } 56 | 57 | public Pipeline setRepository(JsonObject repository) { 58 | if (repository != null) { 59 | jsonObject.put(Repository.REPOSITORY, repository); 60 | } 61 | 62 | return this; 63 | } 64 | 65 | public JsonArray getDataList() { 66 | return jsonObject.getJsonArray(DATA_LIST, new JsonArray()); 67 | } 68 | 69 | public List dataList() { 70 | JsonArray rawDataList = getDataList(); 71 | List dataList = new ArrayList<>(); 72 | 73 | for (int d=0; d dataList) { 81 | jsonObject.put(DATA_LIST, dataList); 82 | return this; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/PipelineJs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | public class PipelineJs extends Entity { 22 | 23 | private static final String FILE_PATH = "filePath"; 24 | 25 | public PipelineJs() { 26 | super(); 27 | } 28 | 29 | public PipelineJs(JsonObject jsonObject) { 30 | super(jsonObject); 31 | } 32 | 33 | public String getFilePath() { 34 | return jsonObject.getString(FILE_PATH); 35 | } 36 | 37 | public PipelineJs setFilePath(String filePath) { 38 | jsonObject.put(FILE_PATH, filePath); 39 | return this; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Project.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | public class Project extends Entity { 22 | public static final String PROJECT = "project"; 23 | 24 | public Project() { 25 | super(); 26 | } 27 | 28 | public Project(JsonObject jsonObject) { 29 | super(jsonObject); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Secret.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | import static io.buildpal.core.domain.User.PASSWORD; 22 | import static io.buildpal.core.domain.User.USERNAME; 23 | 24 | public class Secret extends Entity { 25 | 26 | public static final String SECRET = "secret"; 27 | 28 | public Secret() { 29 | super(); 30 | } 31 | 32 | public Secret(JsonObject jsonObject) { 33 | super(jsonObject); 34 | } 35 | 36 | public String getUserName() { 37 | return jsonObject.getString(USERNAME); 38 | } 39 | 40 | public String getPwd() { 41 | return jsonObject.getString(PASSWORD); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Status.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | public enum Status { 20 | PARKED, 21 | PRE_FLIGHT, 22 | IN_FLIGHT, 23 | DONE, 24 | FAILED, 25 | WAITING, 26 | CANCELED 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/Workspace.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | import java.io.File; 22 | 23 | public class Workspace extends Entity { 24 | public static final String PATH = "path"; 25 | 26 | public static final String WORKSPACE = "workspace"; 27 | 28 | private static final String USER_PATH = "userPath"; 29 | private static final String ROOT_PATH = "rootPath"; 30 | private static final String PHASES_PATH = "phasesPath"; 31 | private static final String BUILD_CONTEXT_PATH = "buildContextPath"; 32 | 33 | public Workspace() { 34 | super(); 35 | } 36 | 37 | public Workspace(JsonObject jsonObject) { 38 | super(jsonObject); 39 | } 40 | 41 | public String getPath() { 42 | return jsonObject.getString(PATH); 43 | } 44 | 45 | public File path() { 46 | return new File(getPath()); 47 | } 48 | 49 | public Workspace setPath(String path) { 50 | jsonObject.put(PATH, path); 51 | return this; 52 | } 53 | 54 | public String getUserPath() { 55 | return jsonObject.getString(USER_PATH); 56 | } 57 | 58 | public Workspace setUserPath(String userPath) { 59 | jsonObject.put(USER_PATH, userPath); 60 | return this; 61 | } 62 | 63 | public String getRootPath() { 64 | return jsonObject.getString(ROOT_PATH); 65 | } 66 | 67 | public Workspace setRootPath(String rootPath) { 68 | jsonObject.put(ROOT_PATH, rootPath); 69 | return this; 70 | } 71 | 72 | public String getPhasesPath() { 73 | return jsonObject.getString(PHASES_PATH); 74 | } 75 | 76 | public Workspace setPhasesPath(String phasesPath) { 77 | jsonObject.put(PHASES_PATH, phasesPath); 78 | return this; 79 | } 80 | 81 | public String getBuildContextPath() { 82 | return jsonObject.getString(BUILD_CONTEXT_PATH); 83 | } 84 | 85 | public File buildContextPath() { 86 | return new File(getBuildContextPath()); 87 | } 88 | 89 | public Workspace setBuildContextPath(String buildContextPath) { 90 | jsonObject.put(BUILD_CONTEXT_PATH, buildContextPath); 91 | return this; 92 | } 93 | 94 | public Workspace cloneMe() { 95 | return new Workspace(json().copy()); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/builder/Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.builder; 18 | 19 | import io.buildpal.core.domain.Entity; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | @FunctionalInterface 23 | public interface Builder> { 24 | E build(JsonObject jsonObject); 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/BuildValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.Build; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class BuildValidator extends BasicValidator { 25 | 26 | public BuildValidator() { 27 | super(Build::new); 28 | } 29 | 30 | @Override 31 | protected List validateEntity(Build entity) { 32 | List errors = new ArrayList<>(); 33 | 34 | validateString(errors, entity.getID(),"Specify an ID.", 32); 35 | 36 | validateInstant(errors, entity.getUtcCreatedDate(), 37 | "Specify a value for when the entity was created."); 38 | validateString(errors, entity.getCreatedBy(), 39 | "Specify a value for who created the entity."); 40 | 41 | validateInstant(errors, entity.getUtcLastModifiedDate(), 42 | "Specify a value for when the entity was last modified."); 43 | validateString(errors, entity.getLastModifiedBy(), 44 | "Specify a value for who last modified the entity."); 45 | 46 | return errors; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/DataItemValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.DataItem; 20 | import org.apache.commons.lang3.StringUtils; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import static io.buildpal.core.domain.DataItem.DEFAULT_VALUE; 26 | 27 | public class DataItemValidator extends BasicValidator { 28 | 29 | public DataItemValidator() { 30 | super(DataItem::new); 31 | } 32 | 33 | @Override 34 | public List validateID(String id) { 35 | List errors = new ArrayList<>(); 36 | 37 | validateString(errors, id,"Specify an ID."); 38 | 39 | if (errors.isEmpty()) { 40 | if (!StringUtils.isAllUpperCase(id.replace("_", ""))) { 41 | errors.add("ID should be all uppercase."); 42 | } 43 | } 44 | 45 | validateAlphanumericUnderscore(errors, id, "ID should be alphanumeric without spaces."); 46 | 47 | return errors; 48 | } 49 | 50 | @Override 51 | protected List validateEntity(DataItem entity) { 52 | List errors = validateID(entity.getID()); 53 | 54 | validateString(errors, entity.getName(),"Specify a name."); 55 | 56 | DataItem.Type type = entity.getType(); 57 | validateObject(errors, type, "Specify a type."); 58 | 59 | if (entity.json().containsKey(DEFAULT_VALUE)) { 60 | validateString(errors, entity.getDefaultValue(),"Specify a default value."); 61 | } 62 | 63 | return errors; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/PipelineJsValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.PipelineJs; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class PipelineJsValidator extends BasicValidator { 25 | 26 | private static final String EXT_JS = ".js"; 27 | 28 | public PipelineJsValidator() { 29 | super(PipelineJs::new); 30 | } 31 | 32 | @Override 33 | public List validateEntity(PipelineJs entity) { 34 | List errors = new ArrayList<>(); 35 | 36 | validateString(errors, entity.getID(), "Specify a pipeline javascript file."); 37 | 38 | // If the javascript file is specified, make sure it has a js extension. 39 | if (errors.isEmpty()) { 40 | if (!entity.getID().endsWith(EXT_JS)) { 41 | errors.add("Please specify a valid pipeline javascript file."); 42 | } 43 | } 44 | 45 | validateString(errors, entity.getFilePath(), "Specify the path to the pipeline javascript file."); 46 | 47 | return errors; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/PipelineValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.DataItem; 20 | import io.buildpal.core.domain.Pipeline; 21 | 22 | import java.util.List; 23 | 24 | import static io.buildpal.core.domain.Pipeline.DATA_LIST; 25 | 26 | public class PipelineValidator extends BasicValidator { 27 | 28 | public PipelineValidator() { 29 | super(Pipeline::new); 30 | } 31 | 32 | @Override 33 | protected List validateEntity(Pipeline entity) { 34 | List errors = super.validateEntity(entity); 35 | 36 | if (entity.json().containsKey(DATA_LIST)) { 37 | try { 38 | 39 | DataItemValidator dataItemValidator = new DataItemValidator(); 40 | 41 | for (DataItem data : entity.dataList()) { 42 | errors.addAll(dataItemValidator.validateEntity(data)); 43 | } 44 | 45 | } catch (Exception ex) { 46 | errors.add("Specify a valid data list."); 47 | } 48 | } 49 | 50 | return errors; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/ProjectValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.Project; 20 | 21 | public class ProjectValidator extends BasicValidator { 22 | 23 | public ProjectValidator() { 24 | super(Project::new); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/SecretValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.Secret; 20 | 21 | public class SecretValidator extends BasicValidator { 22 | 23 | public SecretValidator() { 24 | super(Secret::new); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/UserValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.buildpal.core.domain.User; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | import static io.buildpal.core.domain.User.PASSWORD; 25 | 26 | public class UserValidator extends BasicValidator { 27 | 28 | public UserValidator() { 29 | super(User::new); 30 | } 31 | 32 | @Override 33 | public List validateID(String id) { 34 | List errors = new ArrayList<>(); 35 | 36 | validateString(errors, id,"Specify an ID.", 2); 37 | 38 | return errors; 39 | } 40 | 41 | @Override 42 | protected List validateEntity(User entity) { 43 | List errors = validateID(entity.getID()); 44 | 45 | validateString(errors, entity.getUserName(),"Specify a username."); 46 | 47 | validateInstant(errors, entity.getUtcCreatedDate(), 48 | "Specify a value for when the entity was created."); 49 | validateString(errors, entity.getCreatedBy(), 50 | "Specify a value for who created the entity."); 51 | 52 | validateInstant(errors, entity.getUtcLastModifiedDate(), 53 | "Specify a value for when the entity was last modified."); 54 | validateString(errors, entity.getLastModifiedBy(), 55 | "Specify a value for who last modified the entity."); 56 | 57 | User.Type type = entity.getType(); 58 | validateObject(errors, type, "Specify a type."); 59 | 60 | if (type == User.Type.LOCAL && entity.json().containsKey(PASSWORD)) { 61 | // TODO: Add more pwd validation. 62 | validateString(errors, entity.getPassword(), 63 | "Specify a password with 8 or more alphanumeric characters", 8); 64 | } 65 | 66 | return errors; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/domain/validation/Validator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.domain.validation; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | import java.util.List; 22 | 23 | public interface Validator { 24 | 25 | String ERRORS = "errors"; 26 | 27 | List validate(JsonObject entity); 28 | 29 | List validateID(String id); 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/pipeline/Plugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.pipeline; 18 | 19 | import io.buildpal.core.pipeline.event.CommandKey; 20 | import io.buildpal.core.pipeline.event.EventKey; 21 | import io.vertx.core.AbstractVerticle; 22 | import io.vertx.core.Future; 23 | import io.vertx.core.Handler; 24 | import io.vertx.core.eventbus.EventBus; 25 | import io.vertx.core.eventbus.Message; 26 | import io.vertx.core.json.JsonObject; 27 | import io.vertx.core.logging.Logger; 28 | 29 | import java.util.Set; 30 | 31 | public abstract class Plugin extends AbstractVerticle { 32 | 33 | @Override 34 | public void start(Future startFuture) throws Exception { 35 | start(); 36 | 37 | EventBus eb = getVertx().eventBus(); 38 | 39 | for (CommandKey key : commandKeysToRegister()) { 40 | switch (key) { 41 | case SETUP: 42 | eb.localConsumer(key.getAddress(order()), setupHandler(eb)); 43 | break; 44 | 45 | case RUN_PHASE: 46 | eb.localConsumer(key.getAddress(order()), phaseHandler(eb)); 47 | break; 48 | 49 | case TEAR_DOWN: 50 | eb.localConsumer(key.getAddress(order()), tearDownHandler(eb)); 51 | break; 52 | } 53 | } 54 | 55 | starting(startFuture); 56 | } 57 | 58 | public abstract Set commandKeysToRegister(); 59 | 60 | public abstract Logger getLogger(); 61 | 62 | public int order() { 63 | return 100; 64 | } 65 | 66 | protected void starting(Future startFuture) throws Exception { 67 | startFuture.complete(); 68 | } 69 | 70 | protected Handler> setupHandler(EventBus eb) { 71 | return mh -> { 72 | getLogger().info(mh.body()); 73 | eb.send(EventKey.SETUP_END.getAddress(), mh.body()); 74 | }; 75 | } 76 | 77 | protected Handler> phaseHandler(EventBus eb) { 78 | return mh -> { 79 | getLogger().info(mh.body()); 80 | eb.send(EventKey.PHASE_END.getAddress(), mh.body()); 81 | }; 82 | } 83 | 84 | protected Handler> tearDownHandler(EventBus eb) { 85 | return mh -> { 86 | getLogger().info(mh.body()); 87 | eb.send(EventKey.TEAR_DOWN_END.getAddress(), mh.body()); 88 | }; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/pipeline/event/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.pipeline.event; 18 | 19 | import io.buildpal.core.domain.Build; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | import static io.buildpal.core.domain.Build.BUILD; 23 | 24 | public class Command extends Event { 25 | private static final String COMMAND_KEY = "commandKey"; 26 | private static final String SCRIPT = "script"; 27 | 28 | public Command() { 29 | super(); 30 | } 31 | 32 | public Command(JsonObject jsonObject) { 33 | super(jsonObject); 34 | } 35 | 36 | @Override 37 | public EventKey getKey() { 38 | return null; 39 | } 40 | 41 | public CommandKey getCommandKey() { 42 | Object key = jsonObject.getValue(COMMAND_KEY); 43 | 44 | if (key == null || key instanceof CommandKey) return (CommandKey) key; 45 | 46 | if (key instanceof String) return CommandKey.valueOf((String) key); 47 | 48 | throw new UnsupportedOperationException("The current value is not a valid command key."); 49 | } 50 | 51 | public Command setCommandKey(CommandKey key) { 52 | jsonObject.put(COMMAND_KEY, key); 53 | return this; 54 | } 55 | 56 | public Build getBuild() { 57 | JsonObject build = jsonObject.getJsonObject(BUILD); 58 | 59 | if (build == null) return null; 60 | 61 | return new Build(build); 62 | } 63 | 64 | public Command setBuild(Build build) { 65 | jsonObject.put(BUILD, build.json()); 66 | return this; 67 | } 68 | 69 | public String getScript() { 70 | return jsonObject.getString(SCRIPT); 71 | } 72 | 73 | public Command setScript(String script) { 74 | jsonObject.put(SCRIPT, script); 75 | return this; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/pipeline/event/CommandKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.pipeline.event; 18 | 19 | public enum CommandKey { 20 | SETUP("pipeline:setup:begin:"), 21 | RUN_PHASE("pipeline:phase:begin:"), 22 | TEAR_DOWN("pipeline:tearDown:begin:"); 23 | 24 | private String key; 25 | 26 | CommandKey(String key) { 27 | this.key = key; 28 | } 29 | 30 | public String getAddress(int order) { 31 | return key + order; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/pipeline/event/EventKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.pipeline.event; 18 | 19 | public enum EventKey { 20 | SETUP_END("pipeline:setup:end"), 21 | PHASE_UPDATE("pipeline:phase:update"), 22 | PHASE_END("pipeline:phase:end"), 23 | TEAR_DOWN_END("pipeline:tearDown:end"); 24 | 25 | private String address; 26 | 27 | EventKey(String address) { 28 | this.address = address; 29 | } 30 | 31 | public String getAddress() { 32 | return address; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/QueryEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query; 18 | 19 | import io.buildpal.core.query.sort.Sort; 20 | import io.buildpal.core.query.sort.Sorter; 21 | import io.vertx.core.json.JsonObject; 22 | import io.vertx.core.logging.Logger; 23 | import io.vertx.core.logging.LoggerFactory; 24 | import org.antlr.v4.runtime.CharStream; 25 | import org.antlr.v4.runtime.CharStreams; 26 | import org.antlr.v4.runtime.CommonTokenStream; 27 | import org.antlr.v4.runtime.tree.ParseTree; 28 | import org.apache.commons.lang3.StringUtils; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | public class QueryEngine { 34 | private static final Logger logger = LoggerFactory.getLogger(QueryEngine.class); 35 | 36 | public static List run(QuerySpec querySpec, List items) { 37 | if (querySpec == null || items == null || items.isEmpty()) return items; 38 | 39 | List filteredItems; 40 | 41 | // Filter items based on the query. 42 | if (StringUtils.isNotBlank(querySpec.getQuery())) { 43 | filteredItems = new ArrayList<>(); 44 | 45 | CharStream stream = CharStreams.fromString(querySpec.getQuery().trim()); 46 | QueryLexer lexer = new QueryLexer(stream); 47 | CommonTokenStream tokens = new CommonTokenStream(lexer); 48 | QueryParser parser = new QueryParser(tokens); 49 | 50 | ParseTree parseTree = parser.filter(); 51 | QueryEvaluator evaluator = new QueryEvaluator(); 52 | 53 | // Loop through the list and evaluate the query. 54 | for (JsonObject item : items) { 55 | if (evaluator.setCurrentItem(item).visit(parseTree)) { 56 | filteredItems.add(item); 57 | } 58 | } 59 | 60 | } else { 61 | filteredItems = items; 62 | } 63 | 64 | sort(querySpec, filteredItems); 65 | 66 | return paginate(querySpec, filteredItems); 67 | } 68 | 69 | private static void sort(QuerySpec querySpec, List items) { 70 | if (items == null || items.isEmpty()) return; 71 | 72 | List sorts = querySpec.getSorts(); 73 | 74 | if (sorts.isEmpty()) return; 75 | 76 | items.sort(new Sorter(sorts, items.get(0)).comparator()); 77 | } 78 | 79 | private static List paginate(QuerySpec querySpec, List items) { 80 | if (!querySpec.shouldPaginate()) return items; 81 | 82 | int begin = querySpec.begin(); 83 | int end = querySpec.end(); 84 | 85 | List pageOfItems = new ArrayList<>(); 86 | 87 | if (end > items.size()) end = items.size(); 88 | 89 | if (items.size() < begin) return pageOfItems; 90 | 91 | for (int i=begin; i NO_SORTS = Collections.emptyList(); 30 | 31 | private static final String QUERY = "q"; 32 | private static final String PAGE = "page"; 33 | private static final String LIMIT = "limit"; 34 | private static final String SORT = "sort"; 35 | 36 | private MultiMap multiMap; 37 | 38 | private Integer begin; 39 | private Integer end; 40 | 41 | public QuerySpec() { 42 | this(new CaseInsensitiveHeaders()); 43 | } 44 | 45 | public QuerySpec(MultiMap multiMap) { 46 | this.multiMap = multiMap; 47 | } 48 | 49 | public int getPage() { 50 | return multiMap.contains(PAGE) ? getInteger(multiMap.get(PAGE)) : -1; 51 | } 52 | 53 | public QuerySpec setPage(int page) { 54 | multiMap.set(PAGE, String.valueOf(page)); 55 | begin = end = null; 56 | 57 | return this; 58 | } 59 | 60 | public int getLimit() { 61 | return multiMap.contains(LIMIT) ? getInteger(multiMap.get(LIMIT)) : -1; 62 | } 63 | 64 | public QuerySpec setLimit(int limit) { 65 | multiMap.set(LIMIT, String.valueOf(limit)); 66 | begin = end = null; 67 | 68 | return this; 69 | } 70 | 71 | public String getQuery() { 72 | return multiMap.get(QUERY); 73 | } 74 | 75 | public QuerySpec setQuery(String query) { 76 | multiMap.set(QUERY, query); 77 | 78 | return this; 79 | } 80 | 81 | public List getSorts() { 82 | if (multiMap.contains(SORT)) { 83 | 84 | List sorts = new ArrayList<>(); 85 | List rawSorts = multiMap.getAll(SORT); 86 | 87 | rawSorts.forEach(s -> { 88 | Sort sort = Sort.tryParse(s); 89 | 90 | if (sort != null) sorts.add(sort); 91 | }); 92 | 93 | return sorts; 94 | 95 | } else { 96 | return NO_SORTS; 97 | } 98 | } 99 | 100 | boolean shouldPaginate() { 101 | return getPage() > 0 && getLimit() > 0; 102 | } 103 | 104 | int begin() { 105 | return begin == null ? (getPage() - 1) * getLimit() : begin; 106 | } 107 | 108 | int end() { 109 | return end == null ? begin() + getLimit() : end; 110 | } 111 | 112 | private static int getInteger(Object value) { 113 | if (value instanceof Integer) { 114 | return (Integer) value; 115 | 116 | } else { 117 | try { 118 | return Integer.parseInt((String) value); 119 | 120 | } catch (Exception ex) { 121 | return -1; 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operand/Operand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operand; 18 | 19 | import java.time.Instant; 20 | 21 | import static java.time.format.DateTimeFormatter.ISO_INSTANT; 22 | 23 | public class Operand { 24 | 25 | private Object value; 26 | private String strValue; 27 | private Long longValue; 28 | private Double doubleValue; 29 | private Boolean boolValue; 30 | private Instant instantValue; 31 | 32 | public Operand() { 33 | reset(); 34 | } 35 | 36 | public String getStrValue() { 37 | return strValue; 38 | } 39 | 40 | public Operand setStrValue(String strValue) { 41 | reset(); 42 | this.strValue = strValue; 43 | 44 | return this; 45 | } 46 | 47 | public Long getLongValue() { 48 | return longValue; 49 | } 50 | 51 | public Operand setLongValue(Long longValue) { 52 | reset(); 53 | this.longValue = longValue; 54 | 55 | return this; 56 | } 57 | 58 | public Double getDoubleValue() { 59 | return doubleValue; 60 | } 61 | 62 | public Operand setDoubleValue(Double doubleValue) { 63 | reset(); 64 | this.doubleValue = doubleValue; 65 | 66 | return this; 67 | } 68 | 69 | public Boolean getBoolValue() { 70 | return boolValue; 71 | } 72 | 73 | public Operand setBoolValue(Boolean boolValue) { 74 | reset(); 75 | this.boolValue = boolValue; 76 | return this; 77 | } 78 | 79 | public Instant getInstantValue() { 80 | return instantValue; 81 | } 82 | 83 | public Operand setInstantValue(Instant instantValue) { 84 | reset(); 85 | this.instantValue = instantValue; 86 | 87 | return this; 88 | } 89 | 90 | public Object getValue() { 91 | return value; 92 | } 93 | 94 | public Operand setValue(Object value) { 95 | reset(); 96 | this.value = value; 97 | 98 | return this; 99 | } 100 | 101 | public Long toLong() { 102 | if (getValue() instanceof Long) { 103 | return (Long) getValue(); 104 | 105 | } else if (getValue() instanceof Double) { 106 | return ((Double) getValue()).longValue(); 107 | 108 | } else if (getValue() instanceof Integer) { 109 | return ((Integer) getValue()).longValue(); 110 | } 111 | 112 | return null; 113 | } 114 | 115 | public Double toDouble() { 116 | if (getValue() instanceof Double) { 117 | return (Double) getValue(); 118 | 119 | } else if (getValue() instanceof Long) { 120 | return ((Long) getValue()).doubleValue(); 121 | 122 | } else if (getValue() instanceof Integer) { 123 | return ((Integer) getValue()).doubleValue(); 124 | } 125 | 126 | return null; 127 | } 128 | 129 | public Instant toInstant() { 130 | return Instant.from(ISO_INSTANT.parse(getValue().toString())); 131 | } 132 | 133 | private void reset() { 134 | value = null; 135 | strValue = null; 136 | longValue = null; 137 | doubleValue = null; 138 | boolValue = null; 139 | instantValue = null; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/BooleanOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public class BooleanOperation implements Operation { 22 | 23 | private BooleanOperation() {} 24 | 25 | public static final BooleanOperation SELF = new BooleanOperation(); 26 | 27 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 28 | return leftOperand.getValue() == rightOperand.getBoolValue(); 29 | } 30 | 31 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 32 | return leftOperand.getValue() != rightOperand.getBoolValue(); 33 | } 34 | 35 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 36 | throw new UnsupportedOperationException("gt is not a supported operator on booleans."); 37 | } 38 | 39 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 40 | throw new UnsupportedOperationException("lt is not a supported operator on booleans."); 41 | } 42 | 43 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 44 | throw new UnsupportedOperationException("ge is not a supported operator on booleans."); 45 | } 46 | 47 | public Boolean le(Operand leftOperand, Operand rightOperand) { 48 | throw new UnsupportedOperationException("le is not a supported operator on booleans."); 49 | } 50 | 51 | public Boolean co(Operand leftOperand, Operand rightOperand) { 52 | throw new UnsupportedOperationException("co is not a supported operator on booleans."); 53 | } 54 | 55 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 56 | throw new UnsupportedOperationException("sw is not a supported operator on booleans."); 57 | } 58 | 59 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 60 | throw new UnsupportedOperationException("ew is not a supported operator on booleans."); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/DoubleOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public class DoubleOperation implements Operation { 22 | 23 | private DoubleOperation() {} 24 | 25 | public static final DoubleOperation SELF = new DoubleOperation(); 26 | 27 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 28 | if (leftOperand.getValue() == null) return false; 29 | 30 | return leftOperand.toDouble().equals(rightOperand.getDoubleValue()); 31 | } 32 | 33 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 34 | if (leftOperand.getValue() == null) return false; 35 | 36 | return !leftOperand.toDouble().equals(rightOperand.getDoubleValue()); 37 | } 38 | 39 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 40 | if (leftOperand.getValue() == null) return false; 41 | 42 | return leftOperand.toDouble() > rightOperand.getDoubleValue(); 43 | } 44 | 45 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 46 | if (leftOperand.getValue() == null) return false; 47 | 48 | return leftOperand.toDouble() < rightOperand.getDoubleValue(); 49 | } 50 | 51 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 52 | if (leftOperand.getValue() == null) return false; 53 | 54 | return leftOperand.toDouble() >= rightOperand.getDoubleValue(); 55 | } 56 | 57 | public Boolean le(Operand leftOperand, Operand rightOperand) { 58 | if (leftOperand.getValue() == null) return false; 59 | 60 | return leftOperand.toDouble() <= rightOperand.getDoubleValue(); 61 | } 62 | 63 | public Boolean co(Operand leftOperand, Operand rightOperand) { 64 | throw new UnsupportedOperationException("co is not a supported operator on double."); 65 | } 66 | 67 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 68 | throw new UnsupportedOperationException("sw is not a supported operator on double."); 69 | } 70 | 71 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 72 | throw new UnsupportedOperationException("ew is not a supported operator on double."); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/InstantOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | import java.time.Instant; 22 | 23 | public class InstantOperation implements Operation { 24 | 25 | private InstantOperation() {} 26 | 27 | public static final InstantOperation SELF = new InstantOperation(); 28 | 29 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 30 | if (leftOperand.getValue() == null) return false; 31 | 32 | return leftOperand.toInstant().equals(rightOperand.getInstantValue()); 33 | } 34 | 35 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 36 | if (leftOperand.getValue() == null) return false; 37 | 38 | return !leftOperand.toInstant().equals(rightOperand.getInstantValue()); 39 | } 40 | 41 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 42 | if (leftOperand.getValue() == null) return false; 43 | 44 | return leftOperand.toInstant().isAfter(rightOperand.getInstantValue()); 45 | } 46 | 47 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 48 | if (leftOperand.getValue() == null) return false; 49 | 50 | return leftOperand.toInstant().isBefore(rightOperand.getInstantValue()); 51 | } 52 | 53 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 54 | if (leftOperand.getValue() == null) return false; 55 | 56 | Instant left = leftOperand.toInstant(); 57 | 58 | boolean isEqual = left.equals(rightOperand.getInstantValue()); 59 | 60 | return isEqual || left.isAfter(rightOperand.getInstantValue()); 61 | } 62 | 63 | public Boolean le(Operand leftOperand, Operand rightOperand) { 64 | if (leftOperand.getValue() == null) return false; 65 | 66 | Instant left = leftOperand.toInstant(); 67 | 68 | boolean isEqual = left.equals(rightOperand.getInstantValue()); 69 | 70 | return isEqual || left.isBefore(rightOperand.getInstantValue()); 71 | } 72 | 73 | public Boolean co(Operand leftOperand, Operand rightOperand) { 74 | throw new UnsupportedOperationException("co is not a supported operator on instant."); 75 | } 76 | 77 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 78 | throw new UnsupportedOperationException("sw is not a supported operator on instant."); 79 | } 80 | 81 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 82 | throw new UnsupportedOperationException("ew is not a supported operator on instant."); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/LongOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public class LongOperation implements Operation { 22 | 23 | private LongOperation() {} 24 | 25 | public static final LongOperation SELF = new LongOperation(); 26 | 27 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 28 | if (leftOperand.getValue() == null) return false; 29 | 30 | return leftOperand.toLong().equals(rightOperand.getLongValue()); 31 | } 32 | 33 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 34 | if (leftOperand.getValue() == null) return false; 35 | 36 | return !leftOperand.toLong().equals(rightOperand.getLongValue()); 37 | } 38 | 39 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 40 | if (leftOperand.getValue() == null) return false; 41 | 42 | return leftOperand.toLong() > rightOperand.getLongValue(); 43 | } 44 | 45 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 46 | if (leftOperand.getValue() == null) return false; 47 | 48 | return leftOperand.toLong() < rightOperand.getLongValue(); 49 | } 50 | 51 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 52 | if (leftOperand.getValue() == null) return false; 53 | 54 | return leftOperand.toLong() >= rightOperand.getLongValue(); 55 | } 56 | 57 | public Boolean le(Operand leftOperand, Operand rightOperand) { 58 | if (leftOperand.getValue() == null) return false; 59 | 60 | return leftOperand.toLong() <= rightOperand.getLongValue(); 61 | } 62 | 63 | public Boolean co(Operand leftOperand, Operand rightOperand) { 64 | throw new UnsupportedOperationException("co is not a supported operator on long."); 65 | } 66 | 67 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 68 | throw new UnsupportedOperationException("sw is not a supported operator on long."); 69 | } 70 | 71 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 72 | throw new UnsupportedOperationException("ew is not a supported operator on long."); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/NullOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public class NullOperation implements Operation { 22 | 23 | private NullOperation() {} 24 | 25 | public static final NullOperation SELF = new NullOperation(); 26 | 27 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 28 | return leftOperand.getValue() == null; 29 | } 30 | 31 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 32 | return leftOperand.getValue() != null; 33 | } 34 | 35 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 36 | throw new UnsupportedOperationException("gt is not a supported operator on nulls."); 37 | } 38 | 39 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 40 | throw new UnsupportedOperationException("lt is not a supported operator on nulls."); 41 | } 42 | 43 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 44 | throw new UnsupportedOperationException("ge is not a supported operator on nulls."); 45 | } 46 | 47 | public Boolean le(Operand leftOperand, Operand rightOperand) { 48 | throw new UnsupportedOperationException("le is not a supported operator on nulls."); 49 | } 50 | 51 | public Boolean co(Operand leftOperand, Operand rightOperand) { 52 | throw new UnsupportedOperationException("co is not a supported operator on nulls."); 53 | } 54 | 55 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 56 | throw new UnsupportedOperationException("sw is not a supported operator on nulls."); 57 | } 58 | 59 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 60 | throw new UnsupportedOperationException("ew is not a supported operator on nulls."); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/Operation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public interface Operation { 22 | 23 | Boolean eq(Operand leftOperand, Operand rightOperand); 24 | 25 | Boolean ne(Operand leftOperand, Operand rightOperand); 26 | 27 | Boolean gt(Operand leftOperand, Operand rightOperand); 28 | 29 | Boolean lt(Operand leftOperand, Operand rightOperand); 30 | 31 | Boolean ge(Operand leftOperand, Operand rightOperand); 32 | 33 | Boolean le(Operand leftOperand, Operand rightOperand); 34 | 35 | Boolean co(Operand leftOperand, Operand rightOperand); 36 | 37 | Boolean sw(Operand leftOperand, Operand rightOperand); 38 | 39 | Boolean ew(Operand leftOperand, Operand rightOperand); 40 | } 41 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/operation/StringOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.operation; 18 | 19 | import io.buildpal.core.query.operand.Operand; 20 | 21 | public class StringOperation implements Operation { 22 | 23 | private StringOperation() {} 24 | 25 | public static final StringOperation SELF = new StringOperation(); 26 | 27 | public Boolean eq(Operand leftOperand, Operand rightOperand) { 28 | if (leftOperand.getValue() == null) return false; 29 | 30 | return ((String) leftOperand.getValue()).equalsIgnoreCase(rightOperand.getStrValue()); 31 | } 32 | 33 | public Boolean ne(Operand leftOperand, Operand rightOperand) { 34 | if (leftOperand.getValue() == null) return false; 35 | 36 | return !((String) leftOperand.getValue()).equalsIgnoreCase(rightOperand.getStrValue()); 37 | } 38 | 39 | public Boolean gt(Operand leftOperand, Operand rightOperand) { 40 | if (leftOperand.getValue() == null) return false; 41 | 42 | return ((String) leftOperand.getValue()).compareToIgnoreCase(rightOperand.getStrValue()) > 0; 43 | } 44 | 45 | public Boolean lt(Operand leftOperand, Operand rightOperand) { 46 | if (leftOperand.getValue() == null) return false; 47 | 48 | return ((String) leftOperand.getValue()).compareToIgnoreCase(rightOperand.getStrValue()) < 0; 49 | } 50 | 51 | public Boolean ge(Operand leftOperand, Operand rightOperand) { 52 | if (leftOperand.getValue() == null) return false; 53 | 54 | return ((String) leftOperand.getValue()).compareToIgnoreCase(rightOperand.getStrValue()) >= 0; 55 | } 56 | 57 | public Boolean le(Operand leftOperand, Operand rightOperand) { 58 | if (leftOperand.getValue() == null) return false; 59 | 60 | return ((String) leftOperand.getValue()).compareToIgnoreCase(rightOperand.getStrValue()) <= 0; 61 | } 62 | 63 | public Boolean co(Operand leftOperand, Operand rightOperand) { 64 | if (leftOperand.getValue() == null) return false; 65 | 66 | return ((String) leftOperand.getValue()).contains(rightOperand.getStrValue()); 67 | } 68 | 69 | public Boolean sw(Operand leftOperand, Operand rightOperand) { 70 | if (leftOperand.getValue() == null) return false; 71 | 72 | return ((String) leftOperand.getValue()).startsWith(rightOperand.getStrValue()); 73 | } 74 | 75 | public Boolean ew(Operand leftOperand, Operand rightOperand) { 76 | if (leftOperand.getValue() == null) return false; 77 | 78 | return ((String) leftOperand.getValue()).endsWith(rightOperand.getStrValue()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/sort/Sort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.sort; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | import org.apache.commons.lang3.StringUtils; 21 | 22 | import java.time.Instant; 23 | import java.util.Objects; 24 | 25 | import static io.buildpal.core.config.Constants.PIPE; 26 | import static org.apache.commons.lang3.StringUtils.EMPTY; 27 | 28 | public class Sort { 29 | public enum Direction { 30 | ASC, 31 | DESC 32 | } 33 | 34 | public enum Type { 35 | DYNAMIC, 36 | INSTANT 37 | } 38 | 39 | private final String key; 40 | private final Direction direction; 41 | private final Type type; 42 | 43 | Sort(String key, Direction direction, Type type) { 44 | this.key = Objects.requireNonNull(key); 45 | this.direction = direction; 46 | this.type = type; 47 | } 48 | 49 | public String key() { 50 | return key; 51 | } 52 | 53 | public Direction dir() { 54 | return direction; 55 | } 56 | 57 | public Type type() { 58 | return type; 59 | } 60 | 61 | public static Sort tryParse(String sort) { 62 | try { 63 | String[] splits = sort.split(PIPE); 64 | 65 | String key = StringUtils.isNotBlank(splits[0]) ? splits[0].trim() : null; 66 | Direction dir = Direction.ASC; 67 | Type type = Type.DYNAMIC; 68 | 69 | if (splits.length > 1) { 70 | dir = Direction.valueOf(splits[1].trim().toUpperCase()); 71 | } 72 | 73 | if (splits.length == 3) { 74 | type = Type.valueOf(splits[2].trim().toUpperCase()); 75 | } 76 | 77 | return new Sort(key, dir, type); 78 | 79 | } catch (Exception ex) { 80 | return null; 81 | } 82 | } 83 | 84 | @FunctionalInterface 85 | public interface Comparer { 86 | int compare(String key, JsonObject jo1, JsonObject jo2); 87 | } 88 | 89 | public static class NoCompare implements Comparer { 90 | @Override 91 | public int compare(String key, JsonObject jo1, JsonObject jo2) { 92 | return 0; 93 | } 94 | } 95 | 96 | public static class StringCompare implements Comparer { 97 | @Override 98 | public int compare(String key, JsonObject jo1, JsonObject jo2) { 99 | return jo1.getString(key, EMPTY).compareTo(jo2.getString(key, EMPTY)); 100 | } 101 | } 102 | 103 | public static class LongCompare implements Comparer { 104 | @Override 105 | public int compare(String key, JsonObject jo1, JsonObject jo2) { 106 | return jo1.getLong(key, 0L).compareTo(jo2.getLong(key, 0L)); 107 | } 108 | } 109 | 110 | public static class InstantCompare implements Comparer { 111 | @Override 112 | public int compare(String key, JsonObject jo1, JsonObject jo2) { 113 | return jo1.getInstant(key, Instant.MIN).compareTo(jo2.getInstant(key, Instant.MIN)); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/query/sort/Sorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.query.sort; 18 | 19 | import io.vertx.core.json.JsonObject; 20 | 21 | import java.time.Instant; 22 | import java.util.Comparator; 23 | import java.util.List; 24 | import java.util.function.Function; 25 | 26 | import static org.apache.commons.lang3.StringUtils.EMPTY; 27 | 28 | public class Sorter { 29 | 30 | private Comparator comparator; 31 | 32 | public Sorter(List sorts, JsonObject sample) { 33 | 34 | comparator = null; 35 | 36 | for (Sort sort : sorts) { 37 | comparator = addComparator(comparator, sample, sort); 38 | 39 | if (sort.dir() == Sort.Direction.DESC) { 40 | comparator = comparator.reversed(); 41 | } 42 | } 43 | } 44 | 45 | public Comparator comparator() { 46 | return comparator; 47 | } 48 | 49 | private Comparator addComparator(Comparator comparator, JsonObject sample, Sort sort) { 50 | String key = sort.key(); 51 | Object value = sample.getValue(key); 52 | 53 | if (value instanceof String) { 54 | if (sort.type() == Sort.Type.INSTANT) { 55 | if (comparator == null) { 56 | return Comparator.comparing(instantExtractor(key)); 57 | 58 | } else { 59 | return comparator.thenComparing(instantExtractor(key)); 60 | } 61 | 62 | } else { 63 | if (comparator == null) { 64 | return Comparator.comparing(stringExtractor(key)); 65 | 66 | } else { 67 | return comparator.thenComparing(stringExtractor(key)); 68 | } 69 | } 70 | 71 | } 72 | 73 | if (value instanceof Integer) { 74 | if (comparator == null) { 75 | return Comparator.comparing(integerExtractor(key)); 76 | 77 | } else { 78 | return comparator.thenComparing(integerExtractor(key)); 79 | } 80 | } 81 | 82 | if (value instanceof Long) { 83 | if (comparator == null) { 84 | return Comparator.comparing(longExtractor(key)); 85 | 86 | } else { 87 | return comparator.thenComparing(longExtractor(key)); 88 | } 89 | } 90 | 91 | if (value instanceof Double) { 92 | if (comparator == null) { 93 | return Comparator.comparing(doubleExtractor(key)); 94 | 95 | } else { 96 | return comparator.thenComparing(doubleExtractor(key)); 97 | } 98 | } 99 | 100 | if (comparator == null) { 101 | return Comparator.comparing(noExtractor()); 102 | 103 | } else { 104 | return comparator.thenComparing(noExtractor()); 105 | } 106 | } 107 | 108 | private Function noExtractor() { 109 | return jo -> 0; 110 | } 111 | 112 | private Function stringExtractor(String key) { 113 | return jo -> jo.getString(key, EMPTY); 114 | } 115 | 116 | private Function integerExtractor(String key) { 117 | return jo -> jo.getInteger(key, 0); 118 | } 119 | 120 | private Function longExtractor(String key) { 121 | return jo -> jo.getLong(key, 0L); 122 | } 123 | 124 | private Function doubleExtractor(String key) { 125 | return jo -> jo.getDouble(key, 0D); 126 | } 127 | 128 | private Function instantExtractor(String key) { 129 | return jo -> jo.getInstant(key, Instant.MIN); 130 | } 131 | } 132 | 133 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/util/DataUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.util; 18 | 19 | import io.buildpal.core.domain.DataItem; 20 | import io.vertx.core.json.JsonObject; 21 | import org.apache.commons.lang3.StringUtils; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class DataUtils { 27 | 28 | public static String eval(String statement, JsonObject data) { 29 | for (String key : data.getMap().keySet()) { 30 | DataItem dataItem = new DataItem(data.getJsonObject(key)); 31 | 32 | statement = eval(statement, dataItem); 33 | } 34 | 35 | return statement; 36 | } 37 | 38 | public static String eval(String statement, DataItem dataItem) { 39 | return StringUtils.replace(statement, dataItem.key(), dataItem.value()); 40 | } 41 | 42 | public static List parseIntList(String value) { 43 | List integers = new ArrayList<>(); 44 | 45 | if (StringUtils.isNotBlank(value)) { 46 | for (String splitVal : value.split(",")) { 47 | splitVal = splitVal.trim(); 48 | 49 | if (StringUtils.isNotBlank(splitVal)) { 50 | integers.add(Integer.parseInt(splitVal)); 51 | } 52 | } 53 | } 54 | 55 | return integers; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/io/buildpal/core/util/ResultUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.util; 18 | 19 | import io.buildpal.core.domain.Entity; 20 | import io.vertx.core.AsyncResult; 21 | import io.vertx.core.eventbus.Message; 22 | import io.vertx.core.json.JsonArray; 23 | import io.vertx.core.json.JsonObject; 24 | 25 | import java.util.List; 26 | 27 | import static io.buildpal.core.config.Constants.ITEM; 28 | import static io.buildpal.core.config.Constants.ITEMS; 29 | import static io.buildpal.core.domain.validation.Validator.ERRORS; 30 | 31 | public class ResultUtils { 32 | private static final String IDs = "ids"; 33 | 34 | public static boolean failed(AsyncResult r) { 35 | return r.failed() || 36 | (r.result().containsKey(ERRORS) && 37 | r.result().getJsonArray(ERRORS).size() > 0); 38 | } 39 | 40 | public static boolean msgFailed(AsyncResult> r) { 41 | return r.failed() || 42 | (r.result().body().containsKey(ERRORS) && 43 | r.result().body().getJsonArray(ERRORS).size() > 0); 44 | } 45 | 46 | public static boolean failed(JsonObject result) { 47 | return result.containsKey(ERRORS) && result.getJsonArray(ERRORS).size() > 0; 48 | } 49 | 50 | public static JsonObject newEntity(String id) { 51 | return new JsonObject().put(Entity.ID, id); 52 | } 53 | 54 | public static JsonObject newEntity(List ids) { 55 | return new JsonObject().put(IDs, ids); 56 | } 57 | 58 | public static JsonObject item(JsonObject result) { 59 | return result.getJsonObject(ITEM); 60 | } 61 | 62 | public static JsonObject prepareResult(JsonObject item) { 63 | return putEntity(newResult(), item); 64 | } 65 | 66 | public static JsonObject newResult() { 67 | return new JsonObject().put(ERRORS, new JsonArray()); 68 | } 69 | 70 | public static JsonObject newResult(List errors) { 71 | return new JsonObject().put(ERRORS, new JsonArray(errors)); 72 | } 73 | 74 | public static JsonObject newResult(JsonObject jsonObject) { 75 | return new JsonObject(jsonObject.getMap()).put(ERRORS, new JsonArray()); 76 | } 77 | 78 | public static JsonObject putEntity(JsonObject result, String entity) { 79 | return putEntity(result, entity != null ? new JsonObject(entity) : null); 80 | } 81 | 82 | public static JsonObject putEntity(JsonObject result, JsonObject entity) { 83 | if (entity != null) { 84 | result.put(ITEM, entity); 85 | 86 | } else { 87 | result.getJsonArray(ERRORS).add("Entity not found."); 88 | } 89 | 90 | return result; 91 | } 92 | 93 | public static JsonObject getEntity(JsonObject result) { 94 | return result.getJsonObject(ITEM); 95 | } 96 | 97 | public static JsonObject addEntities(JsonObject result, List entities) { 98 | return result.put(ITEMS, entities); 99 | } 100 | 101 | @SuppressWarnings("unchecked") 102 | public static List getEntities(JsonObject jsonObject) { 103 | return (List) jsonObject.getJsonArray(ITEMS).getList(); 104 | } 105 | 106 | @SuppressWarnings("unchecked") 107 | public static List getIDs(JsonObject jsonObject) { 108 | return (List) jsonObject.getJsonArray(IDs).getList(); 109 | } 110 | 111 | public static JsonObject addError(JsonObject result, String error) { 112 | result.getJsonArray(ERRORS).add(error); 113 | return result; 114 | } 115 | 116 | public static boolean hasError(JsonObject result, String error) { 117 | if (result.containsKey(ERRORS)) { 118 | JsonArray errors = result.getJsonArray(ERRORS); 119 | 120 | for (int e=0; e Future future(Handler> handler) { 36 | Future future = Future.future(); 37 | future.setHandler(handler); 38 | 39 | return future; 40 | } 41 | 42 | public static void deployVerticles(Vertx vertx, 43 | List verticles, 44 | JsonObject config, 45 | Handler> handler) { 46 | 47 | List futures = new ArrayList<>(); 48 | 49 | for (Verticle verticle : verticles) { 50 | futures.add(deploy(vertx, verticle.getClass().getName(), new DeploymentOptions().setConfig(config))); 51 | } 52 | 53 | CompositeFuture.all(futures).setHandler(handler); 54 | } 55 | 56 | private static Future deploy(Vertx vertx, String name, DeploymentOptions options) { 57 | Future deployFuture = Future.future(); 58 | 59 | vertx.deployVerticle(name, options, dh -> { 60 | if (dh.succeeded()) { 61 | deployFuture.complete(dh.result()); 62 | 63 | } else { 64 | deployFuture.fail(dh.cause()); 65 | } 66 | }); 67 | 68 | return deployFuture; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /core/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.core { 18 | exports io.buildpal.core.config; 19 | exports io.buildpal.core.domain; 20 | exports io.buildpal.core.domain.builder; 21 | exports io.buildpal.core.domain.validation; 22 | exports io.buildpal.core.pipeline; 23 | exports io.buildpal.core.pipeline.event; 24 | exports io.buildpal.core.process; 25 | exports io.buildpal.core.util; 26 | exports io.buildpal.core.query; 27 | 28 | requires vertx.core; 29 | 30 | requires org.apache.commons.lang3; 31 | 32 | requires antlr4.runtime; 33 | } -------------------------------------------------------------------------------- /core/src/test/java/io/buildpal/core/util/DataUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.util; 18 | 19 | import io.buildpal.core.domain.DataItem; 20 | import io.vertx.core.json.JsonObject; 21 | import org.junit.Assert; 22 | import org.junit.Test; 23 | 24 | public class DataUtilsTest { 25 | 26 | @Test 27 | public void evalTest() { 28 | DataItem dataItem = new DataItem() 29 | .setID("SHELVED_LIST") 30 | .setType(DataItem.Type.STRING) 31 | .setValue("100"); 32 | 33 | JsonObject data = new JsonObject().put(dataItem.getID(), dataItem.json()); 34 | 35 | String shelvedList = DataUtils.eval("${data.SHELVED_LIST}", data); 36 | 37 | Assert.assertEquals("Data evaluation for ${data.SHELVED_LIST} should be set to 100", 38 | "100", shelvedList); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/test/java/io/buildpal/core/util/FileUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.core.util; 18 | 19 | import org.junit.Assert; 20 | import org.junit.Test; 21 | 22 | import java.io.File; 23 | 24 | public class FileUtilsTest { 25 | @Test 26 | public void extensionTest() { 27 | Assert.assertEquals("Extension should be 'js'.", 28 | ".js", FileUtils.extension(new File("/buildpal/core/util/script.js").toPath())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /db/build.gradle: -------------------------------------------------------------------------------- 1 | javaModule.name = "io.buildpal.db" 2 | 3 | dependencies { 4 | implementation "org.apache.commons:commons-lang3:$commonsLangVersion" 5 | 6 | api project(":auth") 7 | api project(":core") 8 | } 9 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/DbManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db; 18 | 19 | import io.buildpal.core.query.QuerySpec; 20 | import io.vertx.core.AsyncResult; 21 | import io.vertx.core.Handler; 22 | import io.vertx.core.json.JsonObject; 23 | 24 | import java.util.List; 25 | 26 | public interface DbManager { 27 | String getCollectionName(); 28 | 29 | void init(JsonObject config, Handler> handler); 30 | 31 | JsonObject get(String id); 32 | 33 | void get(String id, Handler> handler); 34 | 35 | void getGraph(String id, Handler> handler); 36 | 37 | void add(JsonObject entity, Handler> handler); 38 | 39 | void replace(JsonObject entity, Handler> handler); 40 | 41 | void delete(String id, Handler> handler); 42 | 43 | void find(QuerySpec querySpec, Handler> handler); 44 | 45 | List list(); 46 | } 47 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/DbManagers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db; 18 | 19 | import io.buildpal.core.domain.validation.BuildValidator; 20 | import io.buildpal.core.domain.validation.PipelineValidator; 21 | import io.buildpal.core.domain.validation.ProjectValidator; 22 | import io.buildpal.core.domain.validation.RepositoryValidator; 23 | import io.buildpal.core.domain.validation.SecretValidator; 24 | import io.buildpal.core.domain.validation.UserValidator; 25 | import io.buildpal.db.file.BuildManager; 26 | import io.buildpal.db.file.PipelineManager; 27 | import io.buildpal.db.file.ProjectManager; 28 | import io.buildpal.db.file.RepositoryManager; 29 | import io.buildpal.db.file.SecretManager; 30 | import io.buildpal.db.file.UserManager; 31 | import io.vertx.core.Vertx; 32 | import io.vertx.core.json.JsonObject; 33 | 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | public class DbManagers { 38 | private final List managers; 39 | 40 | private final UserManager userManager; 41 | private final ProjectManager projectManager; 42 | private final RepositoryManager repositoryManager; 43 | private final PipelineManager pipelineManager; 44 | private final BuildManager buildManager; 45 | private final SecretManager secretManager; 46 | 47 | public DbManagers(Vertx vertx, JsonObject config) { 48 | managers = new ArrayList<>(); 49 | 50 | userManager = new UserManager(vertx, config, new UserValidator()); 51 | managers.add(userManager); 52 | 53 | projectManager = new ProjectManager(vertx, config, new ProjectValidator()); 54 | managers.add(projectManager); 55 | 56 | secretManager = new SecretManager(vertx, config, new SecretValidator()); 57 | managers.add(secretManager); 58 | 59 | repositoryManager = new RepositoryManager(vertx, config, new RepositoryValidator(), secretManager); 60 | managers.add(repositoryManager); 61 | 62 | pipelineManager = new PipelineManager(vertx, config, new PipelineValidator(), 63 | repositoryManager); 64 | managers.add(pipelineManager); 65 | 66 | buildManager = new BuildManager(vertx, config, new BuildValidator()); 67 | managers.add(buildManager); 68 | } 69 | 70 | public UserManager getUserManager() { 71 | return userManager; 72 | } 73 | 74 | public ProjectManager getProjectManager() { 75 | return projectManager; 76 | } 77 | 78 | public SecretManager getSecretManager() { 79 | return secretManager; 80 | } 81 | 82 | public RepositoryManager getRepositoryManager() { 83 | return repositoryManager; 84 | } 85 | 86 | public PipelineManager getPipelineManager() { 87 | return pipelineManager; 88 | } 89 | 90 | public BuildManager getBuildManager() { 91 | return buildManager; 92 | } 93 | 94 | public List getManagers() { 95 | return managers; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/file/BuildManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db.file; 18 | 19 | import io.buildpal.core.domain.validation.Validator; 20 | import io.vertx.core.Vertx; 21 | import io.vertx.core.json.JsonObject; 22 | import io.vertx.core.logging.Logger; 23 | import io.vertx.core.logging.LoggerFactory; 24 | 25 | public class BuildManager extends FileDbManager { 26 | private static final Logger logger = LoggerFactory.getLogger(BuildManager.class); 27 | 28 | public BuildManager(Vertx vertx, JsonObject config, Validator validator) { 29 | super(vertx, logger, config, validator); 30 | } 31 | 32 | @Override 33 | public String getCollectionName() { 34 | return "builds"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/file/ProjectManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db.file; 18 | 19 | import io.buildpal.core.domain.validation.Validator; 20 | import io.vertx.core.Vertx; 21 | import io.vertx.core.json.JsonObject; 22 | import io.vertx.core.logging.Logger; 23 | import io.vertx.core.logging.LoggerFactory; 24 | 25 | public class ProjectManager extends FileDbManager { 26 | private static final Logger logger = LoggerFactory.getLogger(ProjectManager.class); 27 | 28 | public ProjectManager(Vertx vertx, JsonObject config, Validator validator) { 29 | super(vertx, logger, config, validator); 30 | } 31 | 32 | @Override 33 | public String getCollectionName() { 34 | return "projects"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/file/RepositoryManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db.file; 18 | 19 | import io.buildpal.core.domain.Repository; 20 | import io.buildpal.core.domain.validation.Validator; 21 | import io.vertx.core.Vertx; 22 | import io.vertx.core.json.JsonObject; 23 | import io.vertx.core.logging.Logger; 24 | import io.vertx.core.logging.LoggerFactory; 25 | import org.apache.commons.lang3.StringUtils; 26 | 27 | import static io.buildpal.core.domain.Repository.SECRET_ID; 28 | import static io.buildpal.core.util.ResultUtils.addError; 29 | import static io.buildpal.core.util.ResultUtils.failed; 30 | import static io.buildpal.core.util.ResultUtils.newResult; 31 | 32 | public class RepositoryManager extends FileDbManager { 33 | private static final Logger logger = LoggerFactory.getLogger(RepositoryManager.class); 34 | 35 | private final SecretManager secretManager; 36 | 37 | public RepositoryManager(Vertx vertx, JsonObject config, Validator validator, SecretManager secretManager) { 38 | super(vertx, logger, config, validator); 39 | 40 | this.secretManager = secretManager; 41 | } 42 | 43 | @Override 44 | public String getCollectionName() { 45 | return "repositories"; 46 | } 47 | 48 | @Override 49 | JsonObject getGraph(String id) { 50 | JsonObject entity = get(id); 51 | 52 | if (entity != null) { 53 | Repository repository = new Repository(entity); 54 | 55 | if (StringUtils.isNotBlank(repository.getSecretID())) { 56 | repository.setSecret(secretManager.get(repository.getSecretID())); 57 | } 58 | 59 | return repository.json(); 60 | } 61 | 62 | return null; 63 | } 64 | 65 | @Override 66 | JsonObject validateEntity(JsonObject entity) { 67 | JsonObject result = newResult(validator.validate(entity)); 68 | 69 | // No validation errors so far. Now, check for secret. 70 | if (!failed(result)) { 71 | 72 | if (entity.containsKey(SECRET_ID) && 73 | secretManager.get(entity.getString(SECRET_ID)) == null) { 74 | addError(result, "System cannot find the specified credentials."); 75 | } 76 | } 77 | 78 | return result; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/file/SecretManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db.file; 18 | 19 | import io.buildpal.auth.vault.VaultService; 20 | import io.buildpal.core.domain.validation.Validator; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Future; 23 | import io.vertx.core.Handler; 24 | import io.vertx.core.Vertx; 25 | import io.vertx.core.json.JsonObject; 26 | import io.vertx.core.logging.Logger; 27 | import io.vertx.core.logging.LoggerFactory; 28 | 29 | import static io.buildpal.core.domain.Entity.CREATED_BY; 30 | import static io.buildpal.core.domain.Entity.DESC; 31 | import static io.buildpal.core.domain.Entity.ID; 32 | import static io.buildpal.core.domain.Entity.LAST_MODIFIED_BY; 33 | import static io.buildpal.core.domain.Entity.NAME; 34 | import static io.buildpal.core.domain.Entity.UTC_CREATED_DATE; 35 | import static io.buildpal.core.domain.Entity.UTC_LAST_MODIFIED_DATE; 36 | import static io.buildpal.core.util.ResultUtils.addError; 37 | import static io.buildpal.core.util.ResultUtils.failed; 38 | import static io.buildpal.core.util.ResultUtils.newResult; 39 | import static io.buildpal.core.util.ResultUtils.putEntity; 40 | import static io.buildpal.core.util.VertxUtils.future; 41 | 42 | public class SecretManager extends FileDbManager { 43 | private static final Logger logger = LoggerFactory.getLogger(SecretManager.class); 44 | 45 | private final VaultService vaultService; 46 | 47 | public SecretManager(Vertx vertx, JsonObject config, Validator validator) { 48 | super(vertx, logger, config, validator); 49 | 50 | vaultService = new VaultService(vertx); 51 | } 52 | 53 | @Override 54 | public String getCollectionName() { 55 | return "secrets"; 56 | } 57 | 58 | @Override 59 | public void getGraph(String id, Handler> handler) { 60 | Future future = future(handler); 61 | JsonObject result = newResult(validator.validateID(id)); 62 | 63 | if (!failed(result)) { 64 | 65 | JsonObject secret = collectionMap.get(id); 66 | 67 | if (secret != null) { 68 | vaultService.retrieve(secret.getString(NAME), rh -> { 69 | if (rh.succeeded()) { 70 | putEntity(result, rh.result()); 71 | 72 | } else { 73 | String message = "Failed to retrieve secret: " + secret; 74 | addError(result, message); 75 | logger.error(message, rh.cause()); 76 | } 77 | 78 | future.complete(result); 79 | }); 80 | 81 | } else { 82 | putEntity(result, secret); 83 | future.complete(result); 84 | } 85 | 86 | } else { 87 | future.complete(result); 88 | } 89 | } 90 | 91 | @Override 92 | void save(JsonObject entity, boolean isAdd, JsonObject result, Future future) { 93 | 94 | JsonObject secret = new JsonObject() 95 | .put(ID, entity.getString(ID)) 96 | .put(NAME, entity.getString(NAME)) 97 | .put(CREATED_BY, entity.getString(CREATED_BY)) 98 | .put(UTC_CREATED_DATE, entity.getString(UTC_CREATED_DATE)) 99 | .put(UTC_LAST_MODIFIED_DATE, entity.getString(UTC_LAST_MODIFIED_DATE)) 100 | .put(LAST_MODIFIED_BY, entity.getString(LAST_MODIFIED_BY)); 101 | 102 | if (entity.containsKey(DESC)) { 103 | secret.put(DESC, entity.getString(DESC)); 104 | } 105 | 106 | // Save to vault and then save the public properties to file. 107 | vaultService.save(entity, sh -> { 108 | if (sh.succeeded()) { 109 | saveToFile(secret, result, future); 110 | 111 | } else { 112 | String message = "Failed to save secret: " + secret; 113 | future.complete(addError(result, message)); 114 | logger.error(message, sh.cause()); 115 | } 116 | }); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /db/src/main/java/io/buildpal/db/file/UserManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.db.file; 18 | 19 | import io.buildpal.auth.vault.VaultService; 20 | import io.buildpal.core.domain.User; 21 | import io.buildpal.core.domain.validation.Validator; 22 | import io.buildpal.core.util.Utils; 23 | import io.vertx.core.Future; 24 | import io.vertx.core.Vertx; 25 | import io.vertx.core.json.JsonObject; 26 | import io.vertx.core.logging.Logger; 27 | import io.vertx.core.logging.LoggerFactory; 28 | 29 | import static io.buildpal.core.domain.Entity.ID; 30 | import static io.buildpal.core.domain.User.PASSWORD; 31 | import static io.buildpal.core.util.ResultUtils.addError; 32 | 33 | public class UserManager extends FileDbManager { 34 | private static final Logger logger = LoggerFactory.getLogger(UserManager.class); 35 | 36 | private final VaultService vaultService; 37 | 38 | public UserManager(Vertx vertx, JsonObject config, Validator validator) { 39 | super(vertx, logger, config, validator); 40 | 41 | vaultService = new VaultService(vertx); 42 | } 43 | 44 | @Override 45 | public String getCollectionName() { 46 | return "users"; 47 | } 48 | 49 | @Override 50 | void save(JsonObject entity, boolean isAdd, JsonObject result, Future future) { 51 | 52 | User user = new User(entity); 53 | 54 | if (user.getType() == User.Type.LOCAL) { 55 | saveUserHash(isAdd, user, result, future); 56 | 57 | } else { 58 | saveToFile(user.json(), result, future); 59 | } 60 | } 61 | 62 | private void saveUserHash(boolean isAdd, User user, JsonObject result, Future future) { 63 | 64 | boolean saveToVault = false; 65 | 66 | if (isAdd || user.json().containsKey(PASSWORD)) { 67 | user.setSalt(Utils.newID().getBytes()); 68 | saveToVault = true; 69 | } 70 | 71 | if (saveToVault) { 72 | // Add or update the hash in the vault. 73 | vaultService.save(user.getUserName(), user.getPassword(), user.getSalt(), sh -> { 74 | // No need to store the pass in the clear. 75 | user.clearPassword(); 76 | 77 | if (sh.succeeded()) { 78 | saveToFile(user.json(), result, future); 79 | 80 | } else { 81 | String message = "Unable to save hash for user: " + user.getName(); 82 | future.complete(addError(result, message)); 83 | logger.error(message, sh.cause()); 84 | } 85 | }); 86 | 87 | } else { 88 | saveToFile(user.json(), result, future); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /db/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.db { 18 | exports io.buildpal.db; 19 | exports io.buildpal.db.file; 20 | 21 | requires vertx.core; 22 | 23 | requires org.apache.commons.lang3; 24 | 25 | requires io.buildpal.core; 26 | requires io.buildpal.auth; 27 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | antlrVersion=4.7 2 | vertxVersion=3.5.1-SNAPSHOT 3 | nettyVersion=4.1.15.Final 4 | commonsLangVersion=3.6 5 | jGitVersion=4.9.0.201710071750-r 6 | dockerJavaVersion=3.0.14 7 | p4JavaVersion=2017.2.1560453 8 | slf4jVersion=1.7.21 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpal/buildpal-platform/e432825ade5f9cf117e666d010eb4630805a3f07/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 01 15:00:37 EST 2017 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /node/build.gradle: -------------------------------------------------------------------------------- 1 | javaModule.name = "io.buildpal.node" 2 | 3 | dependencies { 4 | implementation "io.vertx:vertx-auth-jwt:$vertxVersion" 5 | implementation "io.vertx:vertx-jwt:$vertxVersion" 6 | implementation "io.vertx:vertx-web:$vertxVersion" 7 | implementation "io.vertx:vertx-zookeeper:$vertxVersion" 8 | 9 | implementation "org.apache.commons:commons-lang3:$commonsLangVersion" 10 | implementation "org.slf4j:slf4j-api:$slf4jVersion" 11 | implementation "org.slf4j:slf4j-log4j12:$slf4jVersion" 12 | 13 | api project(":auth") 14 | api project(":core") 15 | api project(":db") 16 | api project(":workspace") 17 | api project(":oci") 18 | } 19 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/NodeLauncher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node; 18 | 19 | import io.vertx.core.DeploymentOptions; 20 | import io.vertx.core.Vertx; 21 | import io.vertx.core.VertxOptions; 22 | import io.vertx.core.impl.launcher.VertxCommandLauncher; 23 | import io.vertx.core.impl.launcher.VertxLifecycleHooks; 24 | import io.vertx.core.json.JsonObject; 25 | 26 | public class NodeLauncher extends VertxCommandLauncher implements VertxLifecycleHooks { 27 | 28 | private NodeLauncher() {} 29 | 30 | /** 31 | * Main entry point. 32 | * 33 | * @param args the user command line arguments. 34 | */ 35 | public static void main(String[] args) { 36 | new NodeLauncher().dispatch(args); 37 | } 38 | 39 | /** 40 | * Hook after the config has been parsed. 41 | * 42 | * @param config the read config, empty if none are provided. 43 | */ 44 | public void afterConfigParsed(JsonObject config) {} 45 | 46 | /** 47 | * Hook before the vertx instance is started. 48 | * 49 | * @param options the configured Vert.x options. Modify them to customize the Vert.x instance. 50 | */ 51 | public void beforeStartingVertx(VertxOptions options) { 52 | options.setPreferNativeTransport(true); 53 | } 54 | 55 | /** 56 | * Hook after the vertx instance is started. 57 | * 58 | * @param vertx the created Vert.x instance 59 | */ 60 | public void afterStartingVertx(Vertx vertx) {} 61 | 62 | /** 63 | * Hook before the verticle is deployed. 64 | * 65 | * @param deploymentOptions the current deployment options. Modify them to customize the deployment. 66 | */ 67 | public void beforeDeployingVerticle(DeploymentOptions deploymentOptions) {} 68 | 69 | @Override 70 | public void beforeStoppingVertx(Vertx vertx) {} 71 | 72 | @Override 73 | public void afterStoppingVertx() {} 74 | 75 | /** 76 | * A deployment failure has been encountered. You can override this method to customize the behavior. 77 | * By default it closes the `vertx` instance. 78 | * 79 | * @param vertx the vert.x instance 80 | * @param mainVerticle the verticle 81 | * @param deploymentOptions the verticle deployment options 82 | * @param cause the cause of the failure 83 | */ 84 | public void handleDeployFailed(Vertx vertx, String mainVerticle, DeploymentOptions deploymentOptions, Throwable cause) { 85 | // Default behaviour is to close Vert.x if the deploy failed 86 | vertx.close(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/auth/LogoutAuthHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.auth; 18 | 19 | import io.vertx.core.Handler; 20 | import io.vertx.core.logging.Logger; 21 | import io.vertx.core.logging.LoggerFactory; 22 | import io.vertx.ext.web.RoutingContext; 23 | 24 | public class LogoutAuthHandler implements Handler { 25 | private static final Logger logger = LoggerFactory.getLogger(LogoutAuthHandler.class); 26 | 27 | @Override 28 | public void handle(RoutingContext context) { 29 | context.clearUser(); 30 | 31 | // TODO: Should we push the JWT token to an invalid list? 32 | context.response().end(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/data/BuildScavenger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.data; 18 | 19 | import io.buildpal.node.router.BuildRouter; 20 | import io.vertx.core.AbstractVerticle; 21 | import io.vertx.core.Future; 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.eventbus.Message; 24 | import io.vertx.core.json.JsonArray; 25 | import io.vertx.core.json.JsonObject; 26 | import io.vertx.core.logging.Logger; 27 | import io.vertx.core.logging.LoggerFactory; 28 | 29 | import java.time.Clock; 30 | import java.time.Instant; 31 | import java.time.temporal.ChronoUnit; 32 | 33 | import static io.buildpal.core.config.Constants.ITEMS; 34 | import static io.buildpal.core.config.Constants.NODE; 35 | import static io.buildpal.core.util.ResultUtils.failed; 36 | 37 | public class BuildScavenger extends AbstractVerticle { 38 | private static final Logger logger = LoggerFactory.getLogger(BuildScavenger.class); 39 | 40 | private static final String QUERY = "(utcEndDate pr and utcEndDate lt i\"%s\") and " + 41 | "(status eq \"DONE\" or status eq \"FAILED\" or status eq \"CANCELED\")"; 42 | 43 | private static final String INFO = "%d builds were deemed old enough and they were requested to be purged"; 44 | 45 | private int daysOldToDelete; 46 | 47 | @Override 48 | public void start(Future startFuture) { 49 | 50 | try { 51 | JsonObject scavengerConfig = config().getJsonObject(NODE).getJsonObject("buildScavenger"); 52 | 53 | daysOldToDelete = scavengerConfig.getInteger("daysOldToDelete"); 54 | 55 | long scavengerInterval = scavengerConfig.getLong("interval"); 56 | 57 | vertx.setPeriodic(scavengerInterval, ph -> requestOldBuilds()); 58 | 59 | vertx.eventBus().localConsumer(BuildRouter.FIND_REPLY_ADDRESS, foundOldBuildsHandler()); 60 | 61 | startFuture.complete(); 62 | 63 | } catch (Exception ex) { 64 | startFuture.fail(ex); 65 | } 66 | } 67 | 68 | private void requestOldBuilds() { 69 | Instant olderThan = Instant.now(Clock.systemUTC()) 70 | .minus(daysOldToDelete, ChronoUnit.DAYS); 71 | 72 | JsonObject request = new JsonObject() 73 | .put("q", String.format(QUERY, olderThan.toString())); 74 | 75 | vertx.eventBus().send(BuildRouter.FIND_ADDRESS, request); 76 | } 77 | 78 | private Handler> foundOldBuildsHandler() { 79 | return mh -> { 80 | if (failed(mh.body())) { 81 | logger.error("Unable to retrieve old builds. Error: " + mh.body()); 82 | 83 | } else { 84 | JsonArray builds = mh.body().getJsonArray(ITEMS); 85 | 86 | if (builds.isEmpty()) return; 87 | 88 | for (int b=0; b userNodeMapping; 36 | 37 | public static NodeTracker ME = new NodeTracker(); 38 | 39 | private NodeTracker() {} 40 | 41 | public void load(Vertx vertx, List items) { 42 | userNodeMapping = vertx.sharedData().getLocalMap("userNodeMapping"); 43 | 44 | for (int i=0; i getAffinities() { 88 | List items = new ArrayList<>(); 89 | 90 | if (userNodeMapping != null) { 91 | userNodeMapping.forEach((key, value) -> 92 | items.add(new JsonObject().put(ID, key).put("nodes", value))); 93 | } 94 | 95 | return items; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/BaseRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.router; 18 | 19 | import io.buildpal.core.query.QuerySpec; 20 | import io.vertx.core.Vertx; 21 | import io.vertx.core.http.HttpServerRequest; 22 | import io.vertx.core.http.HttpServerResponse; 23 | import io.vertx.core.json.JsonObject; 24 | import io.vertx.core.logging.Logger; 25 | import io.vertx.ext.auth.jwt.JWTAuth; 26 | import io.vertx.ext.web.Router; 27 | import io.vertx.ext.web.RoutingContext; 28 | import io.vertx.ext.web.handler.AuthHandler; 29 | import io.vertx.ext.web.handler.JWTAuthHandler; 30 | 31 | import java.util.List; 32 | import java.util.Set; 33 | 34 | /** 35 | * Router with basic features shared across all routes. 36 | */ 37 | public abstract class BaseRouter { 38 | 39 | public static final String ROOT_PATH = "/"; 40 | 41 | static final String ID_PARAM = "id"; 42 | static final String ID_PATH = "/:" + ID_PARAM; 43 | 44 | private static final String ERRORS = "errors"; 45 | private static final String CONTENT_LENGTH = "Content-Length"; 46 | 47 | protected final Vertx vertx; 48 | protected final Router router; 49 | protected final Logger logger; 50 | private final JWTAuth jwtAuth; 51 | 52 | BaseRouter(Vertx vertx, Logger logger) { 53 | this(vertx, logger, null); 54 | } 55 | 56 | BaseRouter(Vertx vertx, Logger logger, JWTAuth jwtAuth) { 57 | this.vertx = vertx; 58 | this.router = Router.router(vertx); 59 | this.logger = logger; 60 | this.jwtAuth = jwtAuth; 61 | } 62 | 63 | public Router getRouter() { 64 | return router; 65 | } 66 | 67 | protected abstract String getBasePath(); 68 | 69 | void secureBaseRoute(Set authorities) { 70 | AuthHandler jwtAuthHandler = JWTAuthHandler.create(jwtAuth); 71 | 72 | if (authorities != null) { 73 | jwtAuthHandler.addAuthorities(authorities); 74 | } 75 | 76 | router.route(getBasePath() + "/*").handler(jwtAuthHandler); 77 | } 78 | 79 | public static void writeResponse(RoutingContext routingContext, JsonObject result) { 80 | writeResponse(routingContext, result, 200); 81 | } 82 | 83 | public static void write201Response(RoutingContext routingContext, JsonObject result) { 84 | writeResponse(routingContext, result, 201); 85 | } 86 | 87 | public static void write202Response(RoutingContext routingContext, JsonObject result) { 88 | writeResponse(routingContext, result, 202); 89 | } 90 | 91 | public static void writeResponse(RoutingContext routingContext, JsonObject result, int statusCode) { 92 | if (result.containsKey(ERRORS) && result.getJsonArray(ERRORS).size() > 0) { 93 | writeErrorResponse(routingContext, result.toString()); 94 | 95 | } else { 96 | routingContext.response().setStatusCode(statusCode); 97 | writeSuccessResponse(routingContext, result.toString(), false); 98 | } 99 | } 100 | 101 | static void writeSuccessResponse(RoutingContext routingContext, String body, boolean chunked) { 102 | HttpServerResponse response = routingContext.response(); 103 | 104 | if (chunked) { 105 | response.setChunked(true); 106 | 107 | } else { 108 | setContentLength(response, body); 109 | } 110 | 111 | response.write(body).end(); 112 | } 113 | 114 | static void writeErrorResponse(RoutingContext routingContext, List errors) { 115 | JsonObject result = new JsonObject().put(ERRORS, errors); 116 | writeErrorResponse(routingContext, result.encode()); 117 | } 118 | 119 | static void writeErrorResponse(RoutingContext routingContext, String body) { 120 | HttpServerResponse response = routingContext.response(); 121 | setContentLength(response, body); 122 | 123 | response.setStatusCode(500).write(body).end(); 124 | } 125 | 126 | static void setContentLength(HttpServerResponse response, String body) { 127 | response.putHeader(CONTENT_LENGTH, String.valueOf(body.length())); 128 | } 129 | 130 | static QuerySpec buildQuerySpec(HttpServerRequest request) { 131 | return new QuerySpec(request.params()); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/CrudRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.router; 18 | 19 | import io.buildpal.core.config.Constants; 20 | import io.buildpal.core.domain.Entity; 21 | import io.buildpal.core.domain.builder.Builder; 22 | import io.buildpal.core.query.QuerySpec; 23 | import io.buildpal.db.DbManager; 24 | import io.vertx.core.Vertx; 25 | import io.vertx.core.http.HttpMethod; 26 | import io.vertx.core.logging.Logger; 27 | import io.vertx.core.logging.LoggerFactory; 28 | import io.vertx.ext.auth.User; 29 | import io.vertx.ext.auth.jwt.JWTAuth; 30 | 31 | import java.time.Clock; 32 | import java.time.Instant; 33 | import java.util.HashSet; 34 | import java.util.List; 35 | 36 | import static io.buildpal.core.domain.Entity.populate; 37 | 38 | public class CrudRouter> extends BaseRouter { 39 | public static final String API_PATH = "/api/v1"; 40 | 41 | private static final Logger logger = LoggerFactory.getLogger(CrudRouter.class); 42 | 43 | final DbManager dbManager; 44 | final Builder builder; 45 | 46 | public CrudRouter(Vertx vertx, JWTAuth jwtAuth, List authorities, 47 | DbManager dbManager, Builder builder) { 48 | this(vertx, logger, jwtAuth, authorities, dbManager, builder); 49 | } 50 | 51 | public CrudRouter(Vertx vertx, Logger logger, JWTAuth jwtAuth, List authorities, 52 | DbManager dbManager, Builder builder) { 53 | 54 | super(vertx, logger, jwtAuth); 55 | 56 | this.dbManager = dbManager; 57 | this.builder = builder; 58 | 59 | if (jwtAuth != null) { 60 | secureBaseRoute(authorities != null ? new HashSet<>(authorities) : null); 61 | 62 | } else { 63 | logger.warn("Router is not backed by an auth handler: " + getBasePath()); 64 | } 65 | 66 | configureRoutes(getBasePath(), vertx); 67 | } 68 | 69 | @Override 70 | protected String getBasePath() { 71 | return "/" + dbManager.getCollectionName(); 72 | } 73 | 74 | protected void configureRoutes(String collectionPath, Vertx vertx) { 75 | configureGetCollectionRoute(collectionPath); 76 | 77 | configureGetRoute(collectionPath); 78 | configurePostRoute(collectionPath); 79 | configurePutRoute(collectionPath); 80 | configureDeleteRoute(collectionPath); 81 | } 82 | 83 | void configureGetCollectionRoute(String collectionPath) { 84 | router.route(HttpMethod.GET, collectionPath).handler(routingContext -> { 85 | QuerySpec querySpec = buildQuerySpec(routingContext.request()); 86 | dbManager.find(querySpec, r -> writeResponse(routingContext, r.result())); 87 | }); 88 | } 89 | 90 | void configureGetRoute(String collectionPath) { 91 | router.route(HttpMethod.GET, collectionPath + ID_PATH).handler(routingContext -> { 92 | 93 | dbManager.get(routingContext.request().getParam(ID_PARAM), 94 | r -> writeResponse(routingContext, r.result())); 95 | }); 96 | } 97 | 98 | void configurePostRoute(String collectionPath) { 99 | router.route(HttpMethod.POST, collectionPath).handler(routingContext -> { 100 | 101 | E entity = builder.build(routingContext.getBodyAsJson()); 102 | preparePost(entity, routingContext.user()); 103 | 104 | dbManager.add(entity.json(), r -> write201Response(routingContext, r.result())); 105 | }); 106 | } 107 | 108 | void configurePutRoute(String collectionPath) { 109 | router.route(HttpMethod.PUT, collectionPath + ID_PATH).handler(routingContext -> { 110 | 111 | E entity = builder.build(routingContext.getBodyAsJson()); 112 | preparePut(entity, routingContext.user()); 113 | 114 | dbManager.replace(entity.json(), r -> write202Response(routingContext, r.result())); 115 | }); 116 | } 117 | 118 | void configureDeleteRoute(String collectionPath) { 119 | router.route(HttpMethod.DELETE, collectionPath + ID_PATH).handler(routingContext -> { 120 | 121 | dbManager.delete(routingContext.request().getParam(ID_PARAM), 122 | r -> write202Response(routingContext, r.result())); 123 | }); 124 | } 125 | 126 | void preparePost(E entity, User user) { 127 | populate(entity, user.principal().getString(Constants.SUBJECT)); 128 | } 129 | 130 | void preparePut(E entity, User user) { 131 | entity.setUtcLastModifiedDate(Instant.now(Clock.systemUTC())) 132 | .setLastModifiedBy(user.principal().getString(Constants.SUBJECT)); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/SecretRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.router; 18 | 19 | import io.buildpal.core.domain.Secret; 20 | import io.buildpal.db.file.SecretManager; 21 | import io.vertx.core.Vertx; 22 | import io.vertx.core.logging.Logger; 23 | import io.vertx.core.logging.LoggerFactory; 24 | import io.vertx.ext.auth.jwt.JWTAuth; 25 | 26 | import java.util.List; 27 | 28 | public class SecretRouter extends CrudRouter { 29 | private static final Logger logger = LoggerFactory.getLogger(SecretRouter.class); 30 | 31 | public SecretRouter(Vertx vertx, JWTAuth jwtAuth, List authorities, 32 | SecretManager secretManager) { 33 | 34 | super(vertx, logger, jwtAuth, authorities, secretManager, Secret::new); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/StaticRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node.router; 18 | 19 | import io.vertx.core.Vertx; 20 | import io.vertx.core.json.JsonObject; 21 | import io.vertx.core.logging.Logger; 22 | import io.vertx.core.logging.LoggerFactory; 23 | import io.vertx.ext.web.handler.StaticHandler; 24 | 25 | public class StaticRouter extends BaseRouter { 26 | private static final Logger logger = LoggerFactory.getLogger(StaticRouter.class); 27 | 28 | private static final String WEB_ROOT = "webroot"; 29 | 30 | public StaticRouter(Vertx vertx, JsonObject config) { 31 | super(vertx, logger); 32 | 33 | StaticHandler handler = StaticHandler.create(); 34 | setWebRoot(config.getString(WEB_ROOT), handler); 35 | router.route().handler(handler); 36 | } 37 | 38 | @Override 39 | protected String getBasePath() { 40 | return ROOT_PATH; 41 | } 42 | 43 | private void setWebRoot(String path, StaticHandler staticHandler) { 44 | if (path == null) return; 45 | 46 | staticHandler.setWebRoot(path).setFilesReadOnly(true); 47 | logger.info("Files will be served from: " + path); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/UserRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Buildpal 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.buildpal.node.router; 18 | 19 | import io.buildpal.core.domain.User; 20 | import io.buildpal.db.file.UserManager; 21 | import io.buildpal.node.data.NodeTracker; 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.Vertx; 24 | import io.vertx.core.eventbus.Message; 25 | import io.vertx.core.http.HttpMethod; 26 | import io.vertx.core.json.JsonObject; 27 | import io.vertx.core.logging.Logger; 28 | import io.vertx.core.logging.LoggerFactory; 29 | import io.vertx.ext.auth.jwt.JWTAuth; 30 | 31 | import java.time.Clock; 32 | import java.time.Instant; 33 | import java.util.List; 34 | 35 | import static io.buildpal.core.config.Constants.ITEM; 36 | import static io.buildpal.core.config.Constants.NODE; 37 | import static io.buildpal.core.config.Constants.SAVE_USER_AFFINITY_ADDRESS; 38 | import static io.buildpal.core.domain.Entity.ID; 39 | import static io.buildpal.core.util.ResultUtils.addEntities; 40 | import static io.buildpal.core.util.ResultUtils.failed; 41 | import static io.buildpal.core.util.ResultUtils.getEntity; 42 | import static io.buildpal.core.util.ResultUtils.newResult; 43 | 44 | public class UserRouter extends CrudRouter { 45 | private static final Logger logger = LoggerFactory.getLogger(UserRouter.class); 46 | 47 | public UserRouter(Vertx vertx, JWTAuth jwtAuth, List authorities, 48 | UserManager userManager) { 49 | 50 | super(vertx, logger, jwtAuth, authorities, userManager, User::new); 51 | } 52 | 53 | @Override 54 | protected void configureRoutes(String collectionPath, Vertx vertx) { 55 | NodeTracker.ME.load(vertx, dbManager.list()); 56 | 57 | configureAffinitiesRoute(collectionPath); 58 | configureDeleteAffinityRoute(collectionPath); 59 | 60 | vertx.eventBus().consumer(SAVE_USER_AFFINITY_ADDRESS, saveNodeAffinityHandler()); 61 | } 62 | 63 | private void configureAffinitiesRoute(String collectionPath) { 64 | String path = collectionPath + "/affinity"; 65 | 66 | router.route(HttpMethod.GET, path).handler(routingContext -> { 67 | 68 | JsonObject result = newResult(); 69 | addEntities(result, NodeTracker.ME.getAffinities()); 70 | 71 | writeResponse(routingContext, result); 72 | }); 73 | } 74 | 75 | private void configureDeleteAffinityRoute(String collectionPath) { 76 | String path = collectionPath + ID_PATH + "/affinity"; 77 | 78 | router.route(HttpMethod.DELETE, path).handler(routingContext -> { 79 | String userID = routingContext.request().getParam(ID_PARAM); 80 | 81 | dbManager.get(userID, gh -> { 82 | JsonObject item = getEntity(gh.result()); 83 | 84 | if (!failed(gh) && item != null) { 85 | User user = new User(item) 86 | .clearNodeAffinity() 87 | .setUtcLastModifiedDate(Instant.now(Clock.systemUTC())) 88 | .setLastModifiedBy(userID); 89 | 90 | dbManager.replace(user.json(), sh -> { 91 | if (!failed(sh)) { 92 | NodeTracker.ME.removeNode(user); 93 | } 94 | 95 | sh.result().remove(ITEM); 96 | writeResponse(routingContext, sh.result()); 97 | }); 98 | 99 | } else { 100 | writeResponse(routingContext, gh.result()); 101 | } 102 | }); 103 | }); 104 | } 105 | 106 | private Handler> saveNodeAffinityHandler() { 107 | return mh -> { 108 | String userID = mh.body().getString(ID); 109 | String node = mh.body().getString(NODE); 110 | 111 | dbManager.get(userID, gh -> { 112 | JsonObject item = getEntity(gh.result()); 113 | 114 | if (failed(gh) || item == null) { 115 | logger.error("Unable to save node affinity for user: " + userID + ". Error: " + gh.result()); 116 | 117 | } else { 118 | User user = new User(item) 119 | .addNodeAffinity(node) 120 | .setUtcLastModifiedDate(Instant.now(Clock.systemUTC())) 121 | .setLastModifiedBy(userID); 122 | 123 | saveNodeAffinity(user); 124 | } 125 | }); 126 | }; 127 | } 128 | 129 | private void saveNodeAffinity(User user) { 130 | dbManager.replace(user.json(), sh -> { 131 | if (failed(sh)) { 132 | logger.error("Unable to save user: " + user.getID() + ". Error: " + sh.result()); 133 | 134 | } else { 135 | NodeTracker.ME.saveNode(user); 136 | } 137 | }); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /node/src/main/java/io/buildpal/node/router/WorkspaceRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Buildpal 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.buildpal.node.router; 18 | 19 | import io.buildpal.core.config.Constants; 20 | import io.buildpal.core.util.ResultUtils; 21 | import io.vertx.core.Vertx; 22 | import io.vertx.core.http.HttpMethod; 23 | import io.vertx.core.json.JsonObject; 24 | import io.vertx.core.logging.Logger; 25 | import io.vertx.core.logging.LoggerFactory; 26 | import io.vertx.ext.auth.jwt.JWTAuth; 27 | 28 | import static io.buildpal.core.config.Constants.DELETE_WORKSPACE_ADDRESS; 29 | import static io.buildpal.core.domain.Entity.ID; 30 | 31 | public class WorkspaceRouter extends BaseRouter { 32 | private static final Logger logger = LoggerFactory.getLogger(WorkspaceRouter.class); 33 | 34 | public WorkspaceRouter(Vertx vertx, JWTAuth jwtAuth) { 35 | super(vertx, logger, jwtAuth); 36 | 37 | if (jwtAuth != null) { 38 | secureBaseRoute(null); 39 | 40 | } else { 41 | logger.warn("Router is not backed by an auth handler: " + getBasePath()); 42 | } 43 | 44 | configureDeleteRoute(); 45 | } 46 | 47 | @Override 48 | protected String getBasePath() { 49 | return "/workspaces/user"; 50 | } 51 | 52 | private void configureDeleteRoute() { 53 | String path = getBasePath() + ID_PATH; 54 | 55 | router.route(HttpMethod.DELETE, path).handler(routingContext -> { 56 | String userID = routingContext.request().getParam(ID_PARAM); 57 | 58 | // Users can delete workspaces that they own. 59 | if (userID.equals(routingContext.user().principal().getString(Constants.SUBJECT))) { 60 | JsonObject entity = new JsonObject().put(ID, userID); 61 | 62 | vertx.eventBus().publish(DELETE_WORKSPACE_ADDRESS, entity); 63 | 64 | write202Response(routingContext, ResultUtils.prepareResult(entity)); 65 | 66 | } else { 67 | routingContext.fail(401); 68 | } 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /node/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.node { 18 | exports io.buildpal.node; 19 | exports io.buildpal.node.engine; 20 | exports io.buildpal.node.data; 21 | 22 | uses io.buildpal.core.pipeline.Plugin; 23 | 24 | requires vertx.core; 25 | requires vertx.auth.common; 26 | requires vertx.jwt; 27 | requires vertx.auth.jwt; 28 | requires vertx.web; 29 | 30 | requires org.apache.commons.lang3; 31 | 32 | requires io.buildpal.auth; 33 | requires io.buildpal.core; 34 | requires io.buildpal.db; 35 | requires io.buildpal.oci; 36 | requires io.buildpal.workspace; 37 | } -------------------------------------------------------------------------------- /node/src/test/java/io/buildpal/node/EngineTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.node; 18 | 19 | import io.buildpal.core.domain.Build; 20 | import io.buildpal.core.domain.Status; 21 | import io.buildpal.node.engine.Engine; 22 | import io.vertx.core.Vertx; 23 | 24 | public class EngineTest { 25 | //@Test 26 | public void testEngine() throws Exception { 27 | Vertx vertx = Vertx.vertx(); 28 | 29 | vertx.deployVerticle(Engine.class.getName(), dh -> { 30 | 31 | if (dh.succeeded()) { 32 | 33 | Build build = new Build() 34 | .setID("b1") 35 | .setPipelineID("p1") 36 | .setStatus(Status.PARKED); 37 | 38 | vertx.eventBus().send(Engine.START, build.json()); 39 | } 40 | }); 41 | 42 | Thread.sleep(1000 * 2); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /oci/build.gradle: -------------------------------------------------------------------------------- 1 | javaModule.name = "io.buildpal.oci" 2 | 3 | dependencies { 4 | implementation "io.vertx:vertx-web:$vertxVersion" 5 | 6 | implementation group: "io.netty", name: "netty-transport-native-kqueue", version: "$nettyVersion", classifier: "osx-x86_64" 7 | implementation group: "io.netty", name: "netty-transport-native-epoll", version: "$nettyVersion", classifier: "linux-x86_64" 8 | 9 | api project(":core") 10 | } 11 | -------------------------------------------------------------------------------- /oci/src/main/java/io/buildpal/oci/DockerStreamerSansHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.oci; 18 | 19 | import io.vertx.core.buffer.Buffer; 20 | import io.vertx.core.logging.Logger; 21 | import io.vertx.core.logging.LoggerFactory; 22 | 23 | import java.nio.ByteBuffer; 24 | 25 | public class DockerStreamerSansHeader { 26 | private static final Logger logger = LoggerFactory.getLogger(DockerStreamerSansHeader.class); 27 | 28 | @FunctionalInterface 29 | public interface StreamHandler { 30 | void onData(Buffer data); 31 | } 32 | 33 | private StreamHandler streamHandler; 34 | private Buffer mainBuffer; 35 | private int msgSize; 36 | 37 | public DockerStreamerSansHeader(StreamHandler streamHandler) { 38 | this.streamHandler = streamHandler; 39 | 40 | mainBuffer = Buffer.buffer(); 41 | msgSize = 0; 42 | } 43 | 44 | public void write(Buffer buffer) { 45 | mainBuffer.appendBuffer(buffer); 46 | scan(); 47 | } 48 | 49 | public void end() { 50 | scan(); 51 | 52 | if (mainBuffer.length() > 0) { 53 | logger.warn("Docker stream overflow. Closing the stream anyway."); 54 | } 55 | 56 | mainBuffer = null; 57 | streamHandler = null; 58 | } 59 | 60 | private void scan() { 61 | if (msgSize > 0) { 62 | writeData(); 63 | 64 | } else { 65 | stripHeader(); 66 | } 67 | } 68 | 69 | private void writeData() { 70 | if (mainBuffer.length() >= msgSize) { 71 | streamHandler.onData(mainBuffer.getBuffer(0, msgSize)); 72 | 73 | mainBuffer = mainBuffer.slice(msgSize, mainBuffer.length()).copy(); 74 | msgSize = 0; 75 | } 76 | 77 | if (mainBuffer.length() > 0) { 78 | stripHeader(); 79 | } 80 | } 81 | 82 | private void stripHeader() { 83 | if (msgSize == 0 && mainBuffer.length() >= 8) { 84 | // Docker adds a header to differentiate b/w stdout and stderr streams when tty is disabled 85 | // Let's remove that header here. 86 | byte[] header = mainBuffer.getBytes(0, 8); 87 | 88 | msgSize = ByteBuffer.wrap(header, 4, 4).getInt(); 89 | mainBuffer = mainBuffer.slice(8, mainBuffer.length()).copy(); 90 | 91 | if (mainBuffer.length() > 0) { 92 | scan(); 93 | } 94 | } 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /oci/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.oci { 18 | exports io.buildpal.oci; 19 | provides io.buildpal.core.pipeline.Plugin with io.buildpal.oci.DockerClientVerticle; 20 | 21 | requires jdk.unsupported; 22 | 23 | requires vertx.core; 24 | requires vertx.web; 25 | 26 | requires static io.netty.transport.epoll; 27 | //requires static io.netty.transport.kqueue; 28 | 29 | requires io.buildpal.core; 30 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include "auth" 2 | include "core" 3 | include "db" 4 | include "node" 5 | include "oci" 6 | include "workspace" -------------------------------------------------------------------------------- /workspace/build.gradle: -------------------------------------------------------------------------------- 1 | javaModule.name = "io.buildpal.workspace" 2 | 3 | dependencies { 4 | implementation "io.vertx:vertx-lang-js:$vertxVersion" 5 | implementation "org.apache.commons:commons-lang3:$commonsLangVersion" 6 | implementation "org.eclipse.jgit:org.eclipse.jgit:$jGitVersion" 7 | implementation "com.perforce:p4java:$p4JavaVersion" 8 | 9 | api project(":auth") 10 | api project(":core") 11 | } 12 | -------------------------------------------------------------------------------- /workspace/src/main/java/io/buildpal/workspace/vcs/BaseVersionController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.workspace.vcs; 18 | 19 | import io.buildpal.core.domain.Repository; 20 | import io.buildpal.core.domain.Workspace; 21 | 22 | import java.io.File; 23 | 24 | public abstract class BaseVersionController implements VersionController { 25 | 26 | protected Repository repository; 27 | protected Workspace workspace; 28 | 29 | BaseVersionController(Repository repository, Workspace workspace) { 30 | this.repository = repository; 31 | this.workspace = workspace; 32 | } 33 | 34 | @Override 35 | public Repository getRepository() { 36 | return repository; 37 | } 38 | 39 | @Override 40 | public Workspace getWorkspace() { 41 | return workspace; 42 | } 43 | 44 | File workspacePath() { 45 | return workspace.path(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /workspace/src/main/java/io/buildpal/workspace/vcs/FileSystemController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.workspace.vcs; 18 | 19 | import io.buildpal.core.domain.Repository; 20 | import io.buildpal.core.domain.Secret; 21 | import io.buildpal.core.domain.Workspace; 22 | import io.buildpal.core.util.FileUtils; 23 | import io.vertx.core.json.JsonObject; 24 | 25 | import java.io.File; 26 | 27 | public class FileSystemController extends BaseVersionController { 28 | 29 | public FileSystemController(Repository repository, Workspace workspace) { 30 | super(repository, workspace); 31 | } 32 | 33 | @Override 34 | public void sync(JsonObject data, Secret secret) throws Exception { 35 | FileUtils.copy(new File(getRepository().getUri()), workspacePath()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /workspace/src/main/java/io/buildpal/workspace/vcs/GitController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.workspace.vcs; 18 | 19 | import io.buildpal.core.domain.Repository; 20 | import io.buildpal.core.domain.Secret; 21 | import io.buildpal.core.domain.Workspace; 22 | import io.buildpal.core.util.DataUtils; 23 | import io.vertx.core.json.JsonObject; 24 | import io.vertx.core.logging.Logger; 25 | import io.vertx.core.logging.LoggerFactory; 26 | import org.eclipse.jgit.api.Git; 27 | 28 | public class GitController extends BaseVersionController { 29 | private final static Logger logger = LoggerFactory.getLogger(GitController.class); 30 | 31 | public GitController(Repository repository, Workspace workspace) { 32 | super(repository, workspace); 33 | } 34 | 35 | @Override 36 | public void sync(JsonObject data, Secret secret) throws Exception { 37 | 38 | String branch = DataUtils.eval(repository.getBranch(), data); 39 | 40 | // TODO: Add SSH and Oauth support. 41 | 42 | Git.cloneRepository() 43 | .setURI(repository.getUri()) 44 | .setBranch(branch) 45 | .setRemote(repository.getRemote()) 46 | .setDirectory(workspacePath()) 47 | .call() 48 | .close(); 49 | 50 | if (logger.isDebugEnabled()) { 51 | logger.debug(String.format("Sync repo %s to %s completed with data: %s ", 52 | getRepository().getName(), workspace.getPath(), data.encode())); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /workspace/src/main/java/io/buildpal/workspace/vcs/SyncResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.workspace.vcs; 18 | 19 | public class SyncResult { 20 | private boolean success; 21 | private String metadata; 22 | private Exception exception; 23 | 24 | public SyncResult(boolean success, String metadata) { 25 | this(success, metadata, null); 26 | } 27 | 28 | public SyncResult(boolean success, String metadata, Exception exception) { 29 | this.success = success; 30 | this.metadata = metadata; 31 | this.exception = exception; 32 | } 33 | 34 | public boolean isSuccess() { 35 | return success; 36 | } 37 | 38 | public String getMetadata() { 39 | return metadata; 40 | } 41 | 42 | public Exception getException() { 43 | return exception; 44 | } 45 | 46 | public static SyncResult success() { 47 | return new SyncResult(true, null); 48 | } 49 | 50 | public static SyncResult success(String metadata) { 51 | return new SyncResult(true, metadata); 52 | } 53 | 54 | public static SyncResult fail(Exception ex) { 55 | return new SyncResult(false, null, ex); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /workspace/src/main/java/io/buildpal/workspace/vcs/VersionController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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.buildpal.workspace.vcs; 18 | 19 | import io.buildpal.core.domain.Repository; 20 | import io.buildpal.core.domain.Secret; 21 | import io.buildpal.core.domain.Workspace; 22 | import io.vertx.core.json.JsonObject; 23 | 24 | public interface VersionController { 25 | void sync(JsonObject data, Secret secret) throws Exception; 26 | 27 | default void revert(Secret secret) throws Exception { 28 | // Do nothing 29 | } 30 | 31 | default Repository getRepository() { 32 | return null; 33 | } 34 | 35 | default Workspace getWorkspace() { 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /workspace/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Buildpal 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 | module io.buildpal.workspace { 18 | exports io.buildpal.workspace; 19 | 20 | provides io.buildpal.core.pipeline.Plugin 21 | with io.buildpal.workspace.WorkspaceVerticle, io.buildpal.workspace.ScriptVerticle; 22 | 23 | requires java.scripting; 24 | requires jdk.scripting.nashorn; 25 | 26 | requires vertx.core; 27 | requires vertx.lang.js; 28 | 29 | requires org.apache.commons.lang3; 30 | 31 | requires org.eclipse.jgit; 32 | 33 | requires p4java; 34 | 35 | requires io.buildpal.auth; 36 | requires io.buildpal.core; 37 | } -------------------------------------------------------------------------------- /workspace/src/main/resources/js/Container.js: -------------------------------------------------------------------------------- 1 | var Shell = require('./Shell.js'); 2 | 3 | var Docker = function(listener) { 4 | this._tags = []; 5 | this._foldersToCopy = []; 6 | 7 | this._listener = listener; 8 | 9 | this._buildEnabled = false; 10 | this._pushEnabled = false; 11 | this._copyWorkspace = false; 12 | }; 13 | 14 | Docker.prototype.tags = function() { 15 | if (arguments && arguments.length > 0) { 16 | for (var a=0; a