chore: restore from backup

restoring to gitea from backup
This commit is contained in:
john 2025-11-24 19:11:03 -07:00
commit 607a89b90f
40 changed files with 1282 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/.classpath
/.factorypath
/.project
/target
/.idea

1
README.md Normal file
View File

@ -0,0 +1 @@
Placeholder.

7
manifest.yml Normal file
View File

@ -0,0 +1,7 @@
---
applications:
- name: GitHelp
memory: 768M
instances: 1
buildpack: java_buildpack_offline
path: target/GitHelp-1.0.0-SNAPSHOT.jar

83
pom.xml Normal file
View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<organization>
<name>John Groller</name>
<url>http://www.jkgroller.com</url>
</organization>
<groupId>com.jkgroller.githelp</groupId>
<artifactId>GitHelp</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>Translates GitLab terminology to scrum terminology and provides additional calculations.</description>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.crnk</groupId>
<artifactId>crnk-setup-spring-boot2</artifactId>
<version>3.0.20190714142556</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>4.12.15</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,16 @@
package com.jkgroller.githelp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GitHelp {
public static void main(String[] args) {
SpringApplication.run(GitHelp.class, args);
}
}

View File

@ -0,0 +1,11 @@
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.request.RetrieveGroupRequestTO;
import com.jkgroller.githelp.adapter.response.RetrieveGroupResponseTO;
public interface GitlabGroupAdapter {
RetrieveGroupResponseTO retrieveGroup(
RetrieveGroupRequestTO retrieveGroupRequestTO);
}

View File

@ -0,0 +1,33 @@
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.request.RetrieveGroupRequestTO;
import com.jkgroller.githelp.adapter.response.RetrieveGroupResponseTO;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.GroupApi;
import org.gitlab4j.api.models.Group;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GitlabGroupAdapterImpl implements GitlabGroupAdapter{
@Autowired
private GroupApi groupApi;
@Override
public RetrieveGroupResponseTO retrieveGroup(RetrieveGroupRequestTO retrieveGroupRequestTO) {
RetrieveGroupResponseTO retrieveGroupResponseTO = new RetrieveGroupResponseTO();
try {
Group group = groupApi.getGroup(retrieveGroupRequestTO.getGroupNumber());
retrieveGroupResponseTO.setGroupName(group.getName());
} catch (GitLabApiException e) {
return null;
}
return retrieveGroupResponseTO;
}
}

View File

@ -0,0 +1,11 @@
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.request.RetrieveMilestoneIssuesRequestTO;
import com.jkgroller.githelp.adapter.response.RetrieveMilestoneIssuesResponseTO;
public interface GitlabIssueAdapter {
RetrieveMilestoneIssuesResponseTO retrieveMilestoneIssues(
RetrieveMilestoneIssuesRequestTO retrieveMilestoneIssuesRequestTO);
}

View File

@ -0,0 +1,50 @@
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.converter.IssueConverter;
import com.jkgroller.githelp.adapter.request.RetrieveMilestoneIssuesRequestTO;
import com.jkgroller.githelp.adapter.response.IssueTO;
import com.jkgroller.githelp.adapter.response.RetrieveMilestoneIssuesResponseTO;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.IssuesApi;
import org.gitlab4j.api.models.IssueFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.List;
@Component
public class GitlabIssueAdapterImpl implements GitlabIssueAdapter {
@Autowired
private IssuesApi issuesApi;
@Autowired
private IssueConverter issueConverter;
@Override
public RetrieveMilestoneIssuesResponseTO retrieveMilestoneIssues(RetrieveMilestoneIssuesRequestTO retrieveMilestoneIssuesRequestTO) {
if (StringUtils.isEmpty(retrieveMilestoneIssuesRequestTO.getMilestoneTitle())) {
return null;
}
RetrieveMilestoneIssuesResponseTO retrieveMilestoneIssuesResponseTO = new RetrieveMilestoneIssuesResponseTO();
try {
IssueFilter issueFilter = new IssueFilter();
issueFilter.setMilestone(retrieveMilestoneIssuesRequestTO.getMilestoneTitle());
List<IssueTO> issueTOs = issueConverter.convert(issuesApi.getIssues(issueFilter));
retrieveMilestoneIssuesResponseTO.setIssueTOs(issueTOs);
} catch (GitLabApiException e) {
return null;
}
return retrieveMilestoneIssuesResponseTO;
}
}

