Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ micronaut {
apiNameSuffix = "Client"
alwaysUseGenerateHttpResponse = true
additionalProperties.put("retryable", "true")
// https://github.com/micronaut-projects/micronaut-openapi/discussions/1783
schemaMapping.put("EventType", "org.justserve.model.EventType")
importMapping.put("EventType", "org.justserve.model.EventType")
schemaMapping.put("ProjectLocationType", "org.justserve.model.ProjectLocationType")
importMapping.put("ProjectLocationType", "org.justserve.model.ProjectLocationType")
}
}
processing {
Expand Down
148 changes: 148 additions & 0 deletions core/src/main/java/org/justserve/client/GraphQLClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package org.justserve.client;

import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.retry.annotation.Retryable;
import org.justserve.model.*;

@Produces("application/json")
@Consumes("application/graphql-response+json; charset=utf-8")
@Retryable
@Client("justserve")
public interface GraphQLClient {

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLAddProjectAttachmentData> executeAddProjectAttachment(@Body GraphQLAddProjectAttachmentRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLAddProjectOrganizationData> executeAddProjectOrganization(@Body GraphQLAddProjectOrganizationRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLCombinedMutationUpdateProjectAddProjectTagData> executeCombinedMutationUpdateProjectAddProjectTag(@Body GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLCreateEventData> executeCreateEvent(@Body GraphQLCreateEventRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLCreateProjectData> executeCreateProject(@Body GraphQLCreateProjectRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLPublishProjectData> executePublishProject(@Body GraphQLPublishProjectRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLSearchOrganizationData> executeSearchOrganization(@Body GraphQLSearchOrganizationRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLSetProjectLocationData> executeSetProjectLocation(@Body GraphQLSetProjectLocationRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLUpdateProjectAttachmentData> executeUpdateProjectAttachment(@Body GraphQLUpdateProjectAttachmentRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLUpdateProjectListingData> executeUpdateProjectListing(@Body GraphQLUpdateProjectListingRequest request);

@Post("/graphql")
@Consumes("application/graphql-response+json")
GraphQLResponse<GraphQLUpdateProjectData> executeUpdateProject(@Body GraphQLUpdateProjectRequest request);

default GraphQLResponse<GraphQLAddProjectAttachmentData> addProjectAttachment(GraphQLAddProjectAttachmentVariables variables) {
String fixedQuery = "mutation ($projectId: ID!, $attachmentId: ID!) {\n addProjectAttachment(projectId: $projectId, attachmentId: $attachmentId) {\n attachmentId\n }\n }";
GraphQLAddProjectAttachmentRequest request = new GraphQLAddProjectAttachmentRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeAddProjectAttachment(request);
}

default GraphQLResponse<GraphQLAddProjectOrganizationData> addProjectOrganization(GraphQLAddProjectOrganizationVariables variables) {
String fixedQuery = "mutation addProjectOrganization($organizationId: ID!, $projectId: ID!) {\n addProjectOrganization(organizationId: $organizationId, projectId: $projectId) {\n id\n organizations {\n id\n name\n }\n }\n }";
GraphQLAddProjectOrganizationRequest request = new GraphQLAddProjectOrganizationRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeAddProjectOrganization(request);
}

default GraphQLResponse<GraphQLCombinedMutationUpdateProjectAddProjectTagData> combinedMutationUpdateProjectAddProjectTag(GraphQLCombinedMutationUpdateProjectAddProjectTagVariables variables) {
String fixedQuery = "mutation combinedMutation($projectId: ID!, $modify: UpdateProjectInput!) {\n updateProject(\n id: $projectId,\n modify: $modify\n ) {\n id\n wheelchairAccessible\n itemDonations\n indoors\n longDescription\n shortDescription\n sponsorUserId\n groupProjects\n }\n\n skill0: addProjectTag(\n projectId: $projectId\n tagId: 31\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\nskill1: addProjectTag(\n projectId: $projectId\n tagId: 46\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\n\n interest0: addProjectTag(\n projectId: $projectId\n tagId: 11\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\ninterest1: addProjectTag(\n projectId: $projectId\n tagId: 26\n ) {\n id\n tags {\n id\n tagType\n tagTypeId\n translations(languageId: 1) {\n description\n label\n languageId\n }\n }\n }\n }";
GraphQLCombinedMutationUpdateProjectAddProjectTagRequest request = new GraphQLCombinedMutationUpdateProjectAddProjectTagRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeCombinedMutationUpdateProjectAddProjectTag(request);
}

default GraphQLResponse<GraphQLCreateEventData> createEvent(GraphQLCreateEventVariables variables) {
String fixedQuery = "mutation createEvent($projectId: ID!, $projectEvent: UpdateProjectEventInput!) {\n createEvent(\n projectId: $projectId\n projectEvent: $projectEvent\n ) {\n id\n projectId\n contactEmail\n contactName\n contactPhone\n start\n end\n groupCap\n groupLimit\n timezone\n totalVolunteersNeeded\n volunteerCap\n }\n }";
GraphQLCreateEventRequest request = new GraphQLCreateEventRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeCreateEvent(request);
}

default GraphQLResponse<GraphQLCreateProjectData> createProject(GraphQLCreateProjectVariables variables) {
String fixedQuery = "mutation createProject($title: String!, $eventType: ProjectType!, $locationType: ProjectLocationType!, $redirect: String) {\n createProject(\n title: $title\n eventType: $eventType\n locationType: $locationType\n redirect: $redirect\n ) {\n id\n title\n typeId\n locationTypeId\n externalVolunteerUrl\n statusId\n }\n }";
GraphQLCreateProjectRequest request = new GraphQLCreateProjectRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeCreateProject(request);
}

default GraphQLResponse<GraphQLPublishProjectData> publishProject(GraphQLPublishProjectVariables variables) {
String fixedQuery = "mutation ($projectId: ID!){\n publishProject(projectId: $projectId) {\n id\n statusId\n }\n }";
GraphQLPublishProjectRequest request = new GraphQLPublishProjectRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executePublishProject(request);
}

default GraphQLResponse<GraphQLSearchOrganizationData> searchOrganization(GraphQLSearchOrganizationVariables variables) {
String fixedQuery = "\n query organization(\n $searchTerm: String!\n $includeAll: Boolean\n $activeOnly: Boolean\n ) {\n adminOrganizationSearchByTitle(\n activeOnly: $activeOnly\n includeAll: $includeAll\n title: $searchTerm\n ) {\n id\n name\n logo\n description\n contactName\n contactPhone\n contactEmail\n url\n location {\n displayCity\n displayState\n }\n }\n }\n ";
GraphQLSearchOrganizationRequest request = new GraphQLSearchOrganizationRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeSearchOrganization(request);
}

default GraphQLResponse<GraphQLSetProjectLocationData> setProjectLocation(GraphQLSetProjectLocationVariables variables) {
String fixedQuery = "mutation setProjectLocation($projectId: ID!, $location: String, $locationData: LocationDataInput) {\n setProjectLocation(\n projectId: $projectId\n location: $location\n locationData: $locationData\n ) {\n displayAddress\n displayAddress2\n displayCity\n displayCountry\n displayCountryCode\n displayCounty\n displayNeighborhood\n displayPostalCode\n displayState\n id\n latitude\n locationDetails\n locationName\n longitude\n maxLatitude\n maxLongitude\n minLatitude\n minLongitude\n timezone\n civicGeography {\n state {\n code\n }\n }\n churchGeography {\n areaUnitId\n ccUnitId\n missionUnitId\n stakeUnitId\n }\n }\n }";
GraphQLSetProjectLocationRequest request = new GraphQLSetProjectLocationRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeSetProjectLocation(request);
}

default GraphQLResponse<GraphQLUpdateProjectAttachmentData> updateProjectAttachment(GraphQLUpdateProjectAttachmentVariables variables) {
String fixedQuery = "mutation ($attachmentId: ID!, $title: String!, $description: String!) {\n updateProjectAttachment(attachmentId: $attachmentId, title: $title, description: $description) {\n attachmentId\n }\n }";
GraphQLUpdateProjectAttachmentRequest request = new GraphQLUpdateProjectAttachmentRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeUpdateProjectAttachment(request);
}

default GraphQLResponse<GraphQLUpdateProjectListingData> updateProjectListing(GraphQLUpdateProjectListingVariables variables) {
String fixedQuery = "mutation listing ($projectId: ID!, $unlisted: Boolean!) {\n updateProjectListing(projectId: $projectId, unlisted: $unlisted) {\n id\n unlisted\n }\n }";
GraphQLUpdateProjectListingRequest request = new GraphQLUpdateProjectListingRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeUpdateProjectListing(request);
}

default GraphQLResponse<GraphQLUpdateProjectData> updateProject(GraphQLUpdateProjectVariables variables) {
String fixedQuery = "mutation ($projectId: ID!, $logo: String!) {\n updateProject(id: $projectId, modify: { logo: $logo }) {\n id\n logo\n }\n }";
GraphQLUpdateProjectRequest request = new GraphQLUpdateProjectRequest();
request.setQuery(fixedQuery);
request.setVariables(variables);
return this.executeUpdateProject(request);
}
}
59 changes: 59 additions & 0 deletions core/src/main/java/org/justserve/model/EventType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.justserve.model;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import io.micronaut.serde.annotation.Serdeable;
import jakarta.annotation.Generated;
import lombok.RequiredArgsConstructor;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Gets or Sets EventType
*/
@RequiredArgsConstructor
@Serdeable
@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen")
public enum EventType {
// None(0, "None"),
DTL(1, "DTL"),
Ongoing(2, "ONGOING"),
Recurring(3, "RECURRING"),
MultipleDTL(4, "MULTIPLE_DTL");

public static final Map<Integer, EventType> VALUE_MAPPING = Map.copyOf(Arrays.stream(values())
.collect(Collectors.toMap(v -> v.intValue, Function.identity())));

private final Integer intValue;
private final String stringValue;

@Override
public String toString() {
return String.valueOf(intValue);
}

@JsonValue
public String getStringValue() {
return stringValue;
}

// 2. RECEIVING (Response): This catches the incoming data.
// It can handle the Integer '1' from GraphQL, or even a String if a REST endpoint sends one.
@JsonCreator
public static EventType fromValue(Object value) {
if (value instanceof Number) {
int intVal = ((Number) value).intValue();
for (EventType type : values()) {
if (type.intValue == intVal) return type;
}
} else if (value instanceof String strVal) {
for (EventType type : values()) {
if (type.stringValue.equalsIgnoreCase(strVal)) return type;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "' for EventType");
}
}
18 changes: 18 additions & 0 deletions core/src/main/java/org/justserve/model/GraphQLRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.justserve.model;

import io.micronaut.serde.annotation.Serdeable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Serdeable
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GraphQLRequest {

private String query;

// This handles dynamic variable maps/objects
private Object variables;
}
23 changes: 23 additions & 0 deletions core/src/main/java/org/justserve/model/GraphQLResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.justserve.model;

import io.micronaut.serde.annotation.Serdeable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Serdeable
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GraphQLResponse<T> {

private T data;

private List<Object> errors;

public boolean hasErrors() {
return errors != null && !errors.isEmpty();
}
}
53 changes: 53 additions & 0 deletions core/src/main/java/org/justserve/model/ProjectLocationType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.justserve.model;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import io.micronaut.serde.annotation.Serdeable;
import jakarta.annotation.Generated;
import lombok.RequiredArgsConstructor;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Serdeable
@Generated("io.micronaut.openapi.generator.JavaMicronautClientCodegen")
public enum ProjectLocationType {
// NONE(0, "NONE"),
SINGLE_LOCATION(1, "SINGLE_LOCATION"),
REGIONAL(3, "REGIONAL"),
REMOTE(4, "REMOTE");

public static final Map<Integer, ProjectLocationType> VALUE_MAPPING = Map.copyOf(Arrays.stream(values())
.collect(Collectors.toMap(v -> v.intValue, Function.identity())));

private final Integer intValue;
private final String stringValue;

@Override
public String toString() {
return String.valueOf(intValue);
}

@JsonValue
public String getStringValue() {
return stringValue;
}

@JsonCreator
public static ProjectLocationType fromValue(Object value) {
if (value instanceof Number) {
int intVal = ((Number) value).intValue();
for (ProjectLocationType type : values()) {
if (type.intValue == intVal) return type;
}
} else if (value instanceof String strVal) {
for (ProjectLocationType type : values()) {
if (type.stringValue.equalsIgnoreCase(strVal)) return type;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "' for ProjectLocationType");
}
}
4 changes: 4 additions & 0 deletions core/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ micronaut:
enabled: true
acquire-timeout: 30s
max-connections: 100
codec:
json:
additional-types:
- application/graphql-response+json
justserve:
token: ${:i-need-to-be-defined}
jackson:
Expand Down
Loading
Loading