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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Keep Spotless line endings stable across operating systems.
*.java text eol=lf
30 changes: 30 additions & 0 deletions .github/workflows/check_java_formatting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Check Java source hygiene

on:
push:
branches:
- master
- develop
- release
pull_request:
paths:
- "**/*.java"
- ".gitattributes"
- ".github/workflows/check_java_formatting.yml"
- "pom.xml"

jobs:
source-hygiene:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
cache: maven
- name: Check Java source hygiene
run: mvn -B -ntp spotless:check
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ configurations, such as:

## Development

### Java source hygiene

We currently use minimal spotless rules, which are checked in the CI.

Apply or check these rules from the repository root:

```bash
mvn spotless:apply
mvn spotless:check
```

Install the repository's pre-push check once per clone:

```bash
mvn spotless:install-git-pre-push-hook
```

### Testing

#### Integration Tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.stream.Stream;

import com.google.common.base.Joiner;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -24,23 +23,23 @@ public void close() throws IOException {
public void heading(String str) throws IOException {
line("\n# "+str);
}

public void subHeading(String str) throws IOException {
line("\n---\n\n## "+str);
}

public void subSubHeading(String str) throws IOException {
line("\n### "+str);
}

public void tableHeader(String... header) throws IOException {
line("\n| "+Joiner.on(" | ").join(header)+" |");
line("| "+Stream.generate(()->"---").limit(header.length).collect(Collectors.joining(" | "))+" |");
}
public void table(String... values) throws IOException {
line("| "+Joiner.on(" | ").join(values)+" | ");
}

public void paragraph(String str) throws IOException {
line(str+"\n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ static Introspection from(File root, ClassInfo cl) {
return new SimpleIntrospection(f);
}
}


CompilationUnit cu = StaticJavaParser.parse(f);

TypeDeclaration<?> typeDeclaration = cu.getPrimaryType().get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public class SimpleIntrospection implements Introspection {

private final File file;

@Override
public String getDescription() {
return "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ public class Group {
private List<Class<?>> hides;
@Singular
private List<Class<?>> markerInterfaces;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public interface AdditionalMediaTypes {

static final String CSV = "text/csv; charset=utf-8";
static final String EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

// As proposed in https://issues.apache.org/jira/browse/ARROW-7396
static final String ARROW_STREAM = "application/vnd.apache.arrow.stream";
static final String ARROW_FILE = "application/vnd.apache.arrow.file";
Expand Down
174 changes: 87 additions & 87 deletions backend/src/main/java/com/bakdata/conquery/apiv1/ApiV1.java
Original file line number Diff line number Diff line change
@@ -1,87 +1,87 @@
package com.bakdata.conquery.apiv1;
import com.bakdata.conquery.commands.ManagerNode;
import com.bakdata.conquery.io.cps.CPSType;
import com.bakdata.conquery.io.jersey.IdPathParamConverterProvider;
import com.bakdata.conquery.io.jetty.CORSPreflightRequestFilter;
import com.bakdata.conquery.io.jetty.CORSResponseFilter;
import com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider;
import com.bakdata.conquery.metrics.ActiveUsersFilter;
import com.bakdata.conquery.models.auth.basic.JWTokenHandler;
import com.bakdata.conquery.models.auth.web.AuthFilter;
import com.bakdata.conquery.models.forms.frontendconfiguration.FormConfigProcessor;
import com.bakdata.conquery.models.forms.frontendconfiguration.FormProcessor;
import com.bakdata.conquery.resources.ResourcesProvider;
import com.bakdata.conquery.resources.api.ConceptResource;
import com.bakdata.conquery.resources.api.ConceptsProcessor;
import com.bakdata.conquery.resources.api.ConfigResource;
import com.bakdata.conquery.resources.api.DatasetFormConfigResource;
import com.bakdata.conquery.resources.api.DatasetFormResource;
import com.bakdata.conquery.resources.api.DatasetQueryResource;
import com.bakdata.conquery.resources.api.DatasetResource;
import com.bakdata.conquery.resources.api.DatasetsResource;
import com.bakdata.conquery.resources.api.FilterResource;
import com.bakdata.conquery.resources.api.FormConfigResource;
import com.bakdata.conquery.resources.api.MeResource;
import com.bakdata.conquery.resources.api.QueryResource;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
@CPSType(base = ResourcesProvider.class, id = "ApiV1")
public class ApiV1 extends ResourceConfig implements ResourcesProvider {
@Override
public void registerResources(ManagerNode manager) {
final JerseyEnvironment jersey = manager.getEnvironment().jersey();
// TODO this does not work, if we really want to do api versioning
jersey.setUrlPattern("/api");
// Inject Processors
jersey.register(new AbstractBinder() {
@Override
protected void configure() {
bindAsContract(QueryProcessor.class);
bindAsContract(ConceptsProcessor.class);
bindAsContract(MeProcessor.class);
bindAsContract(FormConfigProcessor.class);
bindAsContract(FormProcessor.class);
}
});
jersey.register(CORSPreflightRequestFilter.class);
jersey.register(CORSResponseFilter.class);
jersey.register(ActiveUsersFilter.class);
/*
* Register the authentication filter which protects all resources registered in this servlet.
* We use the same instance of the filter for the api servlet and the admin servlet to have a single
* point for authentication.
*/
jersey.register(AuthFilter.class);
AuthFilter.registerTokenExtractor(JWTokenHandler.JWTokenExtractor.class, jersey.getResourceConfig());
jersey.register(IdPathParamConverterProvider.class);
jersey.register(QueryResource.class);
jersey.register(DatasetQueryResource.class);
jersey.register(DatasetFormConfigResource.class);
jersey.register(ConfigResource.class);
jersey.register(FormConfigResource.class);
jersey.register(DatasetFormResource.class);
jersey.register(DatasetsResource.class);
jersey.register(ConceptResource.class);
jersey.register(DatasetResource.class);
jersey.register(FilterResource.class);
jersey.register(MeResource.class);
for (ResultRendererProvider resultProvider : manager.getConfig().getResultProviders()) {
resultProvider.registerResultResource(jersey.getResourceConfig(), manager);
}
}
}
package com.bakdata.conquery.apiv1;

import com.bakdata.conquery.commands.ManagerNode;
import com.bakdata.conquery.io.cps.CPSType;
import com.bakdata.conquery.io.jersey.IdPathParamConverterProvider;
import com.bakdata.conquery.io.jetty.CORSPreflightRequestFilter;
import com.bakdata.conquery.io.jetty.CORSResponseFilter;
import com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider;
import com.bakdata.conquery.metrics.ActiveUsersFilter;
import com.bakdata.conquery.models.auth.basic.JWTokenHandler;
import com.bakdata.conquery.models.auth.web.AuthFilter;
import com.bakdata.conquery.models.forms.frontendconfiguration.FormConfigProcessor;
import com.bakdata.conquery.models.forms.frontendconfiguration.FormProcessor;
import com.bakdata.conquery.resources.ResourcesProvider;
import com.bakdata.conquery.resources.api.ConceptResource;
import com.bakdata.conquery.resources.api.ConceptsProcessor;
import com.bakdata.conquery.resources.api.ConfigResource;
import com.bakdata.conquery.resources.api.DatasetFormConfigResource;
import com.bakdata.conquery.resources.api.DatasetFormResource;
import com.bakdata.conquery.resources.api.DatasetQueryResource;
import com.bakdata.conquery.resources.api.DatasetResource;
import com.bakdata.conquery.resources.api.DatasetsResource;
import com.bakdata.conquery.resources.api.FilterResource;
import com.bakdata.conquery.resources.api.FormConfigResource;
import com.bakdata.conquery.resources.api.MeResource;
import com.bakdata.conquery.resources.api.QueryResource;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;

@CPSType(base = ResourcesProvider.class, id = "ApiV1")
public class ApiV1 extends ResourceConfig implements ResourcesProvider {

@Override
public void registerResources(ManagerNode manager) {

final JerseyEnvironment jersey = manager.getEnvironment().jersey();
// TODO this does not work, if we really want to do api versioning
jersey.setUrlPattern("/api");

// Inject Processors
jersey.register(new AbstractBinder() {
@Override
protected void configure() {
bindAsContract(QueryProcessor.class);
bindAsContract(ConceptsProcessor.class);
bindAsContract(MeProcessor.class);
bindAsContract(FormConfigProcessor.class);
bindAsContract(FormProcessor.class);
}
});

jersey.register(CORSPreflightRequestFilter.class);
jersey.register(CORSResponseFilter.class);

jersey.register(ActiveUsersFilter.class);


/*
* Register the authentication filter which protects all resources registered in this servlet.
* We use the same instance of the filter for the api servlet and the admin servlet to have a single
* point for authentication.
*/
jersey.register(AuthFilter.class);
AuthFilter.registerTokenExtractor(JWTokenHandler.JWTokenExtractor.class, jersey.getResourceConfig());

jersey.register(IdPathParamConverterProvider.class);

jersey.register(QueryResource.class);
jersey.register(DatasetQueryResource.class);
jersey.register(DatasetFormConfigResource.class);
jersey.register(ConfigResource.class);
jersey.register(FormConfigResource.class);
jersey.register(DatasetFormResource.class);

jersey.register(DatasetsResource.class);
jersey.register(ConceptResource.class);
jersey.register(DatasetResource.class);
jersey.register(FilterResource.class);
jersey.register(MeResource.class);

for (ResultRendererProvider resultProvider : manager.getConfig().getResultProviders()) {
resultProvider.registerResultResource(jersey.getResourceConfig(), manager);
}

}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
package com.bakdata.conquery.apiv1;
import java.util.function.Consumer;
import com.bakdata.conquery.io.storage.MetaStorage;
import com.bakdata.conquery.models.auth.entities.Subject;
import com.bakdata.conquery.models.auth.permissions.Ability;
import com.bakdata.conquery.models.forms.configs.FormConfig;
import com.bakdata.conquery.util.QueryUtils;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* Specific class to also patch the values stored in a {@link FormConfig}.
*/
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class FormConfigPatch extends MetaDataPatch {
private JsonNode values;
public void applyTo(FormConfig instance, MetaStorage storage, Subject subject){
chain(QueryUtils.getNoOpEntryPoint(), storage, subject, instance)
.accept(this);
}
protected Consumer<FormConfigPatch> chain(Consumer<FormConfigPatch> patchConsumerChain, MetaStorage storage, Subject subject, FormConfig instance) {
patchConsumerChain = super.buildChain(patchConsumerChain, storage, subject, instance);
if(getValues() != null && subject.isPermitted(instance,Ability.MODIFY)) {
patchConsumerChain = patchConsumerChain.andThen(instance.valueSetter());
}
return patchConsumerChain;
}
}
package com.bakdata.conquery.apiv1;

import java.util.function.Consumer;

import com.bakdata.conquery.io.storage.MetaStorage;
import com.bakdata.conquery.models.auth.entities.Subject;
import com.bakdata.conquery.models.auth.permissions.Ability;
import com.bakdata.conquery.models.forms.configs.FormConfig;
import com.bakdata.conquery.util.QueryUtils;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

/**
* Specific class to also patch the values stored in a {@link FormConfig}.
*/
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class FormConfigPatch extends MetaDataPatch {
private JsonNode values;

public void applyTo(FormConfig instance, MetaStorage storage, Subject subject){
chain(QueryUtils.getNoOpEntryPoint(), storage, subject, instance)
.accept(this);
}

protected Consumer<FormConfigPatch> chain(Consumer<FormConfigPatch> patchConsumerChain, MetaStorage storage, Subject subject, FormConfig instance) {
patchConsumerChain = super.buildChain(patchConsumerChain, storage, subject, instance);

if(getValues() != null && subject.isPermitted(instance,Ability.MODIFY)) {
patchConsumerChain = patchConsumerChain.andThen(instance.valueSetter());
}
return patchConsumerChain;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
public class KeyValue implements Serializable {

private static final long serialVersionUID = 1L;

private String key;
private String value;

}
Loading
Loading