Skip to content

Commit

Permalink
SHIBUI-2584
Browse files Browse the repository at this point in the history
Added additional beacon data collection
  • Loading branch information
chasegawa committed Jul 7, 2023
1 parent 8066653 commit 83631bd
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.BeaconConfiguration;
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;
import edu.internet2.tier.shibboleth.admin.ui.repository.BeaconConfigurationRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.BeaconEventRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
Expand Down Expand Up @@ -47,7 +48,6 @@
import jakarta.servlet.http.HttpServletRequest;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -68,7 +68,6 @@
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
Expand Down Expand Up @@ -285,8 +284,8 @@ public String getBeaconCronValue(BeaconConfigurationRepository repo)
public IBeaconDataService getBeaconDataService(@Value("${shibui.beacon.productName:ShibUi}") String productName, InfoEndpoint info, @Value("#{environment.TIERVERSION}") String tierVersion,
EntityDescriptorRepository entityDescriptorRepository, MetadataResolverRepository metadataResolverRepository, FilterRepository filterRepository,
GroupsRepository groupsRepository, RoleRepository roleRepository, BeaconConfigurationRepository beaconConfigurationRepository,
UserService userService, HealthEndpoint healthEndpoint) {
BeaconDataServiceImpl result = new BeaconDataServiceImpl(productName, info, tierVersion, entityDescriptorRepository, metadataResolverRepository, filterRepository, groupsRepository, roleRepository, beaconConfigurationRepository, userService, healthEndpoint);
UserService userService, HealthEndpoint healthEndpoint, BeaconEventRepository beaconEventRepository) {
BeaconDataServiceImpl result = new BeaconDataServiceImpl(productName, info, tierVersion, entityDescriptorRepository, metadataResolverRepository, filterRepository, groupsRepository, roleRepository, beaconConfigurationRepository, userService, healthEndpoint, beaconEventRepository);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.controller;

import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEventType;
import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation;
Expand All @@ -11,6 +13,7 @@
import edu.internet2.tier.shibboleth.admin.ui.service.DynamicRegistrationService;
import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService;
import edu.internet2.tier.shibboleth.admin.ui.service.FilterService;
import edu.internet2.tier.shibboleth.admin.ui.service.IBeaconDataService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.tags.Tags;
Expand Down Expand Up @@ -40,6 +43,9 @@ public class ActivateController {

@Autowired
private MetadataResolverService metadataResolverService;

@Autowired
private IBeaconDataService beaconDataService;

@PatchMapping(path = "/DynamicRegistration/{resourceId}/{mode}")
@Transactional
Expand Down Expand Up @@ -69,6 +75,9 @@ public ResponseEntity<?> enableEntityDescriptor(@PathVariable String resourceId,
public ResponseEntity<?> enableFilter(@PathVariable String metadataResolverId, @PathVariable String resourceId, @PathVariable String mode) throws PersistentEntityNotFound, ForbiddenException, ScriptException {
boolean status = "enable".equalsIgnoreCase(mode);
MetadataFilter persistedFilter = filterService.updateFilterEnabledStatus(metadataResolverId, resourceId, status);
if (status) {
beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_FILTER_ENABLED));
}
return ResponseEntity.ok(persistedFilter);
}

Expand All @@ -77,6 +86,9 @@ public ResponseEntity<?> enableFilter(@PathVariable String metadataResolverId, @
public ResponseEntity<?> enableProvider(@PathVariable String resourceId, @PathVariable String mode) throws PersistentEntityNotFound, ForbiddenException, MetadataFileNotFoundException, InitializationException {
boolean status = "enable".equalsIgnoreCase(mode);
MetadataResolver metadataResolver = metadataResolverService.updateMetadataResolverEnabledStatus(resourceId, status);
if (status) {
beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_PROVIDER_ENABLED));
}
return ResponseEntity.ok(metadataResolver);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.controller;

import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEventType;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.ITargetable;
Expand All @@ -9,6 +11,7 @@
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService;
import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService;
import edu.internet2.tier.shibboleth.admin.ui.service.IBeaconDataService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.tags.Tags;
Expand Down Expand Up @@ -50,6 +53,9 @@ public class MetadataFiltersController {
private static final Supplier<HttpClientErrorException> HTTP_400_BAD_REQUEST_EXCEPTION = () -> new HttpClientErrorException(BAD_REQUEST);
private static final Supplier<HttpClientErrorException> HTTP_404_CLIENT_ERROR_EXCEPTION = () -> new HttpClientErrorException(NOT_FOUND);

@Autowired
private IBeaconDataService beaconDataService;

@Autowired
org.opensaml.saml.metadata.resolver.MetadataResolver chainingMetadataResolver;

Expand Down Expand Up @@ -82,6 +88,7 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
reloadFiltersAndHandleScriptException(persistedMr.getResourceId());

MetadataFilter persistedFilter = newlyPersistedFilter(persistedMr.getMetadataFilters().stream(), newFilter.getResourceId());
beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_FILTER_CREATED));
return ResponseEntity.created(getResourceUriFor(persistedMr, newFilter.getResourceId())).body(persistedFilter);
}

