Skip to content
Snippets Groups Projects
Commit 12dd3e01 authored by Martin Lowe's avatar Martin Lowe :flag_ca:
Browse files

Add initial implementation

parent 75082cf7
No related branches found
No related tags found
1 merge request!1Add initial implementation of API
package org.eclipsefoundation.mailing.dto;
import java.util.Date;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.ws.rs.core.MultivaluedMap;
import org.eclipsefoundation.persistence.dto.BareNode;
import org.eclipsefoundation.persistence.dto.filter.DtoFilter;
import org.eclipsefoundation.persistence.model.DtoTable;
import org.eclipsefoundation.persistence.model.ParameterizedSQLStatement;
import org.eclipsefoundation.persistence.model.ParameterizedSQLStatementBuilder;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
@Table
@Entity
public class MailingLists extends BareNode {
public static final DtoTable TABLE = new DtoTable(MailingLists.class, "ml");
@Id
@Nonnull
private String listName;
private String listDescription;
@Nonnull
private String projectId;
private String listShortDescription;
@Nonnull
private boolean createArchives;
@Nonnull
private boolean isForNewsArchives;
@Nonnull
private boolean isDisabled;
@Nonnull
private boolean isDeleted;
@Nonnull
private boolean isPrivate;
@Nonnull
private boolean isSubscribable;
private Date createDate;
private String createdBy;
private String provisionStatus;
@JsonInclude(value = Include.NON_NULL)
@Transient
private Long count;
@Transient
private String url;
@Transient
private String email;
@PostLoad
public void loadAdditionalProperties() {
this.url = "https://accounts.eclipse.org/mailing-list/" + listName;
this.email = listName + "@eclipse.org";
}
@JsonIgnore
@Override
public Object getId() {
return getListName();
}
/**
* @return the listName
*/
public String getListName() {
return listName;
}
/**
* @param listName the listName to set
*/
public void setListName(String listName) {
this.listName = listName;
}
/**
* @return the listDescription
*/
public String getListDescription() {
return listDescription;
}
/**
* @param listDescription the listDescription to set
*/
public void setListDescription(String listDescription) {
this.listDescription = listDescription;
}
/**
* @return the projectId
*/
public String getProjectId() {
return projectId;
}
/**
* @param projectId the projectId to set
*/
public void setProjectId(String projectId) {
this.projectId = projectId;
}
/**
* @return the listShortDescription
*/
public String getListShortDescription() {
return listShortDescription;
}
/**
* @param listShortDescription the listShortDescription to set
*/
public void setListShortDescription(String listShortDescription) {
this.listShortDescription = listShortDescription;
}
/**
* @return the createArchives
*/
public boolean isCreateArchives() {
return createArchives;
}
/**
* @param createArchives the createArchives to set
*/
public void setCreateArchives(boolean createArchives) {
this.createArchives = createArchives;
}
/**
* @return the isForNewsArchives
*/
public boolean isForNewsArchives() {
return isForNewsArchives;
}
/**
* @param isForNewsArchives the isForNewsArchives to set
*/
public void setForNewsArchives(boolean isForNewsArchives) {
this.isForNewsArchives = isForNewsArchives;
}
/**
* @return the isDisabled
*/
public boolean isDisabled() {
return isDisabled;
}
/**
* @param isDisabled the isDisabled to set
*/
public void setDisabled(boolean isDisabled) {
this.isDisabled = isDisabled;
}
/**
* @return the isDeleted
*/
public boolean isDeleted() {
return isDeleted;
}
/**
* @param isDeleted the isDeleted to set
*/
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
/**
* @return the isPrivate
*/
public boolean isPrivate() {
return isPrivate;
}
/**
* @param isPrivate the isPrivate to set
*/
public void setPrivate(boolean isPrivate) {
this.isPrivate = isPrivate;
}
/**
* @return the isSubscribable
*/
public boolean isSubscribable() {
return isSubscribable;
}
/**
* @param isSubscribable the isSubscribable to set
*/
public void setSubscribable(boolean isSubscribable) {
this.isSubscribable = isSubscribable;
}
/**
* @return the createDate
*/
public Date getCreateDate() {
return createDate;
}
/**
* @param createDate the createDate to set
*/
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
/**
* @return the createdBy
*/
public String getCreatedBy() {
return createdBy;
}
/**
* @param createdBy the createdBy to set
*/
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
/**
* @return the provisionStatus
*/
public String getProvisionStatus() {
return provisionStatus;
}
/**
* @param provisionStatus the provisionStatus to set
*/
public void setProvisionStatus(String provisionStatus) {
this.provisionStatus = provisionStatus;
}
/**
* @return the count
*/
public Long getCount() {
return count;
}
/**
* @param count the count to set
*/
public void setCount(Long count) {
this.count = count;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}
/**
* @return the email
*/
public String getEmail() {
return email;
}
/**
* @param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
@Singleton
public static class MailingListFilter implements DtoFilter<MailingLists> {
@Inject
ParameterizedSQLStatementBuilder builder;
@Override
public ParameterizedSQLStatement getFilters(MultivaluedMap<String, String> params, boolean isRoot) {
ParameterizedSQLStatement stmt = builder.build(TABLE);
if (isRoot) {
// ID check
String id = params.getFirst("list_name");
if (id != null) {
stmt.addClause(new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".listName = ?",
new Object[] { id }));
}
// project ID check
String projectId = params.getFirst("project_id");
if (projectId != null) {
stmt.addClause(new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".projectId = ?",
new Object[] { projectId }));
}
// subscribable check
boolean isSubscribable = Boolean.parseBoolean(params.getFirst("is_subscribable"));
if (isSubscribable) {
stmt.addClause(new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".isSubscribable = ?",
new Object[] { isSubscribable }));
}
// is private check
boolean isPrivate = Boolean.parseBoolean(params.getFirst("is_private"));
if (isPrivate) {
stmt.addClause(new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".isPrivate = ?",
new Object[] { isPrivate }));
}
// is deleted check
boolean isDeleted = Boolean.parseBoolean(params.getFirst("is_deleted"));
if (isDeleted) {
stmt.addClause(new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".isDeleted = ?",
new Object[] { isDeleted }));
}
}
return stmt;
}
@Override
public Class<MailingLists> getType() {
return MailingLists.class;
}
}
}
package org.eclipsefoundation.mailing.resources;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.eclipsefoundation.core.model.RequestWrapper;
import org.eclipsefoundation.core.service.CachingService;
import org.eclipsefoundation.mailing.dto.MailingListSubscriptions;
import org.eclipsefoundation.mailing.dto.MailingLists;
import org.eclipsefoundation.persistence.dao.impl.DefaultHibernateDao;
import org.eclipsefoundation.persistence.model.RDBMSQuery;
import org.eclipsefoundation.persistence.service.FilterService;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
@Path("/mailing_lists")
@Produces(MediaType.APPLICATION_JSON)
public class MailingListsResource {
@Inject
DefaultHibernateDao dao;
@Inject
FilterService filters;
@Inject
CachingService cache;
@Inject
RequestWrapper wrap;
@GET
public Response all() {
List<MailingLists> mailingLists = dao.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class)));
return Response.ok(mailingLists).build();
}
@GET
@Path("{listName}")
public Response mailingList(@PathParam("listName") String listName) {
MultivaluedMap<String, String> params = new MultivaluedMapImpl<>();
params.add("list_name", listName);
List<MailingLists> mailingLists = dao.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class), params));
if (mailingLists.isEmpty()) {
return Response.status(404).build();
}
// add count to singular mailing list retrieval
MailingLists ml = mailingLists.get(0);
ml.setCount(dao.count(new RDBMSQuery<>(wrap, filters.get(MailingListSubscriptions.class), params)));
return Response.ok(ml).build();
}
@GET
@Path("available")
public Response available() {
List<MailingLists> mailingLists = dao
.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class), getDefaultParams()));
return Response.ok(mailingLists).build();
}
@GET
@Path("projects")
public Response getByProjects(@PathParam("projectId") String projectId) {
List<MailingLists> mailingLists = dao.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class)));
if (mailingLists.isEmpty()) {
return Response.ok(Collections.emptyList()).build();
}
return Response.ok(mailingLists.stream().collect(Collectors.groupingBy(MailingLists::getProjectId))).build();
}
@GET
@Path("projects/{projectId:\\d*}")
public Response getForProjectByID(@PathParam("projectId") String projectId) {
List<MailingLists> mailingLists = dao.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class)));
if (mailingLists.isEmpty()) {
return Response.ok(Collections.emptyList()).build();
}
return Response.ok(mailingLists).build();
}
@GET
@Path("projects/available")
public Response getByProjectsAvailable(@PathParam("projectId") String projectId) {
List<MailingLists> mailingLists = dao
.get(new RDBMSQuery<>(wrap, filters.get(MailingLists.class), getDefaultParams()));
if (mailingLists.isEmpty()) {
return Response.ok(Collections.emptyList()).build();
}
return Response.ok(mailingLists.stream().collect(Collectors.groupingBy(MailingLists::getProjectId))).build();
}
/**
* Gets default params for available mailing lists
* @return
*/
private MultivaluedMap<String, String> getDefaultParams() {
MultivaluedMap<String, String> params = new MultivaluedMapImpl<>();
params.add("is_private", Boolean.FALSE.toString());
params.add("is_deleted", Boolean.FALSE.toString());
params.add("is_disabled", Boolean.FALSE.toString());
params.add("is_subscribable", Boolean.TRUE.toString());
return params;
}
}
\ No newline at end of file
/**
* Copyright (c) 2021 Eclipse
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Martin Lowe <martin.lowe@eclipsefoundation.org>
*
* SPDX-License-Identifier: EPL-2.0
*/
const toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema');
const Resolver = require('@stoplight/json-ref-resolver');
const yaml = require('js-yaml');
const fs = require('fs');
const decamelize = require('decamelize');
const args = require('yargs')
.option('s', {
alias: 'src',
desc: 'The fully qualified path to the YAML spec.',
})
.option('t', {
alias: 'target',
desc: 'The fully qualified path to write the JSON schema to',
}).argv;
if (!args.s || !args.t) {
process.exit(1);
}
run();
/**
* Generates JSON schema files for consumption of the Java tests.
*/
async function run() {
try {
// load in the openapi yaml spec as an object
const doc = yaml.load(fs.readFileSync(args.s, 'utf8'));
// resolve $refs in openapi spec
let resolvedInp = await new Resolver.Resolver().resolve(doc);
const out = toJsonSchema(resolvedInp.result);
// if folder doesn't exist, create it
if (!fs.existsSync(`${args.t}/schemas`)) {
fs.mkdirSync(`${args.t}/schemas`);
}
// for each of the schemas, generate a JSON schema file
for (let schemaName in out.components.schemas) {
fs.writeFileSync(`${args.t}/schemas/${decamelize(schemaName, { separator: '-' })}-schema.json`, JSON.stringify(out.components.schemas[schemaName]));
}
} catch (e) {
console.log(e);
}
}
src/main/resources/META-INF/resources/favicon.ico

