PageRenderTime 24ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/avisi/bitbucketconfigurator/domain/services/ConfigurationService.java

https://bitbucket.org/EricJans/configurator
Java | 236 lines | 158 code | 49 blank | 29 comment | 25 complexity | 3f874736ced27e76474a700ae52bb039 MD5 | raw file
  1. package com.avisi.bitbucketconfigurator.domain.services;
  2. import com.avisi.bitbucketconfigurator.domain.exception.BitbucketCommunicationException;
  3. import com.avisi.bitbucketconfigurator.domain.exception.ConfigFileException;
  4. import com.avisi.bitbucketconfigurator.domain.objects.ActorPermission;
  5. import com.avisi.bitbucketconfigurator.domain.objects.ActorPermissionList;
  6. import com.avisi.bitbucketconfigurator.domain.objects.BitbucketSetup;
  7. import com.avisi.bitbucketconfigurator.domain.objects.Change;
  8. import com.avisi.bitbucketconfigurator.domain.objects.ChangeLog;
  9. import com.avisi.bitbucketconfigurator.domain.objects.GroupPermission;
  10. import com.avisi.bitbucketconfigurator.domain.objects.PermissionType;
  11. import com.avisi.bitbucketconfigurator.domain.objects.UserPermission;
  12. import com.avisi.bitbucketconfigurator.domain.objects.Webhook;
  13. import com.avisi.bitbucketconfigurator.domain.objects.WebhookSet;
  14. import com.avisi.bitbucketconfigurator.domain.objects.configfile.ConfigFile;
  15. import com.avisi.bitbucketconfigurator.domain.objects.configfile.PermissionWrapper;
  16. import com.avisi.bitbucketconfigurator.gateway.BitbucketGateway;
  17. import com.cdancy.bitbucket.rest.features.RepositoryApi;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import com.cdancy.bitbucket.rest.domain.repository.PermissionsPage;
  20. import org.springframework.stereotype.Service;
  21. import java.io.InputStream;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Set;
  27. @Service
  28. public class ConfigurationService {
  29. private final YamlService yamlService;
  30. private final BitbucketGateway bitbucketGateway;
  31. @Autowired
  32. public ConfigurationService(final YamlService yamlService, final BitbucketGateway bitbucketGateway) {
  33. this.yamlService = yamlService;
  34. this.bitbucketGateway = bitbucketGateway;
  35. }
  36. private ConfigFile mergeConfigFile(ConfigFile configFile, ConfigFile defaultConfigFile) {
  37. final ConfigFile mergedConfigFile = new ConfigFile();
  38. final PermissionWrapper permissionWrapper = new PermissionWrapper();
  39. permissionWrapper.setUsers(mergeUserPermissions(configFile, defaultConfigFile));
  40. permissionWrapper.setGroups(mergeGroupPermissions(configFile, defaultConfigFile));
  41. mergedConfigFile.setPermissions(permissionWrapper);
  42. mergedConfigFile.setWebhooks(new HashMap<>());
  43. mergeWebhooks(configFile, defaultConfigFile).forEach(webhook->{
  44. mergedConfigFile.getWebhooks().put(webhook.getName(), webhook);
  45. });
  46. return mergedConfigFile;
  47. }
  48. private Map<String, PermissionType> mergeUserPermissions(ConfigFile configFile, ConfigFile defaultConfigFile) {
  49. final Map<String, PermissionType> configUserPermissions = configFile.getPermissions().getUsers();
  50. final Map<String, PermissionType> defaultUserPermissions = defaultConfigFile.getPermissions().getUsers();
  51. return comparePermissions(configUserPermissions, defaultUserPermissions);
  52. }
  53. private Map<String, PermissionType> mergeGroupPermissions(ConfigFile configFile, ConfigFile defaultConfigFile) {
  54. final Map<String, PermissionType> configGroupPermissions = configFile.getPermissions().getGroups();
  55. final Map<String, PermissionType> defaultGroupPermissions = defaultConfigFile.getPermissions().getGroups();
  56. return comparePermissions(configGroupPermissions, defaultGroupPermissions);
  57. }
  58. private Set<Webhook> mergeWebhooks(ConfigFile configFile, ConfigFile defaultConfigFile) {
  59. final Map<String, Webhook> configWebhooks = configFile.getWebhooks();
  60. final Map<String, Webhook> defaultWebhooks = defaultConfigFile.getWebhooks();
  61. return compareWebhooks(configWebhooks, defaultWebhooks);
  62. }
  63. private Set<Webhook> compareWebhooks(Map<String, Webhook> configWebhooks, Map<String, Webhook> defaultWebhooks) {
  64. final Set<Webhook> mergedWebhooks = new HashSet<>();
  65. if (defaultWebhooks != null) {
  66. defaultWebhooks.forEach((key, value) -> mergedWebhooks.add(new Webhook(key, value.getUrl(), value.getEvents())));
  67. }
  68. if (configWebhooks != null) {
  69. configWebhooks.forEach((key, value) -> mergedWebhooks.add(new Webhook(key, value.getUrl(), value.getEvents())));
  70. }
  71. return mergedWebhooks;
  72. }
  73. private Map<String, PermissionType> comparePermissions(Map<String, PermissionType> configPermissions,
  74. Map<String, PermissionType> defaultPermissions) {
  75. final Map<String, PermissionType> mergedPermissions = new HashMap<>();
  76. if (configPermissions != null) {
  77. mergePermissions(configPermissions, defaultPermissions, mergedPermissions);
  78. }
  79. if (defaultPermissions != null) {
  80. defaultPermissions.forEach((key, value) -> {
  81. if (configPermissions == null) {
  82. mergedPermissions.put(key, value);
  83. } else if (!configPermissions.containsKey(key)) {
  84. mergedPermissions.put(key, value);
  85. }
  86. });
  87. }
  88. return mergedPermissions;
  89. }
  90. private void mergePermissions(Map<String, PermissionType> configPermissions,
  91. Map<String, PermissionType> defaultPermissions,
  92. Map<String, PermissionType> mergedPermissions) {
  93. configPermissions.forEach((key, value) -> {
  94. if (defaultPermissions == null) {
  95. mergedPermissions.put(key, value);
  96. } else if (defaultPermissions.containsKey(key) &&
  97. defaultPermissions.get(key).getRank() > configPermissions.get(key).getRank()) {
  98. mergedPermissions.put(key, defaultPermissions.get(key));
  99. } else {
  100. defaultPermissions.put(key, defaultPermissions.get(key));
  101. mergedPermissions.put(key, value);
  102. }
  103. });
  104. }
  105. /**
  106. * Updates all the configurations specified in the given yaml configuration string.
  107. * @param bitbucketSetup The BitbucketSetup to which this configuration has to be applied to.
  108. * @param yamlConfiguration The specified configuration string formatted as YAML.
  109. * @throws ConfigFileException When mapping the configuration onto a config file fails.
  110. * @throws BitbucketCommunicationException When communication with Bitbucket fails.
  111. * @return A Log containing all the changes that occurred.
  112. */
  113. public ChangeLog updateAllConfigurations(final BitbucketSetup bitbucketSetup, final String yamlConfiguration, final InputStream filePath) throws BitbucketCommunicationException, ConfigFileException {
  114. final ConfigFile configFile = yamlService.deserializeYaml(yamlConfiguration);
  115. final ConfigFile defaultConfigFile = yamlService.deserializeYamlFile(filePath);
  116. final ConfigFile mergedConfigFile = mergeConfigFile(configFile, defaultConfigFile);
  117. final List<Change> actorPermissionChanges = retrieveUpdatePermissions(bitbucketSetup, mergedConfigFile);
  118. final List<Change> webhookChanges = retrieveUpdateWebhooks(bitbucketSetup, mergedConfigFile);
  119. for (Change change : actorPermissionChanges) {
  120. executeChange(bitbucketSetup, (ActorPermission) change.getNewObject());
  121. }
  122. bitbucketGateway.createWebhooksFromChangeList(webhookChanges, bitbucketSetup);
  123. return new ChangeLog(actorPermissionChanges, webhookChanges);
  124. }
  125. /**
  126. * Updates Permissions based on a ConfigFile into the Bitbucket server.
  127. * @param bitbucketSetup The bitbucket setup used for interacting with the Bitbucket server.
  128. * @param configFile The ConfigFile that holds the new configuration.
  129. * @return A list of the applied changes.
  130. */
  131. protected List<Change> retrieveUpdatePermissions(final BitbucketSetup bitbucketSetup, final ConfigFile configFile) {
  132. final ActorPermissionList yamlConfigPermissions = configFile.createPermissionList();
  133. final ActorPermissionList onlinePermissions = getOnlinePermissions(bitbucketSetup);
  134. final List<Change> changes = yamlConfigPermissions.getChanges(onlinePermissions);
  135. return changes;
  136. }
  137. /**
  138. * Updates all webhooks based on a config file
  139. * @param bitbucketSetup The bitbucket setup used for interacting with the Bitbucket server.
  140. * @param configFile The ConfigFile that holds the new configuration.
  141. * @return A list of changes
  142. * @throws BitbucketCommunicationException
  143. */
  144. protected List<Change> retrieveUpdateWebhooks(final BitbucketSetup bitbucketSetup, final ConfigFile configFile) throws BitbucketCommunicationException, ConfigFileException {
  145. final WebhookSet yamlConfigWebhooks = configFile.createWebhookList();
  146. final WebhookSet onlineWebhooks = bitbucketGateway.retrieveWebhooks(bitbucketSetup);
  147. final List<Change> changes = yamlConfigWebhooks.getChanges(onlineWebhooks);
  148. return changes;
  149. }
  150. /**
  151. * Executes the changes that have been made to the YAML file
  152. * @param change A list of all the changes that have been made to the YAML file
  153. */
  154. protected void executeChange(final BitbucketSetup bitbucketSetup, final ActorPermission change) {
  155. final RepositoryApi repositoryApi = bitbucketSetup.getClient().api().repositoryApi();
  156. if (change instanceof UserPermission) {
  157. if (change.getType().equals(PermissionType.NONE)) {
  158. repositoryApi.deletePermissionsByUser(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), change.getName());
  159. } else {
  160. repositoryApi.createPermissionsByUser(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), change.getType().getCommand(), change.getName());
  161. }
  162. } else if (change instanceof GroupPermission) {
  163. if (change.getType().equals(PermissionType.NONE)) {
  164. repositoryApi.deletePermissionsByGroup(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), change.getName());
  165. } else {
  166. repositoryApi.createPermissionsByGroup(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), change.getType().getCommand(), change.getName());
  167. }
  168. }
  169. }
  170. /**
  171. * Gets all the permissions that are online at this moment
  172. * @return A list of the online permissions
  173. */
  174. protected ActorPermissionList getOnlinePermissions(final BitbucketSetup bitbucketSetup) {
  175. final RepositoryApi repositoryApi = bitbucketSetup.getClient().api().repositoryApi();
  176. final ActorPermissionList online = new ActorPermissionList();
  177. final PermissionsPage permissionsPageUsers = repositoryApi.listPermissionsByUser(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), null, null);
  178. final PermissionsPage permissionsPageGroups = repositoryApi.listPermissionsByGroup(bitbucketSetup.getProject(), bitbucketSetup.getRepository(), null, null);
  179. permissionsPageUsers
  180. .values()
  181. .forEach(permissions -> online.add(new UserPermission(permissions)));
  182. permissionsPageGroups
  183. .values()
  184. .forEach(permissions -> online.add(new GroupPermission(permissions)));
  185. return online;
  186. }
  187. }