View File

@ -0,0 +1,11 @@
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.request.RetrieveMilestonesRequestTO;
import com.jkgroller.githelp.adapter.response.RetrieveMilestonesResponseTO;
public interface GitlabMilestoneAdapter {
RetrieveMilestonesResponseTO retrieveMilestones(
RetrieveMilestonesRequestTO retrieveMilestonesRequestTO);
}

View File

@ -0,0 +1,60 @@
/**
*
*/
package com.jkgroller.githelp.adapter;
import com.jkgroller.githelp.adapter.converter.MilestoneConverter;
import com.jkgroller.githelp.adapter.request.RetrieveMilestonesRequestTO;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.adapter.response.RetrieveMilestonesResponseTO;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.MilestonesApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author john@grollerfamily.com
*
*/
@Component
public class GitlabMilestoneAdapterImpl implements GitlabMilestoneAdapter {
@Autowired
private MilestonesApi milestonesApi;
@Autowired
private MilestoneConverter milestoneConverter;
@Override
public RetrieveMilestonesResponseTO retrieveMilestones(
RetrieveMilestonesRequestTO retrieveMilestonesRequestTO) {
if (0 == retrieveMilestonesRequestTO.getGroupNumber()) {
return null;
}
RetrieveMilestonesResponseTO retrieveMilestonesResponseTO = new RetrieveMilestonesResponseTO();
try {
int subListStartIndex = 0;
int subListEndIndex = retrieveMilestonesRequestTO.getNumberOfMilestonesToReturn() - 1;
List<MilestoneTO> milestoneTOs = milestoneConverter.convert(milestonesApi
.getGroupMilestones(retrieveMilestonesRequestTO.getGroupNumber(), retrieveMilestonesRequestTO.getMilestoneState())).subList(subListStartIndex,
subListEndIndex);
retrieveMilestonesResponseTO.setMilestoneTOs(milestoneTOs);
} catch (GitLabApiException e) {
return null;
}
return retrieveMilestonesResponseTO;
}
}

View File

@ -0,0 +1,26 @@
package com.jkgroller.githelp.adapter.converter;
import com.jkgroller.githelp.adapter.response.IssueTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.gitlab4j.api.models.Issue;
import org.springframework.stereotype.Component;
@Component
public class IssueConverter extends AbstractConverter<Issue, IssueTO, Void> {
@Override
public IssueTO convert(Issue from, Void context) {
if (null == from) {
return null;
}
IssueTO issueTO = new IssueTO();
issueTO.setTitle(from.getTitle());
issueTO.setUrl(from.getWebUrl());
issueTO.setWeight(from.getWeight());
return issueTO;
}
}

View File

@ -0,0 +1,25 @@
package com.jkgroller.githelp.adapter.converter;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.gitlab4j.api.models.Milestone;
import org.springframework.stereotype.Component;
@Component
public class MilestoneConverter extends AbstractConverter<Milestone, MilestoneTO, Void> {
@Override
public MilestoneTO convert(Milestone from, Void context) {
if (null == from) {
return null;
}
MilestoneTO milestoneTO = new MilestoneTO();
milestoneTO.setTitle(from.getTitle());
return milestoneTO;
}
}

View File

@ -0,0 +1,14 @@
package com.jkgroller.githelp.adapter.request;
public class RetrieveGroupRequestTO {
private int groupNumber;
public int getGroupNumber() {
return groupNumber;
}
public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}
}

View File

@ -0,0 +1,14 @@
package com.jkgroller.githelp.adapter.request;
public class RetrieveMilestoneIssuesRequestTO {
private String milestoneTitle;
public String getMilestoneTitle() {
return milestoneTitle;
}
public void setMilestoneTitle(String milestoneTitle) {
this.milestoneTitle = milestoneTitle;
}
}

View File

