Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore[xxxx]: updated action #1274

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2d2b94a
chore[1194]: fixed endpoint and frontend bug
Jul 9, 2024
3ad0d85
chore[1194]: updated PolicyServiceImpl
Jul 9, 2024
21b420b
chore[1194]: added Test
Jul 10, 2024
e045725
chore[1194]: added Test
Jul 10, 2024
f77f5a1
chore[1194]: changed Response from getPolicies endpoint
Jul 12, 2024
c048a4d
chore[1194]: fixed bug
Jul 12, 2024
f4346ae
chore[1194]: updated CHANGELOG.md
Jul 12, 2024
43664c9
chore[1194]: fixed Test
Jul 12, 2024
7ed85ac
chore[1194]: code refactor
Jul 12, 2024
e5267fd
Merge branch 'main' into chore/xxx-bug
Jul 12, 2024
95535fa
chore[1194]: code refactor
Jul 12, 2024
d5f2456
Merge branch 'main' into chore/xxx-bug
Jul 19, 2024
4f781b1
chore[1194]: solved merge conflicts
Jul 19, 2024
347e73e
chore[1194]: fixed endpoint and frontend bug
Jul 9, 2024
30fcff6
chore[1194]: updated PolicyServiceImpl
Jul 9, 2024
dcf18dc
chore[1194]: added Test
Jul 10, 2024
e88d5bc
chore[1194]: added Test
Jul 10, 2024
aacbf00
chore[1194]: changed Response from getPolicies endpoint
Jul 12, 2024
fee6f07
chore[1194]: fixed bug
Jul 12, 2024
0c91a94
chore[1194]: updated CHANGELOG.md
Jul 12, 2024
12ac00b
chore[1194]: fixed Test
Jul 12, 2024
3b08686
chore[1194]: code refactor
Jul 12, 2024
c4c64a8
chore[1194]: code refactor
Jul 12, 2024
95df08a
chore[1194]: updated response
Jul 22, 2024
80419c9
Merge remote-tracking branch 'origin/chore/xxx-bug' into chore/xxx-bug
Jul 22, 2024
462468b
chore[1194]: updated response
Jul 22, 2024
a11c533
chore[1194]: updated response
Jul 22, 2024
b090aa8
Merge branch 'main' into chore/xxx-ducumentation
Jul 23, 2024
929196f
Merge branch 'main' into chore/xxx-ducumentation
Jul 23, 2024
1c721e5
chore[XXXX]: updated action
Jul 23, 2024
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
29 changes: 22 additions & 7 deletions .github/workflows/publish-documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ name: "[BE][FE][DOCUMENTATION] Publish documentation"

on:
workflow_dispatch: # Trigger manually
pull_request:
paths:
- 'docs/**'
push:
branches:
- main
paths:
- 'docs/**'

jobs:
publish:
Expand Down Expand Up @@ -58,11 +63,6 @@ jobs:
restore-keys: ${{ runner.os }}-m2


- name: Build API documentation with Maven
run: |
mvn clean package -pl tx-backend,tx-models -DskipTests --batch-mode
cp tx-backend/target/generated-sources/openapi/index.html docs/src/docs/api-specification/index.html
- name: Build with Maven
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
Expand Down Expand Up @@ -127,9 +127,24 @@ jobs:
run: |
mv docs/src/diagram-replacer/assets/ docs/target/generated-docs/assets/
- name: GitHub Pages action
uses: peaceiris/actions-gh-pages@v4.0.0
- name: Generate Swagger UI
uses: Legion2/swagger-ui-action@v1
with:
output: swagger-ui
spec-file: docs/api/traceability-foss-backend.json

- name: Update documentation on GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: "./docs/target/generated-docs"
destination_dir: "docs"

- name: Deploy Swagger UI to GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: "swagger-ui"
destination_dir: "docs/swagger-ui"
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ _**For better traceability add the corresponding GitHub issue number in each cha
- #941 made the naming for quality notifications consistent throughout the FE app
- #1190 store accepted policies in catalog offers on startup
- #941 updated labels from QualityTopic to QualityNotification
- XXXX updated publish-documentation workflow