Expand Down Expand Up @@ -110,6 +117,7 @@ public ResponseEntity<?> delete(@PathVariable String metadataResolverId, @PathVa
//TODO: do we need to reload filters here?!?
//metadataResolverService.reloadFilters(persistedMr.getName());

beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_FILTER_REMOVED));
return ResponseEntity.noContent().build();
}

Expand Down Expand Up @@ -189,8 +197,7 @@ private void reloadFiltersAndHandleScriptException(String resolverResourceId) {

@PutMapping("/Filters/{resourceId}")
@Transactional
public ResponseEntity<?> update(@PathVariable String metadataResolverId, @PathVariable String resourceId, @RequestBody MetadataFilter updatedFilter)
throws ScriptException {
public ResponseEntity<?> update(@PathVariable String metadataResolverId, @PathVariable String resourceId, @RequestBody MetadataFilter updatedFilter) throws ScriptException {
MetadataResolver metadataResolver = findResolverOrThrowHttp404(metadataResolverId);

//Now we operate directly on the filter attached to MetadataResolver,
Expand Down Expand Up @@ -228,6 +235,7 @@ public ResponseEntity<?> update(@PathVariable String metadataResolverId, @PathVa

// TODO: do we need to reload filters here? We shouldnt throw a script exception here now - we check above...
reloadFiltersAndHandleScriptException(metadataResolver.getResourceId());
beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_FILTER_MODIFIED));
return ResponseEntity.ok().body(persistedFilter);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package edu.internet2.tier.shibboleth.admin.ui.controller;

import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEventType;
import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.MetadataResolverValidationService;
import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.service.IBeaconDataService;
import edu.internet2.tier.shibboleth.admin.ui.service.IndexWriterService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
Expand Down Expand Up @@ -52,27 +55,29 @@
@Slf4j
@Tags(value = {@Tag(name = "metadata resolvers")})
public class MetadataResolversController {
@Autowired
private IBeaconDataService beaconDataService;

@Autowired
MetadataResolverRepository resolverRepository;
org.opensaml.saml.metadata.resolver.MetadataResolver chainingMetadataResolver;

@Autowired
MetadataResolverValidationService metadataResolverValidationService;
IndexWriterService indexWriterService;

@Autowired
MetadataResolverService metadataResolverService;
MetadataResolverConverterService metadataResolverConverterService;

@Autowired
MetadataResolversPositionOrderContainerService positionOrderContainerService;
MetadataResolverService metadataResolverService;

@Autowired
IndexWriterService indexWriterService;
MetadataResolverValidationService metadataResolverValidationService;

@Autowired
org.opensaml.saml.metadata.resolver.MetadataResolver chainingMetadataResolver;
MetadataResolversPositionOrderContainerService positionOrderContainerService;

@Autowired
MetadataResolverConverterService metadataResolverConverterService;
MetadataResolverRepository resolverRepository;

@Autowired
MetadataResolverVersionService versionService;
Expand Down Expand Up @@ -156,7 +161,7 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) throw
MetadataResolver persistedResolver = resolverRepository.save(newResolver);
positionOrderContainerService.appendPositionOrderForNew(persistedResolver);
doResolverInitialization(persistedResolver);

beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_PROVIDER_CREATED));
return ResponseEntity.created(getResourceUriFor(persistedResolver)).body(persistedResolver);
}

