Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • osl/code/org.etsi.osl.tmf.api
1 result
Show changes
Commits on Source (61)
Showing
with 1293 additions and 55 deletions
FROM ibm-semeru-runtimes:open-17.0.7_7-jdk FROM ibm-semeru-runtimes:open-17.0.7_7-jdk
# RUN mkdir /opt/shareclasses # RUN mkdir /opt/shareclasses
RUN mkdir -p /opt/openslice/lib/ RUN mkdir -p /opt/openslice/lib/
COPY target/org.etsi.osl.tmf.api-1.1.0-exec.jar /opt/openslice/lib/ COPY target/org.etsi.osl.tmf.api-1.2.0-SNAPSHOT-exec.jar /opt/openslice/lib/
CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/openslice/lib/org.etsi.osl.tmf.api-1.1.0-exec.jar"] CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/openslice/lib/org.etsi.osl.tmf.api-1.2.0-SNAPSHOT-exec.jar"]
EXPOSE 13082 EXPOSE 13082
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.etsi.osl</groupId> <groupId>org.etsi.osl</groupId>
<artifactId>org.etsi.osl.main</artifactId> <artifactId>org.etsi.osl.main</artifactId>
<version>2024Q4</version> <version>2025Q2-SNAPSHOT</version>
<relativePath>../org.etsi.osl.main</relativePath> <relativePath>../org.etsi.osl.main</relativePath>
</parent> </parent>
...@@ -305,7 +305,7 @@ ...@@ -305,7 +305,7 @@
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<scope>test</scope> <version>2.3.232</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.activemq</groupId> <groupId>org.apache.activemq</groupId>
......
...@@ -830,7 +830,7 @@ public GroupedOpenApi pim637() { ...@@ -830,7 +830,7 @@ public GroupedOpenApi pim637() {
SpringDocUtils.getConfig().replaceWithClass(java.time.OffsetDateTime.class, java.util.Date.class); SpringDocUtils.getConfig().replaceWithClass(java.time.OffsetDateTime.class, java.util.Date.class);
return GroupedOpenApi.builder() return GroupedOpenApi.builder()
.group("OpensliceLCMRulesspecificationAPI") .group("OpenSliceLCMRulesspecificationAPI")
.addOpenApiCustomizer( this.lcmOpenAPI() ) .addOpenApiCustomizer( this.lcmOpenAPI() )
.packagesToScan("org.etsi.osl.tmf.lcm.api") .packagesToScan("org.etsi.osl.tmf.lcm.api")
.build(); .build();
...@@ -947,6 +947,39 @@ public GroupedOpenApi pim637() { ...@@ -947,6 +947,39 @@ public GroupedOpenApi pim637() {
.build(); .build();
} }
/**
* Metrics
* @return
*/
@Bean
public OpenApiCustomizer metricsOpenAPI() {
return openApi -> openApi
.specVersion( SpecVersion.V30 ).addSecurityItem(new SecurityRequirement().addList("security_auth"))
.info(new Info().title("OpenSlice Metrics API")
.description("OpenAPI environment for OpenSlice Metrics")
.version("4.0.0")
.license(new License()
.name("Apache 2.0")
.url("https://osl.etsi.org")))
.externalDocs(new ExternalDocumentation()
.description("OpenSlice Metrics")
.url("https://osl.etsi.org"));
}
@Bean
public GroupedOpenApi metrics(){
SpringDocUtils.getConfig().replaceWithClass(java.time.LocalDate.class, java.sql.Date.class);
SpringDocUtils.getConfig().replaceWithClass(java.time.OffsetDateTime.class, java.util.Date.class);
return GroupedOpenApi.builder()
.group("OpenSliceMetricsAPI")
.addOpenApiCustomizer( this.metricsOpenAPI() )
.packagesToScan("org.etsi.osl.tmf.metrics.api")
.build();
}
// @Bean // @Bean
......
package org.etsi.osl.tmf.metrics.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.etsi.osl.tmf.metrics.PublishedServiceSpecifications;
import org.etsi.osl.tmf.metrics.RegisteredIndividuals;
import org.etsi.osl.tmf.metrics.RegisteredResourceSpecifications;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;
@Tag(name = "GeneralMetricsApi", description = "The General Metrics API")
public interface GeneralMetricsApi {
Logger log = LoggerFactory.getLogger(GeneralMetricsApi.class);
@Operation(summary = "Get total number of registered individuals", operationId = "getRegisteredIndividuals")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/registeredIndividuals", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<RegisteredIndividuals> getRegisteredIndividuals();
@Operation(summary = "Get total number of published service specifications", operationId = "getPublishedServiceSpecifications")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/publishedServiceSpecifications", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<PublishedServiceSpecifications> getPublishedServiceSpecifications();
@Operation(summary = "Get total number of registered resource specifications", operationId = "getRegisteredResourceSpecifications")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/registeredResourceSpecifications", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<RegisteredResourceSpecifications> getRegisteredResourceSpecifications();
}
package org.etsi.osl.tmf.metrics.api;
import org.etsi.osl.tmf.metrics.PublishedServiceSpecifications;
import org.etsi.osl.tmf.metrics.RegisteredIndividuals;
import org.etsi.osl.tmf.metrics.RegisteredResourceSpecifications;
import org.etsi.osl.tmf.metrics.reposervices.GeneralMetricsRepoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import java.util.HashMap;
import java.util.Map;
@Controller
public class GeneralMetricsApiController implements GeneralMetricsApi {
private static final Logger log = LoggerFactory.getLogger(GeneralMetricsApiController.class);
private final GeneralMetricsRepoService generalMetricsRepoService;
@Autowired
public GeneralMetricsApiController(GeneralMetricsRepoService generalMetricsRepoService) {
this.generalMetricsRepoService = generalMetricsRepoService;
}
@Override
public ResponseEntity<RegisteredIndividuals> getRegisteredIndividuals() {
try {
int totalIndividuals = generalMetricsRepoService.countRegisteredIndividuals();
RegisteredIndividuals response = new RegisteredIndividuals(totalIndividuals);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total registered individuals. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<PublishedServiceSpecifications> getPublishedServiceSpecifications() {
try {
int totalSpecifications = generalMetricsRepoService.countPublishedServiceSpecifications();
PublishedServiceSpecifications response = new PublishedServiceSpecifications(totalSpecifications);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total published service specifications. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<RegisteredResourceSpecifications> getRegisteredResourceSpecifications() {
try {
int totalResourceSpecifications = generalMetricsRepoService.countRegisteredResourceSpecifications();
RegisteredResourceSpecifications response = new RegisteredResourceSpecifications(totalResourceSpecifications);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total registered resource specifications. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package org.etsi.osl.tmf.metrics.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.etsi.osl.tmf.metrics.ResourcesGroupByState;
import org.etsi.osl.tmf.metrics.TotalResources;
import org.etsi.osl.tmf.ri639.model.ResourceStatusType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.time.OffsetDateTime;
import java.util.Map;
@Tag(name = "ResourceMetricsApi", description = "The Resources' Metrics API")
public interface ResourceMetricsApi {
Logger log = LoggerFactory.getLogger(ResourceMetricsApi.class);
@Operation(summary = "Get total number of resources", operationId = "getTotalResources")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/totalResources", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<TotalResources> getTotalResources(
@Valid @RequestParam(value = "state", required = false) ResourceStatusType state
);
@Operation(summary = "Get resources grouped by state", operationId = "getResourcesGroupedByState")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/resourcesGroupByState", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<ResourcesGroupByState> getResourcesGroupedByState(
@Valid @RequestParam(value = "starttime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime starttime,
@Valid @RequestParam(value = "endtime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime endtime
);
}
package org.etsi.osl.tmf.metrics.api;
import org.etsi.osl.tmf.metrics.*;
import org.etsi.osl.tmf.metrics.reposervices.ResourceMetricsRepoService;
import org.etsi.osl.tmf.ri639.model.ResourceStatusType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import java.time.OffsetDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Controller
public class ResourceMetricsApiController implements ResourceMetricsApi {
private static final Logger log = LoggerFactory.getLogger(ResourceMetricsApiController.class);
private final ResourceMetricsRepoService resourceMetricsRepoService;
@Autowired
public ResourceMetricsApiController(ResourceMetricsRepoService resourceMetricsRepoService) {
this.resourceMetricsRepoService = resourceMetricsRepoService;
}
@Override
public ResponseEntity<TotalResources> getTotalResources(ResourceStatusType state) {
try {
int totalResources = resourceMetricsRepoService.countTotalResources(state);
TotalResources response = new TotalResources(totalResources);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total resources. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<ResourcesGroupByState> getResourcesGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
try {
Map<String, Integer> resourcesByState = resourceMetricsRepoService.getResourcesGroupedByState(starttime, endtime);
// Initialize with all possible states and 0. Ensures that all states are represented, even if not present in the data.
Map<String, Integer> fullStateMap = new LinkedHashMap<>();
for (ResourceStatusType state : ResourceStatusType.values()) {
fullStateMap.put(state.name(), 0); // default to 0
}
// Overwrite counts with actual data
resourcesByState.forEach((key, value) -> {
fullStateMap.put(key.toUpperCase(), value); // normalize case just in case
});
// Create aggregation items
List<ResourcesGroupByStateItem> groupByStateList = fullStateMap.entrySet().stream()
.map(entry -> new ResourcesGroupByStateItem(ResourceStatusType.valueOf(entry.getKey()), entry.getValue()))
.toList();
// Build response structure using models
ResourcesGroupByStateAggregations aggregations = new ResourcesGroupByStateAggregations(groupByStateList);
int total = fullStateMap.values().stream().mapToInt(Integer::intValue).sum();
Resources services = new Resources(total, aggregations);
ResourcesGroupByState response = new ResourcesGroupByState(services);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve resources grouped by state. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package org.etsi.osl.tmf.metrics.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.etsi.osl.tmf.common.model.service.ServiceStateType;
import org.etsi.osl.tmf.metrics.ServicesGroupByState;
import org.etsi.osl.tmf.metrics.TotalServices;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.time.OffsetDateTime;
import java.util.Map;
@Tag(name = "ServiceMetricsApi", description = "The Services' Metrics API")
public interface ServiceMetricsApi {
Logger log = LoggerFactory.getLogger(ServiceMetricsApi.class);
@Operation(summary = "Get total number of services", operationId = "getTotalServices")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/totalServices", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<TotalServices> getTotalServices(
@Valid @RequestParam(value = "state", required = false) ServiceStateType state
);
@Operation(summary = "Get services grouped by state", operationId = "getServicesGroupedByState")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/servicesGroupByState", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<ServicesGroupByState> getServicesGroupedByState(
@Valid @RequestParam(value = "starttime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime starttime,
@Valid @RequestParam(value = "endtime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime endtime
);
}
package org.etsi.osl.tmf.metrics.api;
import org.etsi.osl.tmf.common.model.service.ServiceStateType;
import org.etsi.osl.tmf.metrics.*;
import org.etsi.osl.tmf.metrics.reposervices.ServiceMetricsRepoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import java.time.OffsetDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Controller
public class ServiceMetricsApiController implements ServiceMetricsApi {
private static final Logger log = LoggerFactory.getLogger(ServiceMetricsApiController.class);
private final ServiceMetricsRepoService serviceMetricsRepoService;
@Autowired
public ServiceMetricsApiController(ServiceMetricsRepoService serviceMetricsRepoService) {
this.serviceMetricsRepoService = serviceMetricsRepoService;
}
@Override
public ResponseEntity<TotalServices> getTotalServices(ServiceStateType state) {
try {
int totalServices = serviceMetricsRepoService.countTotalServices(state);
TotalServices response = new TotalServices(totalServices);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total services. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<ServicesGroupByState> getServicesGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
try {
Map<String, Integer> servicesByState = serviceMetricsRepoService.getServicesGroupedByState(starttime, endtime);
// Initialize with all possible states and 0. Ensures that all states are represented, even if not present in the data.
Map<String, Integer> fullStateMap = new LinkedHashMap<>();
for (ServiceStateType state : ServiceStateType.values()) {
fullStateMap.put(state.name(), 0); // default to 0
}
// Overwrite counts with actual data
servicesByState.forEach((key, value) -> {
fullStateMap.put(key.toUpperCase(), value); // normalize case just in case
});
// Create aggregation items
List<ServicesGroupByStateItem> groupByStateList = fullStateMap.entrySet().stream()
.map(entry -> new ServicesGroupByStateItem(ServiceStateType.valueOf(entry.getKey()), entry.getValue()))
.toList();
// Build response structure using metrics models
ServicesGroupByStateAggregations aggregations = new ServicesGroupByStateAggregations(groupByStateList);
int total = fullStateMap.values().stream().mapToInt(Integer::intValue).sum();
Services services = new Services(total, aggregations);
ServicesGroupByState response = new ServicesGroupByState(services);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve services grouped by state. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package org.etsi.osl.tmf.metrics.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.etsi.osl.tmf.metrics.ActiveServiceOrders;
import org.etsi.osl.tmf.metrics.ServiceOrdersGroupByDay;
import org.etsi.osl.tmf.metrics.ServiceOrdersGroupByState;
import org.etsi.osl.tmf.metrics.TotalServiceOrders;
import org.etsi.osl.tmf.so641.model.ServiceOrderStateType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.time.OffsetDateTime;
import java.util.Map;
@Tag(name = "ServiceOrderMetricsApi", description = "The Service Orders' Metrics API")
public interface ServiceOrderMetricsApi {
Logger log = LoggerFactory.getLogger(ServiceOrderMetricsApi.class);
@Operation(summary = "Get total number of service orders", operationId = "getTotalServiceOrders")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/totalServiceOrders", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<TotalServiceOrders> getTotalServiceOrders(
@Valid @RequestParam(value = "state", required = false) ServiceOrderStateType state
);
@Operation(summary = "Get total number of active service orders", operationId = "getTotalActiveServiceOrders")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/activeServiceOrders", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<ActiveServiceOrders> getTotalActiveServiceOrders();
@Operation(summary = "Get service orders grouped by day", operationId = "getServiceOrdersGroupedByDay")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/serviceOrdersGroupByDay", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<ServiceOrdersGroupByDay> getServiceOrdersGroupedByDay(
@Valid @RequestParam(value = "starttime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime starttime,
@Valid @RequestParam(value = "endtime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime endtime
);
@Operation(summary = "Get service orders grouped by state", operationId = "getServiceOrdersGroupedByState")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@RequestMapping(value = "/metrics/serviceOrdersGroupByState", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
ResponseEntity<ServiceOrdersGroupByState> getServiceOrdersGroupedByState(
@Valid @RequestParam(value = "starttime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime starttime,
@Valid @RequestParam(value = "endtime", required = true) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime endtime
);
}
package org.etsi.osl.tmf.metrics.api;
import org.etsi.osl.tmf.metrics.*;
import org.etsi.osl.tmf.metrics.reposervices.ServiceOrderMetricsRepoService;
import org.etsi.osl.tmf.so641.model.ServiceOrderStateType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Controller
public class ServiceOrderMetricsApiController implements ServiceOrderMetricsApi {
private static final Logger log = LoggerFactory.getLogger(ServiceOrderMetricsApiController.class);
private final ServiceOrderMetricsRepoService serviceOrderMetricsRepoService;
@Autowired
public ServiceOrderMetricsApiController(ServiceOrderMetricsRepoService serviceOrderMetricsRepoService) {
this.serviceOrderMetricsRepoService = serviceOrderMetricsRepoService;
}
@Override
public ResponseEntity<TotalServiceOrders> getTotalServiceOrders(ServiceOrderStateType state) {
try {
int totalServiceOrders = serviceOrderMetricsRepoService.countTotalServiceOrders(state);
TotalServiceOrders response = new TotalServiceOrders(totalServiceOrders);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total service orders. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<ActiveServiceOrders> getTotalActiveServiceOrders() {
try {
int totalActiveServiceOrders = serviceOrderMetricsRepoService.countTotalActiveServiceOrders();
ActiveServiceOrders response = new ActiveServiceOrders(totalActiveServiceOrders);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve total active service orders. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<ServiceOrdersGroupByDay> getServiceOrdersGroupedByDay(OffsetDateTime starttime, OffsetDateTime endtime) {
try {
Map<String, Integer> orderDatesGroupedByDate = serviceOrderMetricsRepoService.getServiceOrdersGroupedByDay(starttime, endtime);
// Fill missing days with count 0
Map<String, Integer> fullDayMap = new LinkedHashMap<>();
OffsetDateTime cursor = starttime.truncatedTo(ChronoUnit.DAYS);
OffsetDateTime endDay = endtime.truncatedTo(ChronoUnit.DAYS);
while (!cursor.isAfter(endDay)) {
String key = cursor.toInstant().toString();
fullDayMap.put(key, orderDatesGroupedByDate.getOrDefault(key, 0));
cursor = cursor.plusDays(1);
}
// Convert to model list
List<ServiceOrdersGroupByDayItem> groupByDayList = fullDayMap.entrySet().stream()
.map(entry -> new ServiceOrdersGroupByDayItem(entry.getKey(), entry.getValue()))
.toList();
ServiceOrdersGroupByDayAggregations aggregations = new ServiceOrdersGroupByDayAggregations(groupByDayList);
int total = fullDayMap.values().stream().mapToInt(Integer::intValue).sum();
ServiceOrdersGroupByDayParent wrapper = new ServiceOrdersGroupByDayParent(total, aggregations);
ServiceOrdersGroupByDay response = new ServiceOrdersGroupByDay(wrapper);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve services grouped by state. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
public ResponseEntity<ServiceOrdersGroupByState> getServiceOrdersGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
try {
Map<String, Integer> servicesByState = serviceOrderMetricsRepoService.getServiceOrdersGroupedByState(starttime, endtime);
// Initialize with all possible states and 0. Ensures that all states are represented, even if not present in the data.
Map<String, Integer> fullStateMap = new LinkedHashMap<>();
for (ServiceOrderStateType state : ServiceOrderStateType.values()) {
fullStateMap.put(state.name(), 0);
}
// Overwrite counts with actual data
servicesByState.forEach((key, value) -> {
fullStateMap.put(key.toUpperCase(), value);
});
// Create aggregation items
List<ServiceOrdersGroupByStateItem> groupByStateList = fullStateMap.entrySet().stream()
.map(entry -> new ServiceOrdersGroupByStateItem(ServiceOrderStateType.valueOf(entry.getKey()), entry.getValue()))
.toList();
// Build response structure using models
ServiceOrdersGroupByStateAggregations aggregations = new ServiceOrdersGroupByStateAggregations(groupByStateList);
int total = fullStateMap.values().stream().mapToInt(Integer::intValue).sum();
ServiceOrdersGroupByStateParent services = new ServiceOrdersGroupByStateParent(total, aggregations);
ServiceOrdersGroupByState response = new ServiceOrdersGroupByState(services);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (Exception e) {
log.error("Couldn't retrieve services grouped by state. ", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package org.etsi.osl.tmf.metrics.reposervices;
import org.etsi.osl.tmf.pm632.repo.IndividualRepository;
import org.etsi.osl.tmf.rcm634.repo.ResourceSpecificationRepository;
import org.etsi.osl.tmf.scm633.model.ServiceCandidate;
import org.etsi.osl.tmf.scm633.repo.CandidateRepository;
import org.etsi.osl.tmf.scm633.repo.CategoriesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GeneralMetricsRepoService {
@Autowired
IndividualRepository individualRepository;
@Autowired
ResourceSpecificationRepository resourceSpecificationRepository;
@Autowired
CategoriesRepository categoriesRepository;
@Autowired
CandidateRepository candidateRepository;
public int countRegisteredIndividuals() {
return individualRepository.countAll();
}
public int countPublishedServiceSpecifications() {
List<ServiceCandidate> serviceCandidates = candidateRepository.findAll();
int count = 0;
for (ServiceCandidate serviceCandidate : serviceCandidates) {
System.out.println("ServiceCandidate Category: " + serviceCandidate.getCategoryObj());
if (serviceCandidate.getCategory() != null) {
count += 1;
}
}
return count;
}
public int countRegisteredResourceSpecifications() {
return resourceSpecificationRepository.countLogical() + resourceSpecificationRepository.countPhysical();
}
}
package org.etsi.osl.tmf.metrics.reposervices;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.etsi.osl.tmf.ri639.model.ResourceStatusType;
import org.etsi.osl.tmf.ri639.repo.ResourceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ResourceMetricsRepoService {
@Autowired
ObjectMapper objectMapper;
@Autowired
ResourceRepository resourceRepository;
public int countTotalResources(ResourceStatusType state) {
if (state == null) {
return resourceRepository.countAll();
} else {
return resourceRepository.countByResourceStatus(state);
}
}
public Map<String, Integer> getResourcesGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
if (starttime.plusDays(31).isBefore(endtime)) {
starttime = endtime.minusDays(31);
}
List<Object[]> rawResults = resourceRepository.groupByStateBetweenDates(starttime, endtime);
return rawResults.stream()
.collect(Collectors.toMap(
row -> row[0].toString(),
row -> ((Number) row[1]).intValue()
));
}
}
package org.etsi.osl.tmf.metrics.reposervices;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.etsi.osl.tmf.common.model.service.ServiceStateType;
import org.etsi.osl.tmf.sim638.repo.ServiceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ServiceMetricsRepoService {
@Autowired
ObjectMapper objectMapper;
@Autowired
ServiceRepository serviceRepo;
public int countTotalServices(ServiceStateType state) {
if (state == null) {
return serviceRepo.countAll();
} else {
return serviceRepo.countByState(state);
}
}
public Map<String, Integer> getServicesGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
if (starttime.plusDays(31).isBefore(endtime)) {
starttime = endtime.minusDays(31);
}
List<Object[]> rawResults = serviceRepo.groupByStateBetweenDates(starttime, endtime);
return rawResults.stream()
.collect(Collectors.toMap(
row -> row[0].toString(),
row -> ((Number) row[1]).intValue()
));
}
}
package org.etsi.osl.tmf.metrics.reposervices;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.etsi.osl.tmf.so641.model.ServiceOrderStateType;
import org.etsi.osl.tmf.so641.repo.ServiceOrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ServiceOrderMetricsRepoService {
@Autowired
ObjectMapper objectMapper;
@Autowired
ServiceOrderRepository serviceOrderRepository;
public int countTotalServiceOrders(ServiceOrderStateType state) {
if (state == null) {
return serviceOrderRepository.countAll();
} else {
return serviceOrderRepository.countByState(state);
}
}
public int countTotalActiveServiceOrders() {
OffsetDateTime currentDate = OffsetDateTime.now();
List<ServiceOrderStateType> activeStates = List.of(
ServiceOrderStateType.INPROGRESS,
ServiceOrderStateType.COMPLETED
);
return serviceOrderRepository.countAllActive(currentDate, activeStates);
}
public Map<String, Integer> getServiceOrdersGroupedByDay(OffsetDateTime starttime, OffsetDateTime endtime) {
if (starttime.plusDays(31).isBefore(endtime)) {
starttime = endtime.minusDays(31);
}
List<OffsetDateTime> orderDates = serviceOrderRepository.getOrderDatesBetweenDates(starttime, endtime);
// First group by day with count as Long
Map<String, Long> grouped = orderDates.stream()
.map(dt -> dt.truncatedTo(ChronoUnit.DAYS)) // Remove time portion
.collect(Collectors.groupingBy(
dt -> dt.toInstant().toString(), // Format as ISO string (Z)
Collectors.counting()
));
// Convert Map<String, Long> to Map<String, Integer>
return grouped.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().intValue()
));
}
public Map<String, Integer> getServiceOrdersGroupedByState(OffsetDateTime starttime, OffsetDateTime endtime) {
if (starttime.plusDays(31).isBefore(endtime)) {
starttime = endtime.minusDays(31);
}
List<Object[]> rawResults = serviceOrderRepository.groupByStateBetweenDates(starttime, endtime);
return rawResults.stream()
.collect(Collectors.toMap(
row -> row[0].toString(),
row -> ((Number) row[1]).intValue()
));
}
}
/*-
* ========================LICENSE_START=================================
* org.etsi.osl.tmf.api
* %%
* Copyright (C) 2019 - 2020 openslice.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://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.
* =========================LICENSE_END==================================
*/
package org.etsi.osl.tmf.pcm620.api;
import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.etsi.osl.tmf.pcm620.reposervices.ProductCatalogRepoService;
import org.etsi.osl.tmf.pcm620.reposervices.ProductCategoryRepoService;
import org.etsi.osl.tmf.scm633.model.ServiceSpecification;
import org.etsi.osl.tmf.scm633.model.ServiceSpecificationCreate;
import org.etsi.osl.tmf.scm633.model.ServiceSpecificationUpdate;
import org.etsi.osl.tmf.scm633.reposervices.CatalogRepoService;
import org.etsi.osl.tmf.scm633.reposervices.CategoryRepoService;
import org.etsi.osl.tmf.scm633.reposervices.ServiceSpecificationRepoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
//@RefreshScope
@Component
public class ProductCatalogApiRouteBuilder extends RouteBuilder {
private static final transient Log logger = LogFactory.getLog(ProductCatalogApiRouteBuilder.class.getName());
@Value("${CATALOG_GET_PRODUCTCATALOGS}")
private String CATALOG_GET_PRODUCTCATALOGS = "";
@Value("${CATALOG_GET_PRODUCTCATALOG_BY_ID}")
private String CATALOG_GET_PRODUCTCATALOG_BY_ID = "";
@Value("${CATALOG_GET_PRODUCTCATALOG_BY_NAME}")
private String CATALOG_GET_PRODUCTCATALOG_BY_NAME = "";
@Value("${CATALOG_GET_PRODUCTCATEGORIES}")
private String CATALOG_GET_PRODUCTCATEGORIES = "";
@Value("${CATALOG_GET_PRODUCTCATEGORY_BY_ID}")
private String CATALOG_GET_PRODUCTCATEGORY_BY_ID = "";
@Value("${CATALOG_GET_PRODUCTOFFERINGS_BYCATEGORY_ID}")
private String CATALOG_GET_PRODUCTOFFERINGS_BYCATEGORY_ID = "";
@Autowired
ProductCatalogRepoService catalogRepoService;
@Autowired
ProductCategoryRepoService categoryRepoService;
@Override
public void configure() throws Exception {
from( CATALOG_GET_PRODUCTCATALOG_BY_ID )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTCATALOG_BY_ID + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( catalogRepoService, "findByUuidEager(${header.catalogId})");
from( CATALOG_GET_PRODUCTCATALOGS )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTCATALOGS + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( catalogRepoService, "findAllEager()");
from( CATALOG_GET_PRODUCTCATALOG_BY_NAME )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTCATALOG_BY_NAME + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( catalogRepoService, "findByNameEager(${header.catalogName})")
.marshal().json( JsonLibrary.Jackson, String.class)
.convertBodyTo( String.class );
from( CATALOG_GET_PRODUCTCATEGORIES )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTCATEGORIES + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( catalogRepoService, "findAllCategoriesByCatalogName(${header.catalogName})");
from( CATALOG_GET_PRODUCTCATEGORY_BY_ID )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTCATEGORY_BY_ID + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( categoryRepoService, "findByIdEager(${header.catalogId})");
from( CATALOG_GET_PRODUCTOFFERINGS_BYCATEGORY_ID )
.log(LoggingLevel.INFO, log, CATALOG_GET_PRODUCTOFFERINGS_BYCATEGORY_ID + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.bean( categoryRepoService, "findAllProductOfferingsByCategId(${header.categoryId})");
}
static <T> T toJsonObj(String content, Class<T> valueType) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.readValue( content, valueType);
}
}
package org.etsi.osl.tmf.pcm620.api; package org.etsi.osl.tmf.pcm620.api;
import java.util.ArrayList;
import org.apache.camel.LoggingLevel; import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JsonLibrary; import org.apache.camel.model.dataformat.JsonLibrary;
...@@ -38,6 +39,10 @@ public class ProductSpecificationApiRouteBuilder extends RouteBuilder { ...@@ -38,6 +39,10 @@ public class ProductSpecificationApiRouteBuilder extends RouteBuilder {
@Value("${CATALOG_GET_PRODUCTOFFERING_BY_ID}") @Value("${CATALOG_GET_PRODUCTOFFERING_BY_ID}")
private String CATALOG_GET_PRODUCTOFFERING_BY_ID = ""; private String CATALOG_GET_PRODUCTOFFERING_BY_ID = "";
@Value("${CATALOG_SEARCH_PRODUCTOFFERINGS}")
private String CATALOG_SEARCH_PRODUCTOFFERINGS = "";
...@@ -90,6 +95,14 @@ public class ProductSpecificationApiRouteBuilder extends RouteBuilder { ...@@ -90,6 +95,14 @@ public class ProductSpecificationApiRouteBuilder extends RouteBuilder {
.marshal().json( JsonLibrary.Jackson, String.class) .marshal().json( JsonLibrary.Jackson, String.class)
.convertBodyTo( String.class ); .convertBodyTo( String.class );
from( CATALOG_SEARCH_PRODUCTOFFERINGS )
.log(LoggingLevel.INFO, log, CATALOG_SEARCH_PRODUCTOFFERINGS + " message received!")
.to("log:DEBUG?showBody=true&showHeaders=true")
.unmarshal().json( JsonLibrary.Jackson, ArrayList.class, true)
.bean( productOfferingRepoService, "searchProductOfferings( ${body} )");
} }
} }
...@@ -21,8 +21,12 @@ package org.etsi.osl.tmf.pcm620.reposervices; ...@@ -21,8 +21,12 @@ package org.etsi.osl.tmf.pcm620.reposervices;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule;
import org.etsi.osl.tmf.common.model.ELifecycle; import org.etsi.osl.tmf.common.model.ELifecycle;
import org.etsi.osl.tmf.common.model.TimePeriod; import org.etsi.osl.tmf.common.model.TimePeriod;
import org.etsi.osl.tmf.pcm620.model.Catalog; import org.etsi.osl.tmf.pcm620.model.Catalog;
...@@ -31,11 +35,16 @@ import org.etsi.osl.tmf.pcm620.model.CatalogUpdate; ...@@ -31,11 +35,16 @@ import org.etsi.osl.tmf.pcm620.model.CatalogUpdate;
import org.etsi.osl.tmf.pcm620.model.Category; import org.etsi.osl.tmf.pcm620.model.Category;
import org.etsi.osl.tmf.pcm620.model.CategoryRef; import org.etsi.osl.tmf.pcm620.model.CategoryRef;
import org.etsi.osl.tmf.pcm620.repo.ProductCatalogRepository; import org.etsi.osl.tmf.pcm620.repo.ProductCatalogRepository;
import org.etsi.osl.tmf.scm633.model.ServiceCatalog;
import org.etsi.osl.tmf.scm633.model.ServiceCategory;
import org.etsi.osl.tmf.scm633.model.ServiceCategoryRef;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@Service @Service
@Transactional
public class ProductCatalogRepoService { public class ProductCatalogRepoService {
...@@ -80,6 +89,65 @@ public class ProductCatalogRepoService { ...@@ -80,6 +89,65 @@ public class ProductCatalogRepoService {
return null; return null;
} }
public String findByUuidEager(String id) {
Catalog sc = this.findById(id);
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
String res;
try {
res = mapper.writeValueAsString( sc );
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "{}";
}
return res;
}
public String findAllEager() {
List<Catalog> oids = (List<Catalog>) this.catalogRepo.findByOrderByName();
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
String res;
try {
res = mapper.writeValueAsString( oids );
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "{}";
}
return res;
}
public String findByNameEager(String aname) {
Catalog sc = this.findByName(aname);
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
String res;
try {
res = mapper.writeValueAsString( sc );
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "{}";
}
return res;
}
public Catalog updateCatalog(String id, CatalogUpdate Catalog) { public Catalog updateCatalog(String id, CatalogUpdate Catalog) {
...@@ -131,5 +199,64 @@ public class ProductCatalogRepoService { ...@@ -131,5 +199,64 @@ public class ProductCatalogRepoService {
public Catalog updateCatalog(Catalog scatalog) { public Catalog updateCatalog(Catalog scatalog) {
return this.catalogRepo.save(scatalog); return this.catalogRepo.save(scatalog);
} }
/**
* return recursively all categories in catalog
* @param catalogName
*/
@Transactional
public String findAllCategoriesByCatalogName(String catalogName) {
String res="[]";
Optional<Catalog> scopt = this.catalogRepo.findByName(catalogName);
if (scopt.isEmpty() ) {
return res;
}
Catalog sc = scopt.get();
sc.getCategoryRefs();
List<Category> allcategories = this.getCategories( sc.getCategoryRefs());
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
try {
res = mapper.writeValueAsString( allcategories );
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;
}
@Transactional
private List<Category> getCategories( @Valid List<CategoryRef> list) {
List<Category> categories = new ArrayList<Category>();
for (CategoryRef c : list ) {
Category category = this.categRepoService.findByUuid( c.getId());
categories.add(category);
if (category.getCategoryRefs()!=null && category.getCategoryRefs().size()>0) {
List<Category> subcategories = this.getCategories( category.getCategoryRefs() );
categories.addAll(subcategories );//add children
}
}
return categories;
}
} }
...@@ -26,39 +26,41 @@ import java.util.HashMap; ...@@ -26,39 +26,41 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule;
import org.etsi.osl.tmf.common.model.ELifecycle; import org.etsi.osl.tmf.common.model.ELifecycle;
import org.etsi.osl.tmf.common.model.TimePeriod; import org.etsi.osl.tmf.common.model.TimePeriod;
import org.etsi.osl.tmf.common.model.service.ServiceSpecificationRef;
import org.etsi.osl.tmf.pcm620.model.Category; import org.etsi.osl.tmf.pcm620.model.Category;
import org.etsi.osl.tmf.pcm620.model.CategoryCreate; import org.etsi.osl.tmf.pcm620.model.CategoryCreate;
import org.etsi.osl.tmf.pcm620.model.CategoryRef; import org.etsi.osl.tmf.pcm620.model.CategoryRef;
import org.etsi.osl.tmf.pcm620.model.CategoryUpdate; import org.etsi.osl.tmf.pcm620.model.CategoryUpdate;
import org.etsi.osl.tmf.pcm620.model.ProductOffering; import org.etsi.osl.tmf.pcm620.model.ProductOffering;
import org.etsi.osl.tmf.pcm620.model.ProductOfferingRef; import org.etsi.osl.tmf.pcm620.model.ProductOfferingRef;
import org.etsi.osl.tmf.pcm620.model.ProductSpecificationRef;
import org.etsi.osl.tmf.pcm620.repo.ProductCatalogRepository; import org.etsi.osl.tmf.pcm620.repo.ProductCatalogRepository;
import org.etsi.osl.tmf.pcm620.repo.ProductCategoriesRepository; import org.etsi.osl.tmf.pcm620.repo.ProductCategoriesRepository;
import org.etsi.osl.tmf.pcm620.repo.ProductOfferingRepository; import org.etsi.osl.tmf.pcm620.repo.ProductOfferingRepository;
import org.etsi.osl.tmf.scm633.model.ServiceCandidate;
import org.etsi.osl.tmf.scm633.model.ServiceCategory;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityManagerFactory;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@Service @Service
public class ProductCategoryRepoService { public class ProductCategoryRepoService {
@Autowired private final ProductCategoriesRepository categsRepo;
ProductCategoriesRepository categsRepo;
@Autowired
ProductCatalogRepository catalogRepo;
@Autowired private final ProductOfferingRepository prodsOfferingRepo;
ProductOfferingRepository prodsOfferingRepo;
private SessionFactory sessionFactory;
/** /**
* from * from
...@@ -67,11 +69,11 @@ public class ProductCategoryRepoService { ...@@ -67,11 +69,11 @@ public class ProductCategoryRepoService {
* @param factory * @param factory
*/ */
@Autowired @Autowired
public ProductCategoryRepoService(EntityManagerFactory factory) { public ProductCategoryRepoService( ProductCategoriesRepository categsRepo,
if (factory.unwrap(SessionFactory.class) == null) { ProductOfferingRepository prodsOfferingRepo) {
throw new NullPointerException("factory is not a hibernate factory");
} this.categsRepo = categsRepo;
this.sessionFactory = factory.unwrap(SessionFactory.class); this.prodsOfferingRepo = prodsOfferingRepo;
} }
...@@ -100,28 +102,31 @@ public class ProductCategoryRepoService { ...@@ -100,28 +102,31 @@ public class ProductCategoryRepoService {
} }
public Category findByIdEager(String id) { @Transactional
// Optional<Category> optionalCat = this.categsRepo.findByIdEager( id ); public String findByIdEager(String id) {
// return optionalCat Category sc = this.findByUuid( id );
// .orElse(null);
String res= "{}";
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction(); if ( sc == null ) {
Category dd = null; return res;
try { }
dd = (Category) session.get(Category.class, id);
Hibernate.initialize( dd.getCategoryObj() );
Hibernate.initialize( dd.getProductOfferingRefs() ); ObjectMapper mapper = new ObjectMapper();
for (ProductOfferingRef sc : dd.getProductOfferingRefs()) { // Registering Hibernate4Module to support lazy objects
Hibernate.initialize(sc ); // this will fetch all lazy objects before marshaling
} mapper.registerModule(new Hibernate5JakartaModule());
tx.commit(); try {
} finally { res = mapper.writeValueAsString( sc );
session.close(); } catch (JsonProcessingException e) {
} e.printStackTrace();
return dd; }
}
return res;
}
...@@ -321,4 +326,35 @@ public class ProductCategoryRepoService { ...@@ -321,4 +326,35 @@ public class ProductCategoryRepoService {
return optionalCat return optionalCat
.orElse(null); .orElse(null);
} }
@Transactional
public String findAllProductOfferingsByCategId(String categoryId) {
String res="[]";
List<ProductSpecificationRef> productSpecificationRefList = new ArrayList<>();
Category category = this.findByUuid(categoryId);
if ( category == null ) {
return res;
}
Set<ProductOffering> proffs = category.getProductOfferingObj();
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
try {
res = mapper.writeValueAsString( proffs );
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return res;
}
} }
...@@ -26,18 +26,20 @@ import java.time.OffsetDateTime; ...@@ -26,18 +26,20 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.etsi.osl.tmf.JsonUtils; import java.util.StringJoiner;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule;
import org.etsi.osl.tmf.am651.model.AgreementRef; import org.etsi.osl.tmf.am651.model.AgreementRef;
import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.Any;
import org.etsi.osl.tmf.common.model.AttachmentRefOrValue; import org.etsi.osl.tmf.common.model.AttachmentRefOrValue;
import org.etsi.osl.tmf.common.model.ELifecycle; import org.etsi.osl.tmf.common.model.ELifecycle;
import org.etsi.osl.tmf.common.model.TimePeriod; import org.etsi.osl.tmf.common.model.TimePeriod;
import org.etsi.osl.tmf.common.model.service.ServiceSpecificationRef;
import org.etsi.osl.tmf.pcm620.model.BundledProductOffering; import org.etsi.osl.tmf.pcm620.model.BundledProductOffering;
import org.etsi.osl.tmf.pcm620.model.ProductOffering; import org.etsi.osl.tmf.pcm620.model.ProductOffering;
import org.etsi.osl.tmf.pcm620.model.ProductOfferingCreate; import org.etsi.osl.tmf.pcm620.model.ProductOfferingCreate;
...@@ -50,8 +52,6 @@ import org.etsi.osl.tmf.pcm620.model.ProductSpecificationCharacteristicValueUse; ...@@ -50,8 +52,6 @@ import org.etsi.osl.tmf.pcm620.model.ProductSpecificationCharacteristicValueUse;
import org.etsi.osl.tmf.pcm620.model.ProductSpecificationCreate; import org.etsi.osl.tmf.pcm620.model.ProductSpecificationCreate;
import org.etsi.osl.tmf.pcm620.model.ProductSpecificationRef; import org.etsi.osl.tmf.pcm620.model.ProductSpecificationRef;
import org.etsi.osl.tmf.pcm620.repo.ProductOfferingRepository; import org.etsi.osl.tmf.pcm620.repo.ProductOfferingRepository;
import org.etsi.osl.tmf.pcm620.repo.ProductSpecificationRepository;
import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue;
import org.etsi.osl.tmf.scm633.model.ServiceSpecification; import org.etsi.osl.tmf.scm633.model.ServiceSpecification;
import org.etsi.osl.tmf.scm633.reposervices.ServiceSpecificationRepoService; import org.etsi.osl.tmf.scm633.reposervices.ServiceSpecificationRepoService;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
...@@ -142,15 +142,14 @@ public class ProductOfferingRepoService { ...@@ -142,15 +142,14 @@ public class ProductOfferingRepoService {
} }
sql += " FROM ProductOffering s"; sql += " FROM ProductOffering s";
if (allParams.size() > 0) { if (allParams.size() > 0) {
sql += " WHERE "; String items = allParams.entrySet()
for (String pname : allParams.keySet()) { .stream()
sql += " " + pname + " LIKE "; .map(entry -> "s." + entry.getKey() + " LIKE '%" + URLDecoder.decode( entry.getValue(), StandardCharsets.UTF_8 )+ "%'" )
String pval = URLDecoder.decode(allParams.get(pname), StandardCharsets.UTF_8.toString()); .collect(Collectors.joining(" OR "));
sql += "'" + pval + "'"; sql += " WHERE " + items;
}
}
}
sql += " ORDER BY s.name"; sql += " ORDER BY s.name";
...@@ -632,5 +631,124 @@ public class ProductOfferingRepoService { ...@@ -632,5 +631,124 @@ public class ProductOfferingRepoService {
return pOffer; return pOffer;
} }
@Transactional
public String searchProductOfferings(List<String> searchText) {
String res = "[]";
try {
List<String> specs= this.searchOfferingsInCategories( searchText);
ObjectMapper mapper = new ObjectMapper();
// Registering Hibernate4Module to support lazy objects
// this will fetch all lazy objects before marshaling
mapper.registerModule(new Hibernate5JakartaModule());
res = mapper.writeValueAsString( specs );
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return res;
}
/**
*
* This findAll is optimized on fields.
* @param fields
* @param allParams
* @return
* @throws UnsupportedEncodingException
*/
@Transactional
public List searchOfferingsInCategories( List<String> searchList )
throws UnsupportedEncodingException {
if ( searchList == null || searchList.size() ==0) {
return new ArrayList<>();
}
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
String sql = "SELECT p.id as productOfferingId, p.name as productName, p.description as productDescription";
sql += " FROM ProductCategory as pcateg JOIN pcateg.productOffObj as p ";
sql += " WHERE " ;
// Build the name LIKE clause
StringJoiner nameJoiner = new StringJoiner(" AND ");
for (String term : searchList) {
nameJoiner.add("p.name LIKE '%" + term + "%'");
}
// Build the description LIKE clause
StringJoiner descriptionJoiner = new StringJoiner(" AND ");
for (String term : searchList) {
descriptionJoiner.add("p.description LIKE '%" + term + "%'");
}
// Combine both clauses with OR
sql += "(" + nameJoiner.toString() + ") OR (" + descriptionJoiner.toString() + ")";
sql += " ORDER BY p.name";
// List<ServiceSpecification> specs = session
// .createQuery( sql, ServiceSpecification.class)
// .getResultList();
List<Object> mapaEntity = session
.createQuery(sql )
.setResultTransformer( new ResultTransformer() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
Map<String, Object> result = new LinkedHashMap<String, Object>(tuple.length);
for (int i = 0; i < tuple.length; i++) {
String alias = aliases[i];
if (alias != null) {
if (alias.equals("type")) {
alias = "@type";
}
result.put(alias, tuple[i]);
}
}
return result;
}
@Override
public List transformList(List collection) {
return collection;
}
} )
.list();
// //this will fetch the whole object fields
return mapaEntity;
} finally {
tx.commit();
session.close();
}
}
} }