### Known knowns
- #786 Implemented short term solution for securing EDC Callback APIs
- #1190 CatalogOffers are not able to provide OR constraints therefore notifications are not processed correctly on wrong policy
- XXX update legal notice for documents arc42, admin and user manual to years 2024
- #943 renamed distinctFilterValues API to searchable-values for the asBuilt, asPlanned and notification routes
- #943 changed these endpoints to POST with body instead of GET with parameters
- #1194 fix wrong time format in frontend and changed the response from getPolicies endpoint

## [12.0.0 - 05.07.2024]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('PoliciesAssembler', () => {
const assembledPolicy = PoliciesAssembler.assemblePolicy(mockPolicy2);
expect(assembledPolicy.policyName).toBe(mockPolicy2.policyId);
expect(assembledPolicy.createdOn).toBe('2024-01-01T00:00');
expect(assembledPolicy.validUntil).toBe('2024-12-31T23:59');
expect(assembledPolicy.validUntil).toBe('2025-01-01T00:59:59');
expect(assembledPolicy.accessType).toBe('USE');
expect(assembledPolicy.constraints).toEqual('left1=right1left2!=right2');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,25 @@ export class PoliciesAssembler {
...policy,
policyName: policy.policyId,
createdOn: isNumber(policy.createdOn) ? new Date(policy.createdOn as number * 1000).toISOString().slice(0, 19) + 'Z' : (formattedCreatedOn.isInitial() ? null : formattedCreatedOn.valueOf().toISOString().slice(0, 16)),
validUntil: isNumber(policy.validUntil) ? new Date(policy.validUntil as number * 1000).toISOString().slice(0, 19) + 'Z' : (formattedValidUntil.isInitial() ? null : formattedValidUntil.valueOf().toISOString().slice(0, 16)),
validUntil: isNumber(policy.validUntil) ? new Date(policy.validUntil as number * 1000).toISOString().slice(0, 19) + 'Z' : (formattedValidUntil.isInitial() ? null : this.mapUtcToLocalTime(policy.validUntil)),
accessType: policy.permissions[0].action.toUpperCase() as PolicyAction,
constraints: policy.constraints ?? this.mapDisplayPropsToPolicyRootLevelFromPolicy(policy),
};
}