1.12 KiB

quarkus.log.level=INFO
quarkus.http.port=8090
quarkus.http.cors=true
security.csrf.enabled=true
## DATASOURCE CONFIG
eclipse.db.default.limit=10
eclipse.db.default.limit.max=100
quarkus.datasource.db-kind=mariadb
quarkus.datasource.jdbc.min-size = 5
quarkus.datasource.jdbc.max-size = 15
quarkus.oauth2.enabled=false
quarkus.oidc.application-type=web-app
quarkus.oidc.token.refresh-expired=true
quarkus.oidc.authentication.session-age-extension=60m
quarkus.oidc.discovery-enabled=true
quarkus.oidc.roles.source=accesstoken
# Tells Quarkus which objects are associated with what databases (used to generate entity tables internally)
quarkus.hibernate-orm.packages=org.eclipsefoundation.mailing.dto
quarkus.hibernate-orm.datasource=<default>
quarkus.hibernate-orm.physical-naming-strategy=org.eclipsefoundation.mailing.config.DefaultPhysicalNamingStrategy
\ No newline at end of file
quarkus.log.level=INFO
quarkus.http.port=8090
quarkus.http.cors=true
security.csrf.enabled=true
## DATASOURCE CONFIG
eclipse.db.default.limit=10
eclipse.db.default.limit.max=100
quarkus.datasource.db-kind=mariadb
quarkus.datasource.jdbc.min-size = 5
quarkus.datasource.jdbc.max-size = 15
quarkus.oauth2.enabled=false
quarkus.oidc.application-type=web-app
quarkus.oidc.token.refresh-expired=true
quarkus.oidc.authentication.session-age-extension=60m
quarkus.oidc.discovery-enabled=true
quarkus.oidc.roles.source=accesstoken
# Tells Quarkus which objects are associated with what databases (used to generate entity tables internally)
quarkus.hibernate-orm.packages=org.eclipsefoundation.mailing.dto
quarkus.hibernate-orm.datasource=<default>
quarkus.hibernate-orm.physical-naming-strategy=org.eclipsefoundation.mailing.config.DefaultPhysicalNamingStrategy
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment