Skip to content

Commit

Permalink
Release/1.2.0 (#42)
Browse files Browse the repository at this point in the history
* Bump develop to 1.2.0-alpha0 (#37)

* Update build.gradle

* Update bumpver.toml

* bump version to 1.2.0-alpha1

* Multiticket Update (#39)

* Disable public stacktraces on 500 errors

* Bump priority on SwodlrExceptionResolver

* Move EdlProxyController to edl subpackage

* Initial user roles implementation

* Cache User result in UserReferences

* Initial invalidation implementation

* Enable cicd on all branches

* Linting

* Update changelog

* Cache Fix + Invalidate Change (#40)

* Regenerate on ERROR or UNAVAILABLE

* Change invalidate endpoint to only invalidate

* Initial filtering implementation (#41)

* update changelog to add cache fix and filter performance improvement.

* revert Build 'n Deploy from push '*' wildcard to push branches in build.yml.

* fix syntax

* fix syntax

* bump version to 1.2.0-alpha2

* Updated changelog with release/1.2.0

* bump version to 1.2.0-rc0

* Update graphql schema with new filtering endpoint

* bump version to 1.3.0-rc0

* Hotfix product filtering

* bump version to 1.3.0-rc1

* update CHNAGELOG and rename to .md

* bump version to 1.3.0-rc2

* Fix incorrect version bump

* bump version to 1.2.0-rc1

---------

Co-authored-by: Frank Greguska <[email protected]>
Co-authored-by: Frank Greguska <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Josh Garde <[email protected]>
  • Loading branch information
5 people authored Jun 20, 2024
1 parent d5dca14 commit be1f06f
Show file tree
Hide file tree
Showing 16 changed files with 355 additions and 25 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: Build 'n Deploy

on:
push:
branches:
Expand Down Expand Up @@ -97,12 +98,12 @@ jobs:
- name: Bump rc version
if: startsWith(github.ref, 'refs/heads/release/') && github.event_name != 'workflow_dispatch'
run: |
bumpver update -f --tag rc --tag-num
bumpver update -f -n --tag rc --tag-num
echo "TARGET_ENV=UAT" >> $GITHUB_ENV
- name: Release version
if: github.ref == 'refs/heads/main' && github.event_name != 'workflow_dispatch'
run: |
bumpver update --tag final
bumpver update -f -n --tag final
echo "TARGET_ENV=OPS" >> $GITHUB_ENV
- name: Set the target environment to ${{ env.TARGET_ENV }}
id: set-env
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG → CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
### Deprecated
### Removed
### Fixed
### Security


## [1.2.0]

### Added
- Implement permissions model #92
- As a user, I do not want to see stacktraces when errors occur #36
- Initial filtering implementation (#41)
- Update graphql schema with new filtering endpoint
- Hotfix product filtering
### Fixed
- Cache Fix + Invalidate Change (#40)


## [1.1.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = 'gov.nasa.podaac.swodlr'
version = '1.1.0'
version = '1.2.0-rc1'
sourceCompatibility = '17'

repositories {
Expand Down
2 changes: 1 addition & 1 deletion bumpver.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpver]
current_version = "1.1.0"
current_version = "1.2.0-rc1"
version_pattern = "MAJOR.MINOR.PATCH[-TAGNUM]"
commit = true
tag = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionSystemException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SwodlrExceptionResolver extends DataFetcherExceptionResolverAdapter {
@Override
public List<GraphQLError> resolveToMultipleErrors(Throwable ex, DataFetchingEnvironment env) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
package gov.nasa.podaac.swodlr.l2rasterproduct;

import gov.nasa.podaac.swodlr.exception.SwodlrException;
import gov.nasa.podaac.swodlr.rasterdefinition.GridType;
import gov.nasa.podaac.swodlr.status.State;
import gov.nasa.podaac.swodlr.status.Status;
import gov.nasa.podaac.swodlr.status.StatusRepository;
import gov.nasa.podaac.swodlr.user.User;
import gov.nasa.podaac.swodlr.user.UserReference;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.UUID;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.ContextValue;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;

@Controller
public class L2RasterProductController {
private Logger logger = LoggerFactory.getLogger(getClass());

@Autowired
private L2RasterProductService l2RasterProductService;

@Autowired
L2RasterProductService l2RasterProductService;
private L2RasterProductRepository l2RasterProductRepository;

@Autowired
L2RasterProductRepository l2RasterProductRepository;
private StatusRepository statusRepository;

@MutationMapping
public Mono<L2RasterProduct> generateL2RasterProduct(
Expand Down Expand Up @@ -64,6 +79,23 @@ public Mono<L2RasterProduct> generateL2RasterProduct(
});
}

@PreAuthorize("hasRole(\"ROLE_Administrator\")")
@MutationMapping
@Transactional
public L2RasterProduct invalidateProduct(@Argument UUID id) {
var result = l2RasterProductRepository.findById(id);
if (result.isEmpty()) {
logger.debug("No products found with id: {}", id.toString());
return null;
}

L2RasterProduct product = result.get();
Status invalidatedStatus = new Status(product, State.UNAVAILABLE);
statusRepository.save(invalidatedStatus);

return product;
}

@QueryMapping
public L2RasterProduct l2RasterProduct(@Argument UUID id) {
var result = l2RasterProductRepository.findById(id);
Expand All @@ -82,9 +114,52 @@ public L2RasterProduct getProductForStatus(Status status) {
@SchemaMapping(typeName = "User", field = "products")
public List<L2RasterProduct> getProductsForUser(
@ContextValue UserReference userRef,
@Argument Integer cycle,
@Argument Integer pass,
@Argument Integer scene,
@Argument Boolean outputGranuleExtentFlag,
@Argument GridType outputSamplingGridType,
@Argument Integer rasterResolution,
@Argument Integer utmZoneAdjust,
@Argument Integer mgrsBandAdjust,
@Argument String beforeTimestamp,
@Argument String afterTimestamp,
@Argument UUID after,
@Argument int limit
) {
return l2RasterProductRepository.findByUser(userRef.fetch(), after, limit);
LocalDateTime beforeDate = null;
LocalDateTime afterDate = null;

if (beforeTimestamp != null) {
try {
beforeDate = LocalDateTime.parse(beforeTimestamp);
} catch (DateTimeParseException ex) {
throw new SwodlrException("Invalid \'beforeTimestamp\' - should be ISO8601");
}
}

if (afterTimestamp != null) {
try {
afterDate = LocalDateTime.parse(afterTimestamp);
} catch (DateTimeException ex) {
throw new SwodlrException("Invalid \'afterTimestamp\' - should be ISO8601");
}
}

return l2RasterProductRepository.findByUser(
userRef.fetch(),
cycle,
pass,
scene,
outputGranuleExtentFlag,
outputSamplingGridType,
rasterResolution,
utmZoneAdjust,
mgrsBandAdjust,
beforeDate,
afterDate,
after,
limit
);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
package gov.nasa.podaac.swodlr.l2rasterproduct;

import gov.nasa.podaac.swodlr.rasterdefinition.GridType;
import gov.nasa.podaac.swodlr.user.User;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

public interface L2RasterProductQuery {
List<L2RasterProduct> findByUser(User user, UUID after, int limit);
List<L2RasterProduct> findByUser(
User user,
Integer cycle,
Integer pass,
Integer scene,
Boolean outputGranuleExtentFlag,
GridType outputSamplingGridType,
Integer rasterResolution,
Integer utmZoneAdjust,
Integer mgrsBandAdjust,
LocalDateTime beforeTimestamp,
LocalDateTime afterTimestamp,
UUID after,
int limit
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package gov.nasa.podaac.swodlr.l2rasterproduct;

import gov.nasa.podaac.swodlr.rasterdefinition.GridType;
import gov.nasa.podaac.swodlr.user.User;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.hibernate.type.BooleanType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LocalDateTimeType;
import org.hibernate.type.StringType;
import org.hibernate.type.UUIDCharType;

public class L2RasterProductQueryImpl implements L2RasterProductQuery {
Expand Down Expand Up @@ -41,13 +46,37 @@ public class L2RasterProductQueryImpl implements L2RasterProductQuery {
* - https://github.com/pgjdbc/pgjdbc/issues/247#issuecomment-78213991
*/
@Override
public List<L2RasterProduct> findByUser(User user, UUID after, int limit) {
public List<L2RasterProduct> findByUser(
User user,
Integer cycle,
Integer pass,
Integer scene,
Boolean outputGranuleExtentFlag,
GridType outputSamplingGridType,
Integer rasterResolution,
Integer utmZoneAdjust,
Integer mgrsBandAdjust,
LocalDateTime beforeTimestamp,
LocalDateTime afterTimestamp,
UUID after,
int limit
) {
@SuppressWarnings("LineLength")
String statement =
"""
SELECT \"L2RasterProducts\".* FROM \"L2RasterProducts\"
JOIN \"ProductHistory\" ON \"ProductHistory\".\"rasterProductId\" = \"L2RasterProducts\".id
WHERE
(:cycle is NULL OR \"cycle\" = :cycle) AND
(:pass is NULL OR \"pass\" = :pass) AND
(:scene is NULL OR \"scene\" = :scene) AND
(:outputGranuleExtentFlag is NULL OR \"outputGranuleExtentFlag\" = :outputGranuleExtentFlag) AND
(:outputSamplingGridType is NULL OR \"outputSamplingGridType\" = :outputSamplingGridType) AND
(:rasterResolution is NULL OR \"rasterResolution\" = :rasterResolution) AND
(:utmZoneAdjust is NULL OR \"utmZoneAdjust\" = :utmZoneAdjust) AND
(:mgrsBandAdjust is NULL OR \"mgrsBandAdjust\" = :mgrsBandAdjust) AND
(CAST(:beforeTimestamp as TIMESTAMP) is NULL OR \"L2RasterProducts\".timestamp <= :beforeTimestamp) AND
(CAST(:afterTimestamp as TIMESTAMP) is NULL OR \"L2RasterProducts\".timestamp >= :afterTimestamp) AND
(\"ProductHistory\".\"requestedById\" = CAST(:userId as UUID)) AND
(
(:after is NULL)
Expand All @@ -60,6 +89,17 @@ public List<L2RasterProduct> findByUser(User user, UUID after, int limit) {
Session session = entityManager.unwrap(Session.class);
Query<L2RasterProduct> query = session.createNativeQuery(statement, L2RasterProduct.class);
query.setParameter("userId", user.getId(), UUIDCharType.INSTANCE);
query.setParameter("cycle", cycle, IntegerType.INSTANCE);
query.setParameter("pass", pass, IntegerType.INSTANCE);
query.setParameter("scene", scene, IntegerType.INSTANCE);
query.setParameter("outputGranuleExtentFlag", outputGranuleExtentFlag, BooleanType.INSTANCE);
query.setParameter("outputSamplingGridType", outputSamplingGridType != null
? outputSamplingGridType.toString() : null, StringType.INSTANCE);
query.setParameter("rasterResolution", rasterResolution, IntegerType.INSTANCE);
query.setParameter("utmZoneAdjust", utmZoneAdjust, IntegerType.INSTANCE);
query.setParameter("mgrsBandAdjust", mgrsBandAdjust, IntegerType.INSTANCE);
query.setParameter("beforeTimestamp", beforeTimestamp, LocalDateTimeType.INSTANCE);
query.setParameter("afterTimestamp", afterTimestamp, LocalDateTimeType.INSTANCE);
query.setParameter("after", after, UUIDCharType.INSTANCE);
query.setParameter("limit", limit, IntegerType.INSTANCE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,11 @@ public Mono<L2RasterProduct> createL2RasterProduct(
utmZoneAdjust,
mgrsBandAdjust
);
Status status = new Status(product, State.NEW);
ProductHistory history = new ProductHistory(user, product);

product = l2RasterProductRepository.save(product);
statusRepository.save(status);
productHistoryRepository.save(history);

return productCreateQueue.queueProduct(product).thenReturn(product);
return startProductGeneration(product);
}

@Transactional
Expand All @@ -82,20 +79,29 @@ public Mono<L2RasterProduct> getL2RasterProduct(
mgrsBandAdjust
);

if (!productResult.isPresent()) {
if (productResult.isEmpty()) {
return Mono.empty();
}

L2RasterProduct product = productResult.get();
ProductHistory history = new ProductHistory(requestor, product);
productHistoryRepository.save(history);

if (product.getStatuses().get(0).getState() == State.UNAVAILABLE) {
Status status = new Status(product, State.NEW);
statusRepository.save(status);
return productCreateQueue.queueProduct(product).thenReturn(product);
State currentState = product.getStatuses().get(0).getState();

if (currentState == State.UNAVAILABLE || currentState == State.ERROR) {
return startProductGeneration(product);
}

return Mono.just(product);
}

@Transactional
public Mono<L2RasterProduct> startProductGeneration(L2RasterProduct product) {
return Mono.defer(() -> {
Status status = new Status(product, State.NEW);
statusRepository.save(status);
return productCreateQueue.queueProduct(product).thenReturn(product);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import gov.nasa.podaac.swodlr.security.SwodlrSecurityProperties;
import gov.nasa.podaac.swodlr.security.UserBootstrapWebFilter;
import gov.nasa.podaac.swodlr.security.edl.EdlReactiveAuthenticationManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
Expand All @@ -32,7 +35,15 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
})
.oauth2ResourceServer((resourceServer) -> {
resourceServer.jwt((jwt) -> {
jwt.jwkSetUri(securityProperties.edlBaseUrl() + "/export_edl_jwks");
ReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(
securityProperties.edlBaseUrl() + "/export_edl_jwks"
);

jwt
.jwtDecoder(jwtDecoder)
.authenticationManager(
new EdlReactiveAuthenticationManager(jwtDecoder, securityProperties)
);
});
})
.addFilterAfter(userBootstrapWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.podaac.swodlr.security;
package gov.nasa.podaac.swodlr.security.edl;

import gov.nasa.podaac.swodlr.security.SwodlrSecurityProperties;
import java.net.URI;
import java.util.List;
import java.util.Map;
Expand Down
Loading

0 comments on commit be1f06f

Please sign in to comment.