public static mapUtcToLocalTime(validUntil: string): string {
const date = new Date(validUntil);

const localYear = date.getFullYear();
const localMonth = String(date.getMonth() + 1).padStart(2, '0');
const localDate = String(date.getDate()).padStart(2, '0');
const localHours = String(date.getHours()).padStart(2, '0');
const localMinutes = String(date.getMinutes()).padStart(2, '0');
const localSeconds = String(date.getSeconds()).padStart(2, '0');

return `${ localYear }-${ localMonth }-${ localDate }T${ localHours }:${ localMinutes }:${ localSeconds }`;

}
public static mapToPolicyEntryList(policyResponse: PolicyResponseMap): PolicyEntry[] {
const list: PolicyEntry[] = [];
for (const [ key, value ] of Object.entries(policyResponse)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ToastService } from '@shared/components/toasts/toast.service';
import { ViewMode } from '@shared/model/view.model';
import { Subscription } from 'rxjs';


@Component({
selector: 'app-policy-editor',
templateUrl: './policy-editor.component.html',
Expand Down Expand Up @@ -221,7 +222,6 @@ export class PolicyEditorComponent {
}
*/
updatePolicyForm(policy: Policy) {

const isFromTemplate = !policy?.permissions[0]?.constraints;
this.policyForm.patchValue({
policyName: policy?.policyName,
Expand Down Expand Up @@ -278,8 +278,11 @@ export class PolicyEditorComponent {
};
});

const validUntilDate = new Date(this.policyForm.get('validUntil').getRawValue());
const validUntilISO = validUntilDate.toISOString();

policyEntry = {
validUntil: this.policyForm.get('validUntil').getRawValue() + ':00.000000000Z',
validUntil: validUntilISO,
businessPartnerNumber: this.viewMode === ViewMode.CREATE ? this.policyForm.get('bpns').getRawValue() : this.policyForm.get('bpns').getRawValue()?.trim()?.split(','),
payload: {
'@context': {
Expand All @@ -289,7 +292,7 @@ export class PolicyEditorComponent {
policy: {
policyId: this.policyForm.get('policyName').getRawValue(),
createdOn: new Date(Date.now()).toISOString().replace('Z', '000000Z'),
validUntil: this.policyForm.get('validUntil').getRawValue() + ':00.000000000Z',
validUntil: validUntilISO,
permissions: [
{
action: this.policyForm.get('accessType').getRawValue().toLowerCase(),
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/app/modules/page/policies/model/policy.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export interface Policy {
// props in response
policyId: string;
createdOn: CalendarDateModel | string | number;
validUntil: CalendarDateModel | string | number;
validUntil: string | number;
permissions: PolicyPermission[];

// additional props
Expand Down Expand Up @@ -127,6 +127,7 @@ export function getOperatorTypeSign(type: OperatorType): string {
}
}


export enum ConstraintLogicType {
AND = 'AND',
OR = 'OR',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.eclipse.tractusx.traceability.notification.domain.notification.exception.NotificationNotSupportedException;
import org.eclipse.tractusx.traceability.notification.domain.notification.exception.NotificationSenderAndReceiverBPNEqualException;
import org.eclipse.tractusx.traceability.notification.domain.notification.exception.NotificationStatusTransitionNotAllowed;
import org.eclipse.tractusx.traceability.policies.domain.exception.PolicyNotValidException;
import org.eclipse.tractusx.traceability.submodel.domain.model.SubmodelNotFoundException;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.support.DefaultMessageSourceResolvable;
Expand Down Expand Up @@ -379,6 +380,13 @@ ResponseEntity<ErrorResponse> handleUnsupportedSearchCriteriaFieldException(Unsu
.body(new ErrorResponse(exception.getMessage()));
}

@ExceptionHandler(PolicyNotValidException.class)
ResponseEntity<ErrorResponse> handlePolicyNotValidException(PolicyNotValidException exception) {
log.warn("PolicyNotValidException", exception);
return ResponseEntity.status(BAD_REQUEST)
.body(new ErrorResponse(exception.getMessage()));
}

@ExceptionHandler(CreateNotificationContractException.class)
ResponseEntity<ErrorResponse> handleCreateNotificationContractException(CreateNotificationContractException exception) {
log.warn("handleCreateNotificationContractException", exception);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import policies.response.IrsPolicyResponse;
import policies.response.PolicyResponse;

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static policies.response.PolicyResponse.toDomain;

@Configuration
@ConfigurationPropertiesScan(basePackages = "org.eclipse.tractusx.traceability.*")
@EnableWebMvc
Expand Down Expand Up @@ -105,8 +108,8 @@ private List<AcceptedPolicy> createIrsAcceptedPolicies() {

// Map the IrsPolicyResponse objects to AcceptedPolicy objects
List<AcceptedPolicy> irsPolicies = irsPolicyResponses.stream().map(response -> {
Policy policy = new Policy(response.payload().policyId(), response.payload().policy().getCreatedOn(), response.validUntil(), response.payload().policy().getPermissions());
return new AcceptedPolicy(policy, response.validUntil());
PolicyResponse policy = new PolicyResponse(response.payload().policyId(), response.payload().policy().createdOn(), response.validUntil(), response.payload().policy().permissions(), null);
return new AcceptedPolicy(toDomain(policy), response.validUntil());
}).toList();

// Return the list of AcceptedPolicy objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public class PolicyController {
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class)))})
@GetMapping()
public Map<String, List<IrsPolicyResponse>> getPolicies() {
public Map<String, List<PolicyResponse>> getPolicies() {
return policyService.getIrsPolicies();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
public interface PolicyService {
List<PolicyResponse> getPolicies();

Map<String, List<IrsPolicyResponse>> getIrsPolicies();

Map<String, List<PolicyResponse>> getIrsPolicies();
PolicyResponse getPolicy(String id);

CreatePolicyResponse createPolicy(RegisterPolicyRequest registerPolicyRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,21 @@
import org.eclipse.tractusx.traceability.assets.domain.importpoc.exception.PolicyNotFoundException;
import org.eclipse.tractusx.traceability.notification.domain.contract.EdcNotificationContractService;
import org.eclipse.tractusx.traceability.policies.application.service.PolicyService;
import org.eclipse.tractusx.traceability.policies.domain.exception.PolicyNotValidException;
import org.springframework.stereotype.Service;
import policies.request.RegisterPolicyRequest;
import policies.request.UpdatePolicyRequest;
import policies.response.CreatePolicyResponse;
import policies.response.IrsPolicyResponse;
import policies.response.PolicyResponse;

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static policies.response.IrsPolicyResponse.toResponse;
import java.util.stream.Collectors;


@Slf4j
@RequiredArgsConstructor
Expand All @@ -45,33 +48,46 @@ public class PolicyServiceImpl implements PolicyService {
private final EdcNotificationContractService edcNotificationContractService;

@Override
public Map<String, List<IrsPolicyResponse>> getIrsPolicies() {
return policyRepository.getPolicies();
public Map<String, List<PolicyResponse>> getIrsPolicies() {
Map<String, List<IrsPolicyResponse>> policies = policyRepository.getPolicies();
return policies.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().stream()
.map(irsPolicyResponse -> irsPolicyResponse.payload().policy())
.collect(Collectors.toList())
));
}

@Override
public List<PolicyResponse> getPolicies() {
Map<String, List<IrsPolicyResponse>> policies = policyRepository.getPolicies();
return toResponse(policies);
return policies.values().stream()
.flatMap(List::stream)
.map(irsPolicyResponse -> irsPolicyResponse.payload().policy())
.collect(Collectors.toList());
}

@Override
public PolicyResponse getPolicy(String id) {
Map<String, Optional<IrsPolicyResponse>> policies = policyRepository.getPolicy(id);

// Find the first entry with a present policy
return policies.entrySet().stream()
.filter(entry -> entry.getValue().isPresent())
return policies.values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.map(irsPolicyResponse -> irsPolicyResponse.payload().policy())
.findFirst()
.map(entry -> toResponse(entry.getValue().get(), entry.getKey()))
.orElseThrow(() -> new PolicyNotFoundException("Policy with id: %s not found.".formatted(id)));
}

@Override
public CreatePolicyResponse createPolicy(RegisterPolicyRequest registerPolicyRequest) {
CreatePolicyResponse policy = policyRepository.createPolicy(registerPolicyRequest);
edcNotificationContractService.updateNotificationContractDefinitions();
return policy;
if(registerPolicyRequest.validUntil().isAfter(Instant.now())){
CreatePolicyResponse policy = policyRepository.createPolicy(registerPolicyRequest);
edcNotificationContractService.updateNotificationContractDefinitions();
return policy;
}
throw new PolicyNotValidException("Policy is not valid because of a not accepted validUntil value " +registerPolicyRequest);
}

@Override
Expand All @@ -82,8 +98,12 @@ public void deletePolicy(String id) {

@Override
public void updatePolicy(UpdatePolicyRequest updatePolicyRequest) {
if(updatePolicyRequest.validUntil().isAfter(Instant.now())){
policyRepository.updatePolicy(updatePolicyRequest);
edcNotificationContractService.updateNotificationContractDefinitions();
return;
}
throw new PolicyNotValidException("Policy is not valid because of a not accepted validUntil value " +updatePolicyRequest);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.traceability.policies.domain.exception;

public class PolicyNotValidException extends RuntimeException{
public PolicyNotValidException(String message) {
super(message);
}
}
Loading
Loading