Expand All @@ -168,8 +173,7 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me
return ResponseEntity.notFound().build();
}
if (existingResolver.getVersion() != updatedResolver.getVersion()) {
log.info("Metadata Resolver version conflict. Latest resolver in database version: {}. Resolver version sent from UI: {}",
existingResolver.getVersion(), updatedResolver.getVersion());
log.info("Metadata Resolver version conflict. Latest resolver in database version: {}. Resolver version sent from UI: {}", existingResolver.getVersion(), updatedResolver.getVersion());
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}

Expand All @@ -182,6 +186,7 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me
MetadataResolver persistedResolver = resolverRepository.save(updatedResolver);
doResolverInitialization(persistedResolver);

beaconDataService.addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_PROVIDER_MODIFIED));
return ResponseEntity.ok(resolverRepository.findByResourceId(resourceId));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.beacon;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date;

@Entity
@Data
public class BeaconEvent {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;

private Date eventTime;

private String eventName;

public BeaconEvent() {
eventTime = new Date();
}

public BeaconEvent(BeaconEventType eventType) {
eventTime = new Date();
this.eventName = eventType.name();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.beacon;

public enum BeaconEventType {
METADATA_SOURCE_MODIFIED, METADATA_SOURCE_REMOVED, METADATA_SOURCE_ENABLED, METADATA_SOURCE_CREATED,
METADATA_PROVIDER_MODIFIED, METADATA_PROVIDER_REMOVED, METADATA_PROVIDER_ENABLED, METADATA_PROVIDER_CREATED,
METADATA_FILTER_MODIFIED, METADATA_FILTER_REMOVED, METADATA_FILTER_ENABLED, METADATA_FILTER_CREATED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.repository;

import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BeaconEventRepository extends JpaRepository<BeaconEvent, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.internet2.tier.shibboleth.admin.ui.service.beacon.BeaconDetail;
import edu.internet2.tier.shibboleth.admin.ui.service.beacon.ShibuiDetail;
import edu.internet2.tier.shibboleth.admin.ui.domain.BeaconConfiguration;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEventType;
import edu.internet2.tier.shibboleth.admin.ui.repository.BeaconConfigurationRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.BeaconEventRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository;
import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService;
import edu.internet2.tier.shibboleth.admin.ui.service.beacon.BeaconDetail;
import edu.internet2.tier.shibboleth.admin.ui.service.beacon.ShibuiDetail;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class BeaconDataServiceImpl implements IBeaconDataService {
Expand All @@ -35,11 +38,12 @@ public class BeaconDataServiceImpl implements IBeaconDataService {
private RoleRepository roleRepository;
private BeaconConfigurationRepository beaconConfigurationRepository;
private UserService userService;
private BeaconEventRepository beaconEventRepository;

public BeaconDataServiceImpl(String productName, InfoEndpoint info, String tierVersion, EntityDescriptorRepository entityDescriptorRepository,
MetadataResolverRepository metadataResolverRepository, FilterRepository filterRepository, GroupsRepository groupsRepository,
RoleRepository roleRepository, BeaconConfigurationRepository beaconConfigurationRepository, UserService userService,
HealthEndpoint health) {
HealthEndpoint health, BeaconEventRepository beaconEventRepository) {
mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // skip any null values

Expand All @@ -56,16 +60,26 @@ public BeaconDataServiceImpl(String productName, InfoEndpoint info, String tierV
this.roleRepository = roleRepository;
this.beaconConfigurationRepository = beaconConfigurationRepository;
this.userService = userService;
this.beaconEventRepository = beaconEventRepository;
}

@Override
@SneakyThrows
public String getBeaconData() {
BeaconDetail detail = new BeaconDetail().setTbProduct(productName).setTbProductVersion(version).setTbTIERRelease(tierVersion).setShibui(getShibuiDetailData());

return mapper.writeValueAsString(detail);
}

@Override
public void addBeaconEvent(BeaconEvent event) {
beaconEventRepository.save(event);
}

@Override
public void addEntityDescEnabledEvent() {
addBeaconEvent(new BeaconEvent(BeaconEventType.METADATA_SOURCE_ENABLED));
}

private ShibuiDetail getShibuiDetailData() {
BeaconConfiguration configuration = beaconConfigurationRepository.getReferenceById(1);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import edu.internet2.tier.shibboleth.admin.ui.domain.beacon.BeaconEvent;

public interface IBeaconDataService {
String getBeaconData() throws JsonProcessingException;

void addBeaconEvent(BeaconEvent event);

void addEntityDescEnabledEvent();
}
Loading

0 comments on commit 83631bd

Please sign in to comment.