@ -0,0 +1,37 @@
package com.jkgroller.githelp.adapter.request;
import org.gitlab4j.api.Constants;
public class RetrieveMilestonesRequestTO {
private int groupNumber;
private int numberOfMilestonesToReturn;
//Replace with internal enum later.
private Constants.MilestoneState milestoneState;
public int getGroupNumber() {
return groupNumber;
}
public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}
public int getNumberOfMilestonesToReturn() {
return numberOfMilestonesToReturn;
}
public void setNumberOfMilestonesToReturn(int numberOfMilestonesToReturn) {
this.numberOfMilestonesToReturn = numberOfMilestonesToReturn;
}
public Constants.MilestoneState getMilestoneState() {
return milestoneState;
}
public void setMilestoneState(Constants.MilestoneState milestoneState) {
this.milestoneState = milestoneState;
}
}

View File

@ -0,0 +1,41 @@
/**
*
*/
package com.jkgroller.githelp.adapter.response;
/**
* @author john@grollerfamily.com
*
*/
public class IssueTO {
private String title;
private String url;
private int weight;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}

View File

@ -0,0 +1,15 @@
package com.jkgroller.githelp.adapter.response;
public class MilestoneTO {
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -0,0 +1,14 @@
package com.jkgroller.githelp.adapter.response;
public class RetrieveGroupResponseTO {
private String groupName;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
}

View File

@ -0,0 +1,16 @@
package com.jkgroller.githelp.adapter.response;
import java.util.List;
public class RetrieveMilestoneIssuesResponseTO {
private List<IssueTO> issueTOs;
public List<IssueTO> getIssueTOs() {
return issueTOs;
}
public void setIssueTOs(List<IssueTO> issueTOs) {
this.issueTOs = issueTOs;
}
}

View File

@ -0,0 +1,16 @@
package com.jkgroller.githelp.adapter.response;
import java.util.List;
public class RetrieveMilestonesResponseTO {
private List<MilestoneTO> milestoneTOs;
public List<MilestoneTO> getMilestoneTOs() {
return milestoneTOs;
}
public void setMilestoneTOs(List<MilestoneTO> milestoneTOs) {
this.milestoneTOs = milestoneTOs;
}
}

View File

@ -0,0 +1,44 @@
package com.jkgroller.githelp.config;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GroupApi;
import org.gitlab4j.api.IssuesApi;
import org.gitlab4j.api.MilestonesApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GitlabConfig {
@Value("${gitlab.url}")
private String gitlabUrl;
@Value("${gitlab.apikey}")
private String gitlabApiKey;
@Autowired
private GitLabApi gitlabApi;
@Bean
public GitLabApi getGitlabApi() {
return new GitLabApi(gitlabUrl, gitlabApiKey);
}
@Bean
public IssuesApi getIssuesApi() {
return gitlabApi.getIssuesApi();
}
@Bean
public GroupApi getGroupsApi() {
return gitlabApi.getGroupApi();
}
@Bean
public MilestonesApi getMilestonesApi() {
return gitlabApi.getMilestonesApi();
}
}

View File

@ -0,0 +1,54 @@
package com.jkgroller.githelp.resource;
import java.util.List;
import com.jkgroller.githelp.resource.attribute.CompletedSprintsAttribute;
import io.crnk.core.resource.annotations.JsonApiId;
import io.crnk.core.resource.annotations.JsonApiResource;
@JsonApiResource(type = "group", resourcePath = "groups")
public class GroupResource {
@JsonApiId
private int groupNumber;
private String groupName;
private int velocity;
private List<CompletedSprintsAttribute> recentlyCompletedSprints;
public int getGroupNumber() {
return groupNumber;
}
public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public int getVelocity() {
return velocity;
}
public void setVelocity(int velocity) {
this.velocity = velocity;
}
public List<CompletedSprintsAttribute> getRecentlyCompletedSprints() {
return recentlyCompletedSprints;
}
public void setRecentlyCompletedSprints(List<CompletedSprintsAttribute> recentlyCompletedSprints) {
this.recentlyCompletedSprints = recentlyCompletedSprints;
}
}

View File

@ -0,0 +1,37 @@
package com.jkgroller.githelp.resource.attribute;
import java.util.List;
public class CompletedSprintsAttribute {
private String title;
private List<CompletedStoryAttribute> completedStories;
private int storyPointsCompleted;
public List<CompletedStoryAttribute> getCompletedStories() {
return completedStories;
}
public void setCompletedStories(List<CompletedStoryAttribute> completedStories) {
this.completedStories = completedStories;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getStoryPointsCompleted() {
return storyPointsCompleted;
}
public void setStoryPointsCompleted(int storyPointsCompleted) {
this.storyPointsCompleted = storyPointsCompleted;
}
}

View File

@ -0,0 +1,42 @@
/**
*
*/
package com.jkgroller.githelp.resource.attribute;
/**
* @author john@grollerfamily.com
*
*/
public class CompletedStoryAttribute {
private String title;
private String url;
private int storyPoints;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getStoryPoints() {
return storyPoints;
}
public void setStoryPoints(int storyPoints) {
this.storyPoints = storyPoints;
}
}

View File

@ -0,0 +1,34 @@
package com.jkgroller.githelp.resource.converter;
import com.jkgroller.githelp.resource.GroupResource;
import com.jkgroller.githelp.resource.attribute.CompletedStoryAttribute;
import com.jkgroller.githelp.service.response.RetrieveScrumInformationResponseTO;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.service.response.StoryTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RetrieveScrumInformationResponseTOConverter extends AbstractConverter<RetrieveScrumInformationResponseTO, GroupResource, Void> {
@Autowired
private SprintTOConverter sprintTOConverter;
@Override
public GroupResource convert(RetrieveScrumInformationResponseTO from, Void context) {
if(null == from){
return null;
}
GroupResource groupResource = new GroupResource();
groupResource.setGroupName(from.getGroupName());
groupResource.setVelocity(from.getVelocity());
groupResource.setRecentlyCompletedSprints(sprintTOConverter.convert(from.getCompletedSprintTOs()));
return groupResource;
}
}

View File

@ -0,0 +1,32 @@
package com.jkgroller.githelp.resource.converter;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.resource.attribute.CompletedSprintsAttribute;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SprintTOConverter extends AbstractConverter<SprintTO, CompletedSprintsAttribute, Void> {
@Autowired
private StoryTOConverter storyTOConverter;
@Override
public CompletedSprintsAttribute convert(SprintTO from, Void context) {
if(null == from){
return null;
}
CompletedSprintsAttribute completedSprintsAttribute = new CompletedSprintsAttribute();
completedSprintsAttribute.setTitle(from.getTitle());
completedSprintsAttribute.setStoryPointsCompleted(from.getStoryPointsCompleted());
completedSprintsAttribute.setCompletedStories(storyTOConverter.convert(from.getCompletedStories()));
return completedSprintsAttribute;
}
}

View File

@ -0,0 +1,29 @@
package com.jkgroller.githelp.resource.converter;
import com.jkgroller.githelp.resource.attribute.CompletedSprintsAttribute;
import com.jkgroller.githelp.resource.attribute.CompletedStoryAttribute;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.service.response.StoryTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.springframework.stereotype.Component;
@Component
public class StoryTOConverter extends AbstractConverter<StoryTO, CompletedStoryAttribute, Void> {
@Override
public CompletedStoryAttribute convert(StoryTO from, Void context) {
if(null == from){
return null;
}
CompletedStoryAttribute completedStoryAttribute = new CompletedStoryAttribute();
completedStoryAttribute.setStoryPoints(from.getPoints());
completedStoryAttribute.setTitle(from.getTitle());
completedStoryAttribute.setUrl(from.getUrl());
return completedStoryAttribute;
}
}

View File

@ -0,0 +1,54 @@
package com.jkgroller.githelp.resource.repository;
import com.jkgroller.githelp.resource.GroupResource;
import com.jkgroller.githelp.resource.converter.RetrieveScrumInformationResponseTOConverter;
import com.jkgroller.githelp.service.ScrumService;
import com.jkgroller.githelp.service.request.RetrieveScrumInformationRequestTO;
import io.crnk.core.exception.MethodNotAllowedException;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class GroupResourceRepository extends ResourceRepositoryBase<GroupResource, Integer> {
@Autowired
private ScrumService scrumService;
@Autowired
private RetrieveScrumInformationResponseTOConverter retrieveScrumInformationResponseTOConverter;
@Value("${number.of.milestones}")
private int numberOfMilestones;
public GroupResourceRepository() {
super(GroupResource.class);
}
@Override
public GroupResource findOne(Integer id, QuerySpec querySpec) {
RetrieveScrumInformationRequestTO retrieveScrumInformationRequestTO = new RetrieveScrumInformationRequestTO();
retrieveScrumInformationRequestTO.setGroupNumber(id);
retrieveScrumInformationRequestTO.setNumberOfMilestonesToReturn(numberOfMilestones);
GroupResource groupResource =
retrieveScrumInformationResponseTOConverter.convert(scrumService.retrieveScrumInformation(retrieveScrumInformationRequestTO));
groupResource.setGroupNumber(id);
return groupResource;
}
@Override
public ResourceList<GroupResource> findAll(QuerySpec querySpec) {
throw new MethodNotAllowedException("Only one group resource is allowed.");
}
}

View File

@ -0,0 +1,10 @@
package com.jkgroller.githelp.service;
import com.jkgroller.githelp.service.request.RetrieveScrumInformationRequestTO;
import com.jkgroller.githelp.service.response.RetrieveScrumInformationResponseTO;
public interface ScrumService {
RetrieveScrumInformationResponseTO retrieveScrumInformation(
RetrieveScrumInformationRequestTO retrieveScrumInformationRequestTO);
}

View File

@ -0,0 +1,131 @@
/**
*
*/
package com.jkgroller.githelp.service;
import com.jkgroller.githelp.adapter.GitlabGroupAdapter;
import com.jkgroller.githelp.adapter.GitlabIssueAdapter;
import com.jkgroller.githelp.adapter.GitlabMilestoneAdapter;
import com.jkgroller.githelp.adapter.request.RetrieveGroupRequestTO;
import com.jkgroller.githelp.adapter.request.RetrieveMilestoneIssuesRequestTO;
import com.jkgroller.githelp.adapter.request.RetrieveMilestonesRequestTO;
import com.jkgroller.githelp.adapter.response.IssueTO;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.adapter.response.RetrieveMilestonesResponseTO;
import com.jkgroller.githelp.service.converter.IssueTOConverter;
import com.jkgroller.githelp.service.converter.MilestoneTOConverter;
import com.jkgroller.githelp.service.request.RetrieveScrumInformationRequestTO;
import com.jkgroller.githelp.service.response.RetrieveScrumInformationResponseTO;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.service.response.StoryTO;
import org.gitlab4j.api.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author john@grollerfamily.com
*
*/
@Service
public class ScrumServiceImpl implements ScrumService {
@Autowired
private GitlabMilestoneAdapter gitlabMilestoneAdapter;
@Autowired
private GitlabIssueAdapter gitlabIssueAdapter;
@Autowired
private GitlabGroupAdapter gitlabGroupAdapter;
@Autowired
private MilestoneTOConverter milestoneTOConverter;
@Autowired
private IssueTOConverter issueTOConverter;
@Override
public RetrieveScrumInformationResponseTO retrieveScrumInformation(
RetrieveScrumInformationRequestTO retrieveGroupInformationRequestTO) {
RetrieveScrumInformationResponseTO retrieveScrumInformationResponseTO = new RetrieveScrumInformationResponseTO();
//retrieve the group name
retrieveScrumInformationResponseTO.setGroupName(retrieveGroupName(retrieveGroupInformationRequestTO));
//retrieve closed sprints
List<SprintTO> sprintTOs = retrieveSprints(retrieveGroupInformationRequestTO);
//update closed sprints with closed stories and story points completed
for(SprintTO sprintTO : sprintTOs){
sprintTO.setCompletedStories(retrieveSprintStories(sprintTO.getTitle()));
sprintTO.setStoryPointsCompleted(calculateStoryPointsCompleted(sprintTO));
}
//sprint stuff all done
retrieveScrumInformationResponseTO.setCompletedSprintTOs(sprintTOs);
//calculate velocity
retrieveScrumInformationResponseTO.setVelocity(calculateVelocity(sprintTOs));
return retrieveScrumInformationResponseTO;
}
private int calculateStoryPointsCompleted(SprintTO sprintTO){
int totalStoryPointsCompleted = 0;
for(StoryTO storyTO : sprintTO.getCompletedStories()){
totalStoryPointsCompleted += storyTO.getPoints();
}
return totalStoryPointsCompleted;
}
private List<SprintTO> retrieveSprints(RetrieveScrumInformationRequestTO retrieveGroupInformationRequestTO) {
RetrieveMilestonesRequestTO retrieveMilestonesRequestTO = new RetrieveMilestonesRequestTO();
retrieveMilestonesRequestTO.setGroupNumber(retrieveGroupInformationRequestTO.getGroupNumber());
retrieveMilestonesRequestTO.setMilestoneState(Constants.MilestoneState.CLOSED);
retrieveMilestonesRequestTO.setNumberOfMilestonesToReturn(5);
RetrieveMilestonesResponseTO retrieveMilestonesResponseTO = gitlabMilestoneAdapter.retrieveMilestones(retrieveMilestonesRequestTO);
return milestoneTOConverter.convert(retrieveMilestonesResponseTO.getMilestoneTOs());
}
private List<StoryTO> retrieveSprintStories(String sprintTitle) {
RetrieveMilestoneIssuesRequestTO retrieveMilestoneIssuesRequestTO = new RetrieveMilestoneIssuesRequestTO();
retrieveMilestoneIssuesRequestTO.setMilestoneTitle(sprintTitle);
return issueTOConverter.convert(gitlabIssueAdapter.retrieveMilestoneIssues(retrieveMilestoneIssuesRequestTO).getIssueTOs());
}
private String retrieveGroupName(RetrieveScrumInformationRequestTO retrieveScrumInformationRequestTO) {
RetrieveGroupRequestTO retrieveGroupRequestTO = new RetrieveGroupRequestTO();
retrieveGroupRequestTO.setGroupNumber(retrieveScrumInformationRequestTO.getGroupNumber());
return gitlabGroupAdapter.retrieveGroup(retrieveGroupRequestTO).getGroupName();
}
private int calculateVelocity(List<SprintTO> sprintTOs){
int totalStoryPointsCompleted = 0;
for(SprintTO sprintTO : sprintTOs){
totalStoryPointsCompleted += sprintTO.getStoryPointsCompleted();
}
return totalStoryPointsCompleted / sprintTOs.size();
}
}

View File

@ -0,0 +1,29 @@
package com.jkgroller.githelp.service.converter;
import com.jkgroller.githelp.adapter.response.IssueTO;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.service.response.StoryTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.springframework.stereotype.Component;
@Component
public class IssueTOConverter extends AbstractConverter<IssueTO, StoryTO, Void> {
@Override
public StoryTO convert(IssueTO from, Void context) {
if(null == from){
return null;
}
StoryTO storyTO = new StoryTO();
storyTO.setTitle(from.getTitle());
storyTO.setUrl(from.getUrl());
storyTO.setPoints(from.getWeight());
return storyTO;
}
}

View File

@ -0,0 +1,24 @@
package com.jkgroller.githelp.service.converter;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import com.jkgroller.githelp.service.response.SprintTO;
import com.jkgroller.githelp.util.AbstractConverter;
import org.gitlab4j.api.models.Milestone;
import org.springframework.stereotype.Component;
@Component
public class MilestoneTOConverter extends AbstractConverter<MilestoneTO, SprintTO, Void> {
@Override
public SprintTO convert(MilestoneTO from, Void context) {
if(null == from){
return null;
}
SprintTO sprintTO = new SprintTO();
sprintTO.setTitle(from.getTitle());
return sprintTO;
}
}

View File

@ -0,0 +1,24 @@
package com.jkgroller.githelp.service.request;
public class RetrieveScrumInformationRequestTO {
private int groupNumber;
private int numberOfMilestonesToReturn = 5;
public int getGroupNumber() {
return groupNumber;
}
public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}
public int getNumberOfMilestonesToReturn() {
return numberOfMilestonesToReturn;
}
public void setNumberOfMilestonesToReturn(int numberOfMilestonesToReturn) {
this.numberOfMilestonesToReturn = numberOfMilestonesToReturn;
}
}

View File

@ -0,0 +1,38 @@
package com.jkgroller.githelp.service.response;
import com.jkgroller.githelp.adapter.response.MilestoneTO;
import java.util.List;
public class RetrieveScrumInformationResponseTO {
private String groupName;
private int velocity;
private List<SprintTO> completedSprintTOs;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public int getVelocity() {
return velocity;
}
public void setVelocity(int velocity) {
this.velocity = velocity;
}
public List<SprintTO> getCompletedSprintTOs() {
return completedSprintTOs;
}
public void setCompletedSprintTOs(List<SprintTO> completedSprintTOs) {
this.completedSprintTOs = completedSprintTOs;
}
}

View File

@ -0,0 +1,46 @@
package com.jkgroller.githelp.service.response;
import java.util.List;
public class SprintTO {
private String title;
private int storyPointsCompleted;
private int numberOfStoriesCompleted;
private List<StoryTO> completedStories;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getStoryPointsCompleted() {
return storyPointsCompleted;
}
public void setStoryPointsCompleted(int storyPointsCompleted) {
this.storyPointsCompleted = storyPointsCompleted;
}
public int getNumberOfStoriesCompleted() {
return numberOfStoriesCompleted;
}
public void setNumberOfStoriesCompleted(int numberOfStoriesCompleted) {
this.numberOfStoriesCompleted = numberOfStoriesCompleted;
}
public List<StoryTO> getCompletedStories() {
return completedStories;
}
public void setCompletedStories(List<StoryTO> completedStories) {
this.completedStories = completedStories;
}
}

View File

@ -0,0 +1,41 @@
/**
*
*/
package com.jkgroller.githelp.service.response;
/**
* @author john@grollerfamily.com
*
*/
public class StoryTO {
private String title;
private String url;
private int points;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}

View File

@ -0,0 +1,76 @@
package com.jkgroller.githelp.util;
/**
* Copyright (c) 2018 John Groller
*/
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class AbstractConverter<F, T, W> implements Converter<F, T, W> {
@Override
public List<T> convert(List<F> fromObjects, W context) {
if (CollectionUtils.isEmpty(fromObjects)) {
return emptyList();
}
List<T> output = new ArrayList<T>();
for (F from : fromObjects) {
if (null == from) {
continue;
}
T value = convert(from, context);
if (null != value) {
output.add(value);
}
}
return output;
}
@SuppressWarnings("unchecked")
private List<T> emptyList() {
return Collections.EMPTY_LIST;
}
@Override
public T convert(F from) {
return convert(from, null);
}
@Override
public List<T> convert(F[] fromObjects, W context) {
if (ArrayUtils.isEmpty(fromObjects)) {
return emptyList();
}
List<T> output = new ArrayList<T>();
for (int idx = 0; fromObjects.length > idx; idx++) {
if (null != fromObjects[idx]) {
T value = convert(fromObjects[idx], context);
if (null != value) {
output.add(value);
}
}
}
return output;
}
@Override
public List<T> convert(List<F> fromObjects) {
return convert(fromObjects, null);
}
@Override
public List<T> convert(F[] fromObjects) {
return convert(fromObjects, null);
}
}

View File

@ -0,0 +1,19 @@
package com.jkgroller.githelp.util;
import java.util.List;
public interface Converter<F, T, C> {
T convert(F from, C context);
T convert(F from);
List<T> convert(List<F> from, C context);
List<T> convert(List<F> from);
List<T> convert(F[] from, C context);
List<T> convert(F[] from);
}

View File

@ -0,0 +1,12 @@
#===============================
# = CRNK
# ===============================
crnk.path-prefix=/v1
crnk.return404-on-null=true
#===============================
# = Gitlab
# ===============================
gitlab.url=https://git.grollerfamily.com
gitlab.apikey=DUmjEJ4hQ2GW_Rkzq4L7
number.of.